From 7ebe49b76a001b10b007193b1771f33e6cbc4f3f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 16 Oct 2022 12:41:26 +0200 Subject: [PATCH 0001/1480] driver core: allow kobj_to_dev() to take a const pointer If a const * to a kobject is passed to kobj_to_dev(), we want to return back a const * to a device as the driver core shouldn't be modifying a constant structure. But when dealing with container_of() the pointer const attribute is cast away, so we need to manually handle this by determining the type of the pointer passed in to know the type of the pointer to pass out. Luckily _Generic can do this type of magic, and as the kernel now supports C11 it is availble to us to handle this type of build-time type detection. Cc: "Rafael J. Wysocki" Reviewed-by: Sakari Ailus Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221016104126.1259809-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/include/linux/device.h b/include/linux/device.h index 424b55df02727..023ea50b19162 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -680,11 +680,27 @@ struct device_link { bool supplier_preactivated; /* Owned by consumer probe. */ }; -static inline struct device *kobj_to_dev(struct kobject *kobj) +static inline struct device *__kobj_to_dev(struct kobject *kobj) { return container_of(kobj, struct device, kobj); } +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) +{ + return container_of(kobj, const struct device, kobj); +} + +/* + * container_of() will happily take a const * and spit back a non-const * as it + * is just doing pointer math. But we want to be a bit more careful in the + * driver code, so manually force any const * of a kobject to also be a const * + * to a device. + */ +#define kobj_to_dev(kobj) \ + _Generic((kobj), \ + const struct kobject *: __kobj_to_dev_const, \ + struct kobject *: __kobj_to_dev)(kobj) + /** * device_iommu_mapped - Returns true when the device DMA is translated * by an IOMMU -- GitLab From 593efa4091f5f05c224f8b7fd204d18dbff97e31 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 16 Oct 2022 12:41:55 +0200 Subject: [PATCH 0002/1480] USB: allow some usb functions to take a const pointer. The functions to_usb_interface(), to_usb_device, and interface_to_usbdev() sometimes would like to take a const * and return a const * back. As we are doing pointer math, a call to container_of() loses the const-ness of a pointer, so use a _Generic() macro to pick the proper inline function to call instead. Link: https://lore.kernel.org/r/20221016104155.1260201-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 55 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 9ff1ad4dfad12..3a55131e0ad4a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -258,7 +258,27 @@ struct usb_interface { struct device *usb_dev; struct work_struct reset_ws; /* for resets in atomic context */ }; -#define to_usb_interface(d) container_of(d, struct usb_interface, dev) + +static inline struct usb_interface *__to_usb_interface(struct device *d) +{ + return container_of(d, struct usb_interface, dev); +} + +static inline const struct usb_interface *__to_usb_interface_const(const struct device *d) +{ + return container_of(d, struct usb_interface, dev); +} + +/* + * container_of() will happily take a const * and spit back a non-const * as it + * is just doing pointer math. But we want to be a bit more careful in the USB + * driver code, so manually force any const * of a device to also be a const * + * to a usb_device. + */ +#define to_usb_interface(dev) \ + _Generic((dev), \ + const struct device *: __to_usb_interface_const, \ + struct device *: __to_usb_interface)(dev) static inline void *usb_get_intfdata(struct usb_interface *intf) { @@ -709,12 +729,41 @@ struct usb_device { u16 hub_delay; unsigned use_generic_driver:1; }; -#define to_usb_device(d) container_of(d, struct usb_device, dev) -static inline struct usb_device *interface_to_usbdev(struct usb_interface *intf) +static inline struct usb_device *__to_usb_device(struct device *d) +{ + return container_of(d, struct usb_device, dev); +} + +static inline const struct usb_device *__to_usb_device_const(const struct device *d) +{ + return container_of(d, struct usb_device, dev); +} + +/* + * container_of() will happily take a const * and spit back a non-const * as it + * is just doing pointer math. But we want to be a bit more careful in the USB + * driver code, so manually force any const * of a device to also be a const * + * to a usb_device. + */ +#define to_usb_device(dev) \ + _Generic((dev), \ + const struct device *: __to_usb_device_const, \ + struct device *: __to_usb_device)(dev) + +static inline struct usb_device *__intf_to_usbdev(struct usb_interface *intf) { return to_usb_device(intf->dev.parent); } +static inline const struct usb_device *__intf_to_usbdev_const(const struct usb_interface *intf) +{ + return to_usb_device((const struct device *)intf->dev.parent); +} + +#define interface_to_usbdev(intf) \ + _Generic((intf), \ + const struct usb_interface *: __intf_to_usbdev_const, \ + struct usb_interface *: __intf_to_usbdev)(intf) extern struct usb_device *usb_get_dev(struct usb_device *dev); extern void usb_put_dev(struct usb_device *dev); -- GitLab From 5033ac5c580cb22245a0c2b9e53d508e8fdd50d8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 Oct 2022 18:51:28 +0200 Subject: [PATCH 0003/1480] USB: make devnode() callback in usb_class_driver take a const * With the changes to the driver core to make more pointers const, the USB subsystem also needs to be modified to take a const * for the devnode callback so that the driver core's constant pointer will also be properly propagated. Cc: Benjamin Tissoires Cc: Juergen Stuber Reviewed-by: Johan Hovold Acked-by: Pete Zaitcev Reviewed-by: Jiri Kosina Link: https://lore.kernel.org/r/20221001165128.2688526-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/hid/usbhid/hiddev.c | 2 +- drivers/usb/class/usblp.c | 2 +- drivers/usb/misc/iowarrior.c | 2 +- drivers/usb/misc/legousbtower.c | 2 +- include/linux/usb.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 2fb2991dbe4c3..59cf3ddfdf78c 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -857,7 +857,7 @@ static const struct file_operations hiddev_fops = { .llseek = noop_llseek, }; -static char *hiddev_devnode(struct device *dev, umode_t *mode) +static char *hiddev_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); } diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index f27b4aecff3d4..5a2e43331064e 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1090,7 +1090,7 @@ static const struct file_operations usblp_fops = { .llseek = noop_llseek, }; -static char *usblp_devnode(struct device *dev, umode_t *mode) +static char *usblp_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); } diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 988a8c02e7e24..f9427a67789cf 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -717,7 +717,7 @@ static const struct file_operations iowarrior_fops = { .llseek = noop_llseek, }; -static char *iowarrior_devnode(struct device *dev, umode_t *mode) +static char *iowarrior_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); } diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 1c9e09138c109..379cf01a6e96e 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -245,7 +245,7 @@ static const struct file_operations tower_fops = { .llseek = tower_llseek, }; -static char *legousbtower_devnode(struct device *dev, umode_t *mode) +static char *legousbtower_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); } diff --git a/include/linux/usb.h b/include/linux/usb.h index 3a55131e0ad4a..4b463a5e4ba22 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1321,7 +1321,7 @@ struct usb_device_driver { */ struct usb_class_driver { char *name; - char *(*devnode)(struct device *dev, umode_t *mode); + char *(*devnode)(const struct device *dev, umode_t *mode); const struct file_operations *fops; int minor_base; }; -- GitLab From aa1d058d48f292aa138e33ad12b7b4d18b5407cd Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 18 Oct 2022 10:32:42 +0800 Subject: [PATCH 0004/1480] kernfs: dont take i_lock on inode attr read The kernfs write lock is held when the kernfs node inode attributes are updated. Therefore, when either kernfs_iop_getattr() or kernfs_iop_permission() are called the kernfs node inode attributes won't change. Consequently concurrent kernfs_refresh_inode() calls always copy the same values from the kernfs node. So there's no need to take the inode i_lock to get consistent values for generic_fillattr() and generic_permission(), the kernfs read lock is sufficient. Cc: Tejun Heo Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/166606036215.13363.1288735296954908554.stgit@donald.themaw.net Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/inode.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 3d783d80f5daa..74f3453f4639f 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -190,10 +190,8 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns, struct kernfs_root *root = kernfs_root(kn); down_read(&root->kernfs_rwsem); - spin_lock(&inode->i_lock); kernfs_refresh_inode(kn, inode); generic_fillattr(&init_user_ns, inode, stat); - spin_unlock(&inode->i_lock); up_read(&root->kernfs_rwsem); return 0; @@ -288,10 +286,8 @@ int kernfs_iop_permission(struct user_namespace *mnt_userns, root = kernfs_root(kn); down_read(&root->kernfs_rwsem); - spin_lock(&inode->i_lock); kernfs_refresh_inode(kn, inode); ret = generic_permission(&init_user_ns, inode, mask); - spin_unlock(&inode->i_lock); up_read(&root->kernfs_rwsem); return ret; -- GitLab From 92b57842f43014e6ca81ddf6d5d59e9ddf762e12 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 18 Oct 2022 10:32:49 +0800 Subject: [PATCH 0005/1480] kernfs: dont take i_lock on revalidate In kernfs_dop_revalidate() when the passed in dentry is negative the dentry directory is checked to see if it has changed and if so the negative dentry is discarded so it can refreshed. During this check the dentry inode i_lock is taken to mitigate against a possible concurrent rename. But if it's racing with a rename, becuase the dentry is negative, it can't be the source it must be the target and it must be going to do a d_move() otherwise the rename will return an error. In this case the parent dentry of the target will not change, it will be the same over the d_move(), only the source dentry parent may change so the inode i_lock isn't needed. Cc: Tejun Heo Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/166606036967.13363.9336408133975631967.stgit@donald.themaw.net Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 3990f3e270cb6..6acd9c3d4cff1 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1073,20 +1073,30 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) /* If the kernfs parent node has changed discard and * proceed to ->lookup. + * + * There's nothing special needed here when getting the + * dentry parent, even if a concurrent rename is in + * progress. That's because the dentry is negative so + * it can only be the target of the rename and it will + * be doing a d_move() not a replace. Consequently the + * dentry d_parent won't change over the d_move(). + * + * Also kernfs negative dentries transitioning from + * negative to positive during revalidate won't happen + * because they are invalidated on containing directory + * changes and the lookup re-done so that a new positive + * dentry can be properly created. */ - spin_lock(&dentry->d_lock); + root = kernfs_root_from_sb(dentry->d_sb); + down_read(&root->kernfs_rwsem); parent = kernfs_dentry_node(dentry->d_parent); if (parent) { - spin_unlock(&dentry->d_lock); - root = kernfs_root(parent); - down_read(&root->kernfs_rwsem); if (kernfs_dir_changed(parent, dentry)) { up_read(&root->kernfs_rwsem); return 0; } - up_read(&root->kernfs_rwsem); - } else - spin_unlock(&dentry->d_lock); + } + up_read(&root->kernfs_rwsem); /* The kernfs parent node hasn't changed, leave the * dentry negative and return success. -- GitLab From 0c04b83d95e02c9def6e2db49fc2cab618faf949 Mon Sep 17 00:00:00 2001 From: Tanjuate Brunostar Date: Tue, 18 Oct 2022 12:01:54 +0000 Subject: [PATCH 0006/1480] staging: rts5208: split long line of code Fix checkpatch warning by splitting up a long line of code, improving code readability Signed-off-by: Tanjuate Brunostar Acked-by: Julia Lawall Link: https://lore.kernel.org/r/Y06Vsr7JVvpPem5T@elroy-temp-vm.gaiao0uenmiufjlowqgp5yxwdh.gvxx.internal.cloudapp.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index d1fafd530c80e..4b7122add51aa 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -4506,7 +4506,8 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (CHK_SD(sd_card)) { retval = reset_sd(chip); if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + sd_card->sd_lock_status &= + ~(SD_UNLOCK_POW_ON | SD_SDR_RST); goto sd_execute_write_cmd_failed; } } -- GitLab From fd22186003a98daaab1ea08aaa177c041fdaa649 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Mon, 17 Oct 2022 12:02:30 +0530 Subject: [PATCH 0007/1480] staging: iio: frequency: ad9834: merge unnecessary split lines Improve code readability by merging unnecessary split lines that are well within the code-style guidelines post merge. Signed-off-by: Deepak R Varma Acked-by: Julia Lawall Link: https://lore.kernel.org/r/Y0z2/qFe3kW96MTs@debian-BULLSEYE-live-builder-AMD64 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/frequency/ad9834.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 2b4267a87e65e..285df0e489a62 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -331,11 +331,9 @@ static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9834_write, AD9834_REG_PHASE1); static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, ad9834_write, AD9834_PSEL); static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ -static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, - ad9834_write, AD9834_PIN_SW); +static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, ad9834_write, AD9834_PIN_SW); static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, ad9834_write, AD9834_RESET); -static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL, - ad9834_write, AD9834_OPBITEN); +static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL, ad9834_write, AD9834_OPBITEN); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); -- GitLab From febdb8eea98b1c506cf8624531a334e507c4a771 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 1 Oct 2022 19:06:18 +0200 Subject: [PATCH 0008/1480] staging: r8188eu: remove bLedLinkBlinkInProgress Remove the bLedLinkBlinkInProgress component from struct led_priv. Its only use is to block requests for "link blinking" when this blinking pattern is already active. The "link blinking" pattern is a continuous blinking pattern (as opposed to other patterns where we blink N times), it's no problem to restart this pattern when it's already running. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221001170618.444444-1-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 14 -------------- drivers/staging/r8188eu/include/rtw_led.h | 1 - 2 files changed, 15 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 1e316e6358ea2..2527c252c3e95 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -26,7 +26,6 @@ static void ResetLedStatus(struct led_priv *pLed) pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */ - pLed->bLedLinkBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; } @@ -99,7 +98,6 @@ static void blink_work(struct work_struct *work) pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); } else { @@ -115,7 +113,6 @@ static void blink_work(struct work_struct *work) pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); } else { @@ -132,7 +129,6 @@ static void blink_work(struct work_struct *work) break; case LED_BLINK_WPS_STOP: /* WPS success */ if (!pLed->bLedOn) { - pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); @@ -189,23 +185,18 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) cancel_delayed_work(&pLed->blink_work); - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = false; pLed->CurrLedState = LED_BLINK_SLOWLY; schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); break; case LED_CTL_LINK: - if (!pLed->bLedLinkBlinkInProgress) - return; - if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; cancel_delayed_work(&pLed->blink_work); pLed->bLedBlinkInProgress = false; - pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); @@ -222,7 +213,6 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) cancel_delayed_work(&pLed->blink_work); - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = false; pLed->bLedScanBlinkInProgress = true; @@ -240,7 +230,6 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) cancel_delayed_work(&pLed->blink_work); - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_TXRX; @@ -253,7 +242,6 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) cancel_delayed_work(&pLed->blink_work); - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; pLed->bLedWPSBlinkInProgress = true; @@ -263,7 +251,6 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) case LED_CTL_STOP_WPS: cancel_delayed_work(&pLed->blink_work); - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; pLed->bLedWPSBlinkInProgress = true; @@ -283,7 +270,6 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) break; case LED_CTL_POWER_OFF: pLed->CurrLedState = RTW_LED_OFF; - pLed->bLedLinkBlinkInProgress = false; pLed->bLedBlinkInProgress = false; pLed->bLedWPSBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h index 8520f022a67f2..f57dcf6c8b24e 100644 --- a/drivers/staging/r8188eu/include/rtw_led.h +++ b/drivers/staging/r8188eu/include/rtw_led.h @@ -47,7 +47,6 @@ struct led_priv { u32 BlinkTimes; /* Number of times to toggle led state for blinking. */ - bool bLedLinkBlinkInProgress; bool bLedScanBlinkInProgress; struct delayed_work blink_work; }; -- GitLab From 85eba7ac39f7e86a2b473aae9d664f9ef47cad2c Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:40:29 +0200 Subject: [PATCH 0009/1480] staging: rtl8192e: Remove unchanged variable bFwCtrlLPS bFwCtrlLPS is just once initialized and never changed. The evaluation will always have the same result. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/d5b5cfd26648180d082f38085a807c932e87703c.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 15 ++++----------- drivers/staging/rtl8192e/rtllib.h | 3 --- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 89bc989cffbae..10b79003c6339 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -889,7 +889,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rtllib->PowerSaveControl.bInactivePs = true; priv->rtllib->PowerSaveControl.bIPSModeBackup = false; priv->rtllib->PowerSaveControl.bLeisurePs = true; - priv->rtllib->PowerSaveControl.bFwCtrlLPS = false; priv->rtllib->LPSDelayCnt = 0; priv->rtllib->sta_sleep = LPS_IS_WAKE; priv->rtllib->rf_power_state = rf_on; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 8c00b111ddb2b..49c50ec21d04f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -229,11 +229,8 @@ void rtl92e_leisure_ps_enter(struct net_device *dev) if (pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) { if (priv->rtllib->ps == RTLLIB_PS_DISABLED) { - if (!pPSC->bFwCtrlLPS) { - if (priv->rtllib->SetFwCmdHandler) - priv->rtllib->SetFwCmdHandler( - dev, FW_CMD_LPS_ENTER); - } + if (priv->rtllib->SetFwCmdHandler) + priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_ENTER); _rtl92e_ps_set_mode(dev, RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST); } @@ -251,12 +248,8 @@ void rtl92e_leisure_ps_leave(struct net_device *dev) if (pPSC->bLeisurePs) { if (priv->rtllib->ps != RTLLIB_PS_DISABLED) { _rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED); - - if (!pPSC->bFwCtrlLPS) { - if (priv->rtllib->SetFwCmdHandler) - priv->rtllib->SetFwCmdHandler(dev, - FW_CMD_LPS_LEAVE); - } + if (priv->rtllib->SetFwCmdHandler) + priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_LEAVE); } } } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 3c72ed2a30a41..40bea71bcb22c 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1264,9 +1264,6 @@ struct rt_pwr_save_ctrl { u32 CurPsLevel; u32 RegRfPsLevel; - - bool bFwCtrlLPS; - }; #define RT_RF_CHANGE_SOURCE u32 -- GitLab From e77996261369bb5b202d3739270fcc5bc50c5c91 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:40:36 +0200 Subject: [PATCH 0010/1480] staging: rtl8192e: Remove unchanged variable bInactivePs bInactivePs is just once initialized and never changed. The evaluation will always have the same result. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/9f46eebf8220a06a1889eaf2d6bac74dd08cfd1f.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_cam.c | 18 ++++--- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 49 +++++++++----------- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 48 +++++++++---------- drivers/staging/rtl8192e/rtllib.h | 2 - 5 files changed, 51 insertions(+), 67 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index 41faeb4b9b9b4..8c3ce6cc2541a 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -81,17 +81,15 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; - if (priv->rtllib->PowerSaveControl.bInactivePs) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - return; - } - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); + if (rt_state == rf_off) { + if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); + return; } + mutex_lock(&priv->rtllib->ips_mutex); + rtl92e_ips_leave(dev); + mutex_unlock(&priv->rtllib->ips_mutex); } priv->rtllib->is_set_key = true; if (EntryNo >= TOTAL_CAM_ENTRY) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 10b79003c6339..7c0fd2bce923a 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -886,7 +886,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; priv->SetRFPowerStateInProgress = false; - priv->rtllib->PowerSaveControl.bInactivePs = true; priv->rtllib->PowerSaveControl.bIPSModeBackup = false; priv->rtllib->PowerSaveControl.bLeisurePs = true; priv->rtllib->LPSDelayCnt = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 49c50ec21d04f..fba86ef730b53 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -116,16 +116,14 @@ void rtl92e_ips_enter(struct net_device *dev) &(priv->rtllib->PowerSaveControl); enum rt_rf_power_state rt_state; - if (pPSC->bInactivePs) { - rt_state = priv->rtllib->rf_power_state; - if (rt_state == rf_on && !pPSC->bSwRfProcessing && - (priv->rtllib->state != RTLLIB_LINKED) && - (priv->rtllib->iw_mode != IW_MODE_MASTER)) { - pPSC->eInactivePowerState = rf_off; - priv->isRFOff = true; - priv->bInPowerSaveMode = true; - _rtl92e_ps_update_rf_state(dev); - } + rt_state = priv->rtllib->rf_power_state; + if (rt_state == rf_on && !pPSC->bSwRfProcessing && + (priv->rtllib->state != RTLLIB_LINKED) && + (priv->rtllib->iw_mode != IW_MODE_MASTER)) { + pPSC->eInactivePowerState = rf_off; + priv->isRFOff = true; + priv->bInPowerSaveMode = true; + _rtl92e_ps_update_rf_state(dev); } } @@ -136,14 +134,12 @@ void rtl92e_ips_leave(struct net_device *dev) &(priv->rtllib->PowerSaveControl); enum rt_rf_power_state rt_state; - if (pPSC->bInactivePs) { - rt_state = priv->rtllib->rf_power_state; - if (rt_state != rf_on && !pPSC->bSwRfProcessing && - priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { - pPSC->eInactivePowerState = rf_on; - priv->bInPowerSaveMode = false; - _rtl92e_ps_update_rf_state(dev); - } + rt_state = priv->rtllib->rf_power_state; + if (rt_state != rf_on && !pPSC->bSwRfProcessing && + priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { + pPSC->eInactivePowerState = rf_on; + priv->bInPowerSaveMode = false; + _rtl92e_ps_update_rf_state(dev); } } @@ -165,18 +161,15 @@ void rtl92e_rtllib_ips_leave_wq(struct net_device *dev) enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; - - if (priv->rtllib->PowerSaveControl.bInactivePs) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - return; - } - netdev_info(dev, "=========>%s(): rtl92e_ips_leave\n", + if (rt_state == rf_off) { + if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { + netdev_warn(dev, "%s(): RF is OFF.\n", __func__); - schedule_work(&priv->rtllib->ips_leave_wq); + return; } + netdev_info(dev, "=========>%s(): rtl92e_ips_leave\n", + __func__); + schedule_work(&priv->rtllib->ips_leave_wq); } } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 4920cb49e3811..12eea4fcb9dde 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -252,22 +252,20 @@ static int _rtl92e_wx_set_mode(struct net_device *dev, mutex_lock(&priv->wx_mutex); if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR || ieee->bNetPromiscuousMode) { - if (priv->rtllib->PowerSaveControl.bInactivePs) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > - RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return -1; - } - netdev_info(dev, - "=========>%s(): rtl92e_ips_leave\n", + if (rt_state == rf_off) { + if (priv->rtllib->rf_off_reason > + RF_CHANGE_BY_IPS) { + netdev_warn(dev, "%s(): RF is OFF.\n", __func__); - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); + mutex_unlock(&priv->wx_mutex); + return -1; } + netdev_info(dev, + "=========>%s(): rtl92e_ips_leave\n", + __func__); + mutex_lock(&priv->rtllib->ips_mutex); + rtl92e_ips_leave(dev); + mutex_unlock(&priv->rtllib->ips_mutex); } } ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b); @@ -414,19 +412,17 @@ static int _rtl92e_wx_set_scan(struct net_device *dev, priv->rtllib->FirstIe_InScan = true; if (priv->rtllib->state != RTLLIB_LINKED) { - if (priv->rtllib->PowerSaveControl.bInactivePs) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > - RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return -1; - } - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); + if (rt_state == rf_off) { + if (priv->rtllib->rf_off_reason > + RF_CHANGE_BY_IPS) { + netdev_warn(dev, "%s(): RF is OFF.\n", + __func__); + mutex_unlock(&priv->wx_mutex); + return -1; } + mutex_lock(&priv->rtllib->ips_mutex); + rtl92e_ips_leave(dev); + mutex_unlock(&priv->rtllib->ips_mutex); } rtllib_stop_scan(priv->rtllib); if (priv->rtllib->LedControlHandler) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 40bea71bcb22c..d23d1c3ce39b8 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1250,8 +1250,6 @@ enum rt_rf_power_state { }; struct rt_pwr_save_ctrl { - - bool bInactivePs; bool bIPSModeBackup; bool bSwRfProcessing; enum rt_rf_power_state eInactivePowerState; -- GitLab From 3700c365b6b204eb6d76dac7312fc3bb21faa350 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:40:49 +0200 Subject: [PATCH 0011/1480] staging: rtl8192e: Remove unused variable bIPSModeBackup bIPSModeBackup is just once initialized and never used. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/657035f84d266fd5c6f96e9b530a96c2ab4ff900.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtllib.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 7c0fd2bce923a..cbb65cfea83ac 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -886,7 +886,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; priv->SetRFPowerStateInProgress = false; - priv->rtllib->PowerSaveControl.bIPSModeBackup = false; priv->rtllib->PowerSaveControl.bLeisurePs = true; priv->rtllib->LPSDelayCnt = 0; priv->rtllib->sta_sleep = LPS_IS_WAKE; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index d23d1c3ce39b8..e0fa87b12cebb 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1250,7 +1250,6 @@ enum rt_rf_power_state { }; struct rt_pwr_save_ctrl { - bool bIPSModeBackup; bool bSwRfProcessing; enum rt_rf_power_state eInactivePowerState; enum ips_callback_function ReturnPoint; -- GitLab From 697541a0e53d16a12b00ffa4c9d204b275e68053 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:40:56 +0200 Subject: [PATCH 0012/1480] staging: rtl8192e: Remove unused variable bInPowerSaveMode bInPowerSaveMode is just once initialized and changed but never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/be3ebecd88b85ba1d87b9b3fbe02f2e78e6a669e.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 2 -- 3 files changed, 4 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index cbb65cfea83ac..db55b9b65192c 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -881,7 +881,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->hw_radio_off = false; priv->RegRfOff = false; priv->isRFOff = false; - priv->bInPowerSaveMode = false; priv->rtllib->rf_off_reason = 0; priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 7021f9c435d96..28733dc2038b1 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -475,7 +475,6 @@ struct r8192_priv { bool RegRfOff; bool isRFOff; - bool bInPowerSaveMode; u8 bHwRfOffAction; bool rf_change_in_progress; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index fba86ef730b53..1ced5bcebdabb 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -122,7 +122,6 @@ void rtl92e_ips_enter(struct net_device *dev) (priv->rtllib->iw_mode != IW_MODE_MASTER)) { pPSC->eInactivePowerState = rf_off; priv->isRFOff = true; - priv->bInPowerSaveMode = true; _rtl92e_ps_update_rf_state(dev); } } @@ -138,7 +137,6 @@ void rtl92e_ips_leave(struct net_device *dev) if (rt_state != rf_on && !pPSC->bSwRfProcessing && priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { pPSC->eInactivePowerState = rf_on; - priv->bInPowerSaveMode = false; _rtl92e_ps_update_rf_state(dev); } } -- GitLab From 11dc999d77e4c76deb353d9923e783cdc16c3a7d Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:04 +0200 Subject: [PATCH 0013/1480] staging: rtl8192e: Remove unused variable isRFOff isRFOff is just once initialized and changed but never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/53242638126775f6698fdcfc49ac552a4e08578b.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index db55b9b65192c..3cddc9a86f28f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -880,7 +880,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rtllib->wx_set_enc = 0; priv->hw_radio_off = false; priv->RegRfOff = false; - priv->isRFOff = false; priv->rtllib->rf_off_reason = 0; priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 28733dc2038b1..23dccd6079ea5 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -474,7 +474,6 @@ struct r8192_priv { u16 ChannelPlan; bool RegRfOff; - bool isRFOff; u8 bHwRfOffAction; bool rf_change_in_progress; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 1ced5bcebdabb..1501f7be8eee9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -121,7 +121,6 @@ void rtl92e_ips_enter(struct net_device *dev) (priv->rtllib->state != RTLLIB_LINKED) && (priv->rtllib->iw_mode != IW_MODE_MASTER)) { pPSC->eInactivePowerState = rf_off; - priv->isRFOff = true; _rtl92e_ps_update_rf_state(dev); } } -- GitLab From 20401e6c6a59f56d9235756168f620e7bffbae26 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:10 +0200 Subject: [PATCH 0014/1480] staging: rtl8192e: Remove unchanged variable RegRfOff RegRfOff is just once initialized with false and then set to false again. All evaluations will result in false. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/fa306d364b43fee7b81f5289309e93bb6fccdba5.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 7 +------ drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 -- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 18e4e5d84878a..f2cbec6eb08f2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -624,9 +624,6 @@ start: } priv->pFirmware->status = FW_STATUS_0_INIT; - if (priv->RegRfOff) - priv->rtllib->rf_power_state = rf_off; - ulRegRead = rtl92e_readl(dev, CPU_GEN); if (priv->pFirmware->status == FW_STATUS_0_INIT) ulRegRead |= CPU_GEN_SYSTEM_RESET; @@ -756,9 +753,7 @@ start: rtl92e_writeb(dev, 0x87, 0x0); - if (priv->RegRfOff) { - rtl92e_set_rf_state(dev, rf_off, RF_CHANGE_BY_SW); - } else if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_PS) { + if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_PS) { rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason); } else if (priv->rtllib->rf_off_reason >= RF_CHANGE_BY_IPS) { rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason); diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 1b592258e6406..a44dffa76a39e 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -1325,7 +1325,6 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, do { InitilizeCount--; - priv->RegRfOff = false; rtstatus = rtl92e_enable_nic(dev); } while (!rtstatus && (InitilizeCount > 0)); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 3cddc9a86f28f..e77a73df9bc57 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -879,7 +879,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->RxCounter = 0; priv->rtllib->wx_set_enc = 0; priv->hw_radio_off = false; - priv->RegRfOff = false; priv->rtllib->rf_off_reason = 0; priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 23dccd6079ea5..7d716fa129953 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -472,8 +472,6 @@ struct r8192_priv { u16 RegChannelPlan; u16 ChannelPlan; - - bool RegRfOff; u8 bHwRfOffAction; bool rf_change_in_progress; -- GitLab From ec437736505f4ba1152730d8c0ec3d0167bb358b Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:18 +0200 Subject: [PATCH 0015/1480] staging: rtl8192e: Remove unchanged variable bDisableNormalResetCheck bDisableNormalResetCheck is just once initialized with false. All evaluations will result in !false. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/026313f17cf708bf8fa0661f83b2c2b515e55b12.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 6 ++---- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index e77a73df9bc57..9dcae5d71fb99 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -871,7 +871,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->ScanDelay = 50; priv->ResetProgress = RESET_TYPE_NORESET; priv->bForcedSilentReset = false; - priv->bDisableNormalResetCheck = false; priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); @@ -1403,13 +1402,12 @@ static void _rtl92e_watchdog_wq_cb(void *data) } spin_unlock_irqrestore(&priv->tx_lock, flags); - if (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) { + if (ResetType == RESET_TYPE_NORMAL) { priv->ResetProgress = RESET_TYPE_NORMAL; return; } - if (((priv->force_reset) || (!priv->bDisableNormalResetCheck && - ResetType == RESET_TYPE_SILENT))) + if ((priv->force_reset || ResetType == RESET_TYPE_SILENT)) _rtl92e_if_silent_reset(dev); priv->force_reset = false; priv->bForcedSilentReset = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 7d716fa129953..8a24037a93ec6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -541,7 +541,6 @@ struct r8192_priv { enum reset_type ResetProgress; bool bForcedSilentReset; - bool bDisableNormalResetCheck; u16 TxCounter; u16 RxCounter; bool bResetInProgress; -- GitLab From eda244c081e60a576eecaf635205c4fa5dc9032f Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:24 +0200 Subject: [PATCH 0016/1480] staging: rtl8192e: Remove unused variable bForcedSilentReset bForcedSilentReset is never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/10504e628eae110d73cd43050e7cc5801ce7f17b.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 4 ---- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - 2 files changed, 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 9dcae5d71fb99..ae0fcbbee2bb5 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -870,7 +870,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->CckPwEnl = 6; priv->ScanDelay = 50; priv->ResetProgress = RESET_TYPE_NORESET; - priv->bForcedSilentReset = false; priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); @@ -1240,8 +1239,6 @@ RESET_START: END: priv->ResetProgress = RESET_TYPE_NORESET; priv->reset_count++; - - priv->bForcedSilentReset = false; priv->bResetInProgress = false; rtl92e_writeb(dev, UFWP, 1); @@ -1410,7 +1407,6 @@ static void _rtl92e_watchdog_wq_cb(void *data) if ((priv->force_reset || ResetType == RESET_TYPE_SILENT)) _rtl92e_if_silent_reset(dev); priv->force_reset = false; - priv->bForcedSilentReset = false; priv->bResetInProgress = false; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 8a24037a93ec6..763ed761bb38d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -540,7 +540,6 @@ struct r8192_priv { u32 reset_count; enum reset_type ResetProgress; - bool bForcedSilentReset; u16 TxCounter; u16 RxCounter; bool bResetInProgress; -- GitLab From 93057f8354462708e9721ad6ff6a2294a5ae8a98 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:31 +0200 Subject: [PATCH 0017/1480] staging: rtl8192e: Remove unused variable ScanDelay ScanDelay is never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/13d0b993d077490c65768f2b11a631a447f8e86f.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 -- 3 files changed, 4 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index f2cbec6eb08f2..c3dcaa27fd2ea 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -503,7 +503,6 @@ static void _rtl92e_read_eeprom_info(struct net_device *dev) priv->ChannelPlan = 0x0; break; case EEPROM_CID_Nettronix: - priv->ScanDelay = 100; priv->CustomerID = RT_CID_Nettronix; break; case EEPROM_CID_Pronet: diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index ae0fcbbee2bb5..f07f0fc690a37 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -868,7 +868,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rfa_txpowertrackingindex = 0; priv->rfc_txpowertrackingindex = 0; priv->CckPwEnl = 6; - priv->ScanDelay = 50; priv->ResetProgress = RESET_TYPE_NORESET; priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 763ed761bb38d..c536131ecd5d4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -410,8 +410,6 @@ struct r8192_priv { short chan; short sens; short max_sens; - - u8 ScanDelay; bool ps_force; u32 irq_mask[2]; -- GitLab From 753def95543cf1a01f5487c0ae8cce3ee5180d77 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sat, 1 Oct 2022 11:41:38 +0200 Subject: [PATCH 0018/1480] staging: rtl8192e: Remove unused variable bDriverIsGoingToUnload bDriverIsGoingToUnload is never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/48a84cbe359f159cc9c296b261256a405ee3884e.1664616227.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 3 --- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index f07f0fc690a37..213aac943ef76 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -686,7 +686,6 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) (&priv->rtllib->PowerSaveControl); bool init_status; - priv->bDriverIsGoingToUnload = false; priv->bdisable_nic = false; priv->up = 1; @@ -735,7 +734,6 @@ static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) if (priv->rtllib->state == RTLLIB_LINKED) rtl92e_leisure_ps_leave(dev); - priv->bDriverIsGoingToUnload = true; priv->up = 0; priv->rtllib->ieee_up = 0; priv->bfirst_after_down = true; @@ -838,7 +836,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->polling_timer_on = 0; priv->up_first_time = 1; priv->blinked_ingpio = false; - priv->bDriverIsGoingToUnload = false; priv->being_init_adapter = false; priv->initialized_at_probe = false; priv->bdisable_nic = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index c536131ecd5d4..1ae3c77e2fefc 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -311,7 +311,6 @@ struct r8192_priv { bool bfirst_after_down; bool initialized_at_probe; bool being_init_adapter; - bool bDriverIsGoingToUnload; int irq; short irq_enabled; -- GitLab From 11247c998b00298e9b621f3121380494146c40ff Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 09:48:23 +0200 Subject: [PATCH 0019/1480] staging: r8188eu: merge odm_types.h into other headers The macros SET_TX_DESC_ANTSEL_{A,B,C}_88E are used in odm_RTL8188E.c. Move them from odm_types.h to odm_RTL8188E.h. ODM_CE is used in places where also ODM_ITRF_USB is used in the code. Move the ODM_CE define to the header that defines ODM_ITRF_USB. While at it remove an extra space between '#' and 'define ODM_ITRF_USB'. The haeder odm_types.h is now empty and we can remove it. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002074827.8566-2-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/odm.h | 3 ++- drivers/staging/r8188eu/include/odm_RTL8188E.h | 7 +++++++ drivers/staging/r8188eu/include/odm_types.h | 16 ---------------- drivers/staging/r8188eu/include/rtl8188e_hal.h | 1 - 4 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 drivers/staging/r8188eu/include/odm_types.h diff --git a/drivers/staging/r8188eu/include/odm.h b/drivers/staging/r8188eu/include/odm.h index f131e17167bfb..89b01dd614ba9 100644 --- a/drivers/staging/r8188eu/include/odm.h +++ b/drivers/staging/r8188eu/include/odm.h @@ -119,7 +119,8 @@ enum odm_ability_def { ODM_BB_PWR_TRA = BIT(8), }; -# define ODM_ITRF_USB 0x2 +#define ODM_ITRF_USB 0x2 +#define ODM_CE 0x04 /* ODM_CMNINFO_WM_MODE */ enum odm_wireless_mode { diff --git a/drivers/staging/r8188eu/include/odm_RTL8188E.h b/drivers/staging/r8188eu/include/odm_RTL8188E.h index 3c6471f1a893f..4f16af2485913 100644 --- a/drivers/staging/r8188eu/include/odm_RTL8188E.h +++ b/drivers/staging/r8188eu/include/odm_RTL8188E.h @@ -11,6 +11,13 @@ #define MAIN_ANT_CGCS_RX 0 #define AUX_ANT_CGCS_RX 1 +#define SET_TX_DESC_ANTSEL_A_88E(__ptxdesc, __value) \ + le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(24)) +#define SET_TX_DESC_ANTSEL_B_88E(__ptxdesc, __value) \ + le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(25)) +#define SET_TX_DESC_ANTSEL_C_88E(__ptxdesc, __value) \ + le32p_replace_bits((__le32 *)(__ptxdesc + 28), __value, BIT(29)) + void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *pDM_Odm); void ODM_AntennaDiversity_88E(struct odm_dm_struct *pDM_Odm); diff --git a/drivers/staging/r8188eu/include/odm_types.h b/drivers/staging/r8188eu/include/odm_types.h deleted file mode 100644 index 76302df4b330b..0000000000000 --- a/drivers/staging/r8188eu/include/odm_types.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#ifndef __ODM_TYPES_H__ -#define __ODM_TYPES_H__ - -#define ODM_CE 0x04 /* BIT(2) */ - -#define SET_TX_DESC_ANTSEL_A_88E(__ptxdesc, __value) \ - le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(24)) -#define SET_TX_DESC_ANTSEL_B_88E(__ptxdesc, __value) \ - le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(25)) -#define SET_TX_DESC_ANTSEL_C_88E(__ptxdesc, __value) \ - le32p_replace_bits((__le32 *)(__ptxdesc + 28), __value, BIT(29)) - -#endif /* __ODM_TYPES_H__ */ diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h index ed4091e7cc7e6..a1e88e6d5c0c7 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h @@ -14,7 +14,6 @@ #include "rtl8188e_xmit.h" #include "rtl8188e_cmd.h" #include "rtw_efuse.h" -#include "odm_types.h" #include "odm.h" #include "odm_HWConfig.h" #include "odm_RegDefine11N.h" -- GitLab From ef2a2422ab86d99e0bfd940c38c60b77c9ad9954 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 09:48:24 +0200 Subject: [PATCH 0020/1480] staging: r8188eu: convert rtw_init_evt_priv() to common error logic Convert the function rtw_init_evt_priv() to common kernel error logic. Return 0 on success and negative value on failure. This is part of getting rid of returning _SUCCESS and _FAIL which uses inverted error logic and is used all over the driver. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002074827.8566-3-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_cmd.c | 8 +++----- drivers/staging/r8188eu/include/rtw_cmd.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c index 3fadace33de65..88b939e42f5a1 100644 --- a/drivers/staging/r8188eu/core/rtw_cmd.c +++ b/drivers/staging/r8188eu/core/rtw_cmd.c @@ -90,10 +90,8 @@ u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) return _SUCCESS; } -u32 rtw_init_evt_priv(struct evt_priv *pevtpriv) +int rtw_init_evt_priv(struct evt_priv *pevtpriv) { - u32 res = _SUCCESS; - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ atomic_set(&pevtpriv->event_seq, 0); @@ -101,9 +99,9 @@ u32 rtw_init_evt_priv(struct evt_priv *pevtpriv) pevtpriv->c2h_wk_alive = false; pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1); if (!pevtpriv->c2h_queue) - res = _FAIL; + return -ENOMEM; - return res; + return 0; } void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 9a76aa85de940..c6c48e1fb9618 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -85,7 +85,7 @@ int rtw_cmd_thread(void *context); u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv); -u32 rtw_init_evt_priv(struct evt_priv *pevtpriv); +int rtw_init_evt_priv(struct evt_priv *pevtpriv); void rtw_free_evt_priv(struct evt_priv *pevtpriv); void rtw_evt_notify_isr(struct evt_priv *pevtpriv); u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 6a45315d01a29..dd4c89d7390dd 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -468,7 +468,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) padapter->cmdpriv.padapter = padapter; - if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) { + if (rtw_init_evt_priv(&padapter->evtpriv)) { dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_evt_priv failed\n"); goto free_cmd_priv; } -- GitLab From d4fda24757678311ff0a219bd150a3c3aeb6a2f8 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 09:48:25 +0200 Subject: [PATCH 0021/1480] staging: r8188eu: convert rtw_init_cmd_priv() to common error logic Convert the function rtw_init_cmd_priv() to common kernel error logic. Return 0 on success and negative value on failure. This is part of getting rid of returning _SUCCESS and _FAIL which uses inverted error logic and is used all over the driver. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002074827.8566-4-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_cmd.c | 8 ++++---- drivers/staging/r8188eu/include/rtw_cmd.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c index 88b939e42f5a1..fdc0c71e28a45 100644 --- a/drivers/staging/r8188eu/core/rtw_cmd.c +++ b/drivers/staging/r8188eu/core/rtw_cmd.c @@ -54,7 +54,7 @@ exit: return _SUCCESS; } -u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) +int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) { init_completion(&pcmdpriv->enqueue_cmd); /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ @@ -71,7 +71,7 @@ u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) GFP_KERNEL); if (!pcmdpriv->cmd_allocated_buf) - return _FAIL; + return -ENOMEM; pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ - 1)); @@ -79,7 +79,7 @@ u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) if (!pcmdpriv->rsp_allocated_buf) { kfree(pcmdpriv->cmd_allocated_buf); - return _FAIL; + return -ENOMEM; } pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3); @@ -87,7 +87,7 @@ u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) pcmdpriv->cmd_done_cnt = 0; pcmdpriv->rsp_cnt = 0; - return _SUCCESS; + return 0; } int rtw_init_evt_priv(struct evt_priv *pevtpriv) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index c6c48e1fb9618..8bbfeb42604fa 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -82,7 +82,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd); int rtw_cmd_thread(void *context); -u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); +int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv); int rtw_init_evt_priv(struct evt_priv *pevtpriv); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index dd4c89d7390dd..490e0c7dc0345 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -461,7 +461,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) u8 rtw_init_drv_sw(struct adapter *padapter) { - if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { + if (rtw_init_cmd_priv(&padapter->cmdpriv)) { dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_cmd_priv failed\n"); return _FAIL; } -- GitLab From 40b3f62227d46d21eab71832e331e3aa740b1b34 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 09:48:26 +0200 Subject: [PATCH 0022/1480] staging: r8188eu: convert rtw_init_mlme_priv() to common error logic Convert the function rtw_init_mlme_priv() to common kernel error logic. Return 0 on success and negative value on failure. This is part of getting rid of returning _SUCCESS and _FAIL which uses inverted error logic and is used all over the driver. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002074827.8566-5-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme.c | 12 ++++-------- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c index 5ca03d6cac32a..1f69e5c57d5d5 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme.c +++ b/drivers/staging/r8188eu/core/rtw_mlme.c @@ -224,7 +224,6 @@ int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) u8 *pbuf; struct wlan_network *pnetwork; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int res = _SUCCESS; /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ @@ -245,10 +244,9 @@ int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); - if (!pbuf) { - res = _FAIL; - goto exit; - } + if (!pbuf) + return -ENOMEM; + pmlmepriv->free_bss_buf = pbuf; pnetwork = (struct wlan_network *)pbuf; @@ -265,9 +263,7 @@ int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) rtw_init_mlme_timer(padapter); -exit: - - return res; + return 0; } void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 490e0c7dc0345..d8b8a5291e402 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -473,7 +473,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) goto free_cmd_priv; } - if (rtw_init_mlme_priv(padapter) == _FAIL) { + if (rtw_init_mlme_priv(padapter)) { dev_err(dvobj_to_dev(padapter->dvobj), "rtw_init_mlme_priv failed\n"); goto free_evt_priv; } -- GitLab From fd692ab4c511a4dd5685e9e34e4ee69ddc362675 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 09:48:27 +0200 Subject: [PATCH 0023/1480] staging: r8188eu: convert _rtw_init_sta_priv() to common error logic Convert the function _rtw_init_sta_priv() to common kernel error logic. Return 0 on success and negative value on failure. This is part of getting rid of returning _SUCCESS and _FAIL which uses inverted error logic and is used all over the driver. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002074827.8566-6-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_sta_mgt.c | 6 +++--- drivers/staging/r8188eu/include/sta_info.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c index 98eeb16cab6c8..bbde5c03f9ae0 100644 --- a/drivers/staging/r8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/r8188eu/core/rtw_sta_mgt.c @@ -45,7 +45,7 @@ static void _rtw_init_stainfo(struct sta_info *psta) psta->keep_alive_trycnt = 0; } -u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) +int _rtw_init_sta_priv(struct sta_priv *pstapriv) { struct sta_info *psta; s32 i; @@ -53,7 +53,7 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4); if (!pstapriv->pallocated_stainfo_buf) - return _FAIL; + return -ENOMEM; pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - ((size_t)(pstapriv->pallocated_stainfo_buf) & 3); @@ -93,7 +93,7 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) pstapriv->expire_to = 3; /* 3*2 = 6 sec */ pstapriv->max_num_sta = NUM_STA; - return _SUCCESS; + return 0; } inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h index 4112c837bcefb..f76e086b5701f 100644 --- a/drivers/staging/r8188eu/include/sta_info.h +++ b/drivers/staging/r8188eu/include/sta_info.h @@ -295,7 +295,7 @@ static inline u32 wifi_mac_hash(u8 *mac) return x; } -extern u32 _rtw_init_sta_priv(struct sta_priv *pstapriv); +extern int _rtw_init_sta_priv(struct sta_priv *pstapriv); extern void _rtw_free_sta_priv(struct sta_priv *pstapriv); #define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index d8b8a5291e402..e43ef7e5ba708 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -494,7 +494,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) goto free_xmit_priv; } - if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { + if (_rtw_init_sta_priv(&padapter->stapriv)) { dev_err(dvobj_to_dev(padapter->dvobj), "_rtw_init_sta_priv failed\n"); goto free_recv_priv; } -- GitLab From a609750c8bf0e29060862f2f232f775129c31593 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 16:35:43 +0200 Subject: [PATCH 0024/1480] staging: r8188eu: convert rtw_reset_drv_sw() to void The function rtw_reset_drv_sw() always returns _SUCCESS. None of its callers use the return value. Convert the return type of that function from u8 to void. This is part of getting rid of _FAIL / _SUCCESS. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002143544.7974-2-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/osdep_intf.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h index 36511c4695461..ce8e1bc4a61ca 100644 --- a/drivers/staging/r8188eu/include/osdep_intf.h +++ b/drivers/staging/r8188eu/include/osdep_intf.h @@ -44,7 +44,7 @@ int netdev_close(struct net_device *pnetdev); u8 rtw_init_drv_sw(struct adapter *padapter); u8 rtw_free_drv_sw(struct adapter *padapter); -u8 rtw_reset_drv_sw(struct adapter *padapter); +void rtw_reset_drv_sw(struct adapter *padapter); u32 rtw_start_drv_threads(struct adapter *padapter); void rtw_stop_drv_threads (struct adapter *padapter); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index e43ef7e5ba708..2983e665bd5c4 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -433,7 +433,7 @@ static void rtw_init_default_value(struct adapter *padapter) padapter->bShowGetP2PState = 1; } -u8 rtw_reset_drv_sw(struct adapter *padapter) +void rtw_reset_drv_sw(struct adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -455,8 +455,6 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; rtw_set_signal_stat_timer(&padapter->recvpriv); - - return _SUCCESS; } u8 rtw_init_drv_sw(struct adapter *padapter) -- GitLab From c55f29446d175049700bdfb41a8d30fa67640d15 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 2 Oct 2022 16:35:44 +0200 Subject: [PATCH 0025/1480] staging: r8188eu: convert rtw_free_drv_sw() to void The function rtw_free_drv_sw() always returns _SUCCESS. None of its callers use the return value. Convert the return type of that function from u8 to void. This is part of getting rid of _FAIL / _SUCCESS. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221002143544.7974-3-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/osdep_intf.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h index ce8e1bc4a61ca..0f7d74a3ff6df 100644 --- a/drivers/staging/r8188eu/include/osdep_intf.h +++ b/drivers/staging/r8188eu/include/osdep_intf.h @@ -43,7 +43,7 @@ int netdev_open(struct net_device *pnetdev); int netdev_close(struct net_device *pnetdev); u8 rtw_init_drv_sw(struct adapter *padapter); -u8 rtw_free_drv_sw(struct adapter *padapter); +void rtw_free_drv_sw(struct adapter *padapter); void rtw_reset_drv_sw(struct adapter *padapter); u32 rtw_start_drv_threads(struct adapter *padapter); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 2983e665bd5c4..38e324754c8fa 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -548,7 +548,7 @@ void rtw_cancel_all_timer(struct adapter *padapter) _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer); } -u8 rtw_free_drv_sw(struct adapter *padapter) +void rtw_free_drv_sw(struct adapter *padapter) { /* we can call rtw_p2p_enable here, but: */ /* 1. rtw_p2p_enable may have IO operation */ @@ -585,8 +585,6 @@ u8 rtw_free_drv_sw(struct adapter *padapter) /* clear pbuddystruct adapter to avoid access wrong pointer. */ if (padapter->pbuddy_adapter) padapter->pbuddy_adapter->pbuddy_adapter = NULL; - - return _SUCCESS; } void netdev_br_init(struct net_device *netdev) -- GitLab From c21899dcab317de9007e65dbf218400782ee064c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 4 Oct 2022 16:09:44 +0100 Subject: [PATCH 0026/1480] staging: rtl8192u: Fix spelling mistake athros -> Atheros and fix grammer There is a spellig mistake, correct it and fix capital letter on the proper noun. Also fix the grammar. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221004150944.148157-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index b58e75932ecd5..f142d09869901 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -1806,7 +1806,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[0] == 0x00 && info_element->data[1] == 0x13 && info_element->data[2] == 0x74)) { - netdev_dbg(ieee->dev, "========> athros AP is exist\n"); + netdev_dbg(ieee->dev, "========> Atheros AP exists\n"); network->atheros_cap_exist = true; } else network->atheros_cap_exist = false; -- GitLab From 0fd4d8b7e87e472d54fdb4912703c1c09d12ac70 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 4 Oct 2022 16:35:39 +0100 Subject: [PATCH 0027/1480] staging: rtl8723bs: Remove redundant initialization of variable efuseValue The variable efuseValue is being initialized with a value that is never read. The variable is being re-assigned later on. The initialization is redundant and can be removed. Cleans up warning: drivers/staging/rtl8723bs/core/rtw_efuse.c:285:6: warning: variable 'efuseValue' set but not used [-Wunused-but-set-variable] Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221004153539.150867-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_efuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c index 06e727ce9cc29..eb848f9bbf2c3 100644 --- a/drivers/staging/rtl8723bs/core/rtw_efuse.c +++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c @@ -282,7 +282,7 @@ u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoT { u8 tmpidx = 0; u8 bResult = false; - u32 efuseValue = 0; + u32 efuseValue; if (bPseudoTest) return Efuse_Write1ByteToFakeContent(addr, data); -- GitLab From dcf478ab1566ceb6c7796b3830bd340e50bb3f73 Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Wed, 19 Oct 2022 12:31:10 -0700 Subject: [PATCH 0028/1480] staging: rtl8723bs: Removed extra tabs in conditional statements checkpatch found extra tabs in two conditional statements in rtw_ieee80211.c. Should be one tab instead of two. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/Y1BQfiwOXzAZpCCa@marshmallow Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index 3d8a64f694481..30e7457a9c312 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -1063,18 +1063,18 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork) /* parsing HT_CAP_IE */ p = rtw_get_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, pnetwork->network.ie_length - _FIXED_IE_LENGTH_); if (p && len > 0) { - pht_cap = (struct ieee80211_ht_cap *)(p + 2); - pnetwork->bcn_info.ht_cap_info = le16_to_cpu(pht_cap->cap_info); + pht_cap = (struct ieee80211_ht_cap *)(p + 2); + pnetwork->bcn_info.ht_cap_info = le16_to_cpu(pht_cap->cap_info); } else { - pnetwork->bcn_info.ht_cap_info = 0; + pnetwork->bcn_info.ht_cap_info = 0; } /* parsing HT_INFO_IE */ p = rtw_get_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_OPERATION, &len, pnetwork->network.ie_length - _FIXED_IE_LENGTH_); if (p && len > 0) { - pht_info = (struct HT_info_element *)(p + 2); - pnetwork->bcn_info.ht_info_infos_0 = pht_info->infos[0]; + pht_info = (struct HT_info_element *)(p + 2); + pnetwork->bcn_info.ht_info_infos_0 = pht_info->infos[0]; } else { - pnetwork->bcn_info.ht_info_infos_0 = 0; + pnetwork->bcn_info.ht_info_infos_0 = 0; } } -- GitLab From 1850f1598d4a991289628487648e17f2631e37df Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Wed, 19 Oct 2022 19:10:52 -0700 Subject: [PATCH 0029/1480] staging: rtl8723bs: align block comment stars Align '*' on each line of block comment in rtw_ioctl_set. Issue found by checkpatch. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/3d9738edd0992b72bf8fc8a05706a490772b5317.1666230736.git.eperi1024@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index 8c11daff2d590..f15dbf450ff4d 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -462,11 +462,11 @@ exit: } /* -* rtw_get_cur_max_rate - -* @adapter: pointer to struct adapter structure -* -* Return 0 or 100Kbps -*/ + * rtw_get_cur_max_rate - + * @adapter: pointer to struct adapter structure + * + * Return 0 or 100Kbps + */ u16 rtw_get_cur_max_rate(struct adapter *adapter) { int i = 0; -- GitLab From d9e57cc302f33fcbcd12fe9cca6213d520e0537c Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Wed, 19 Oct 2022 19:10:53 -0700 Subject: [PATCH 0030/1480] staging: rtl8723bs: remove unnecessary parenthesis Remove extra parenthesis in conditional statement in rtw_ioctl_set. Issue found by checkpatch. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/a08a440eabddd8e78d045ca9898a415d81f6f6d7.1666230736.git.eperi1024@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index f15dbf450ff4d..8c7daab141db4 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -159,7 +159,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { if ((pmlmepriv->assoc_ssid.ssid_length == ssid->ssid_length) && (!memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid, ssid->ssid_length))) { - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false) { if (rtw_is_same_ibss(padapter, pnetwork) == false) { /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ rtw_disassoc_cmd(padapter, 0, true); -- GitLab From b860ce04ac409386e4261931525ac3b3ac1758e1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 7 Oct 2022 21:29:41 +0100 Subject: [PATCH 0031/1480] staging: sm750fb: Kconfig: Fix spelling mistake "accelearion" -> "acceleration" There is a spelling mistake in a Kconfig description. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221007202941.2756304-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig index 8c0d8a873d5b0..2101a6605efc3 100644 --- a/drivers/staging/sm750fb/Kconfig +++ b/drivers/staging/sm750fb/Kconfig @@ -8,7 +8,7 @@ config FB_SM750 select FB_CFB_IMAGEBLIT help Frame buffer driver for the Silicon Motion SM750 chip - with 2D accelearion and dual head support. + with 2D acceleration and dual head support. This driver is also available as a module. The module will be called sm750fb. If you want to compile it as a module, say M -- GitLab From 6c2fb5dfb640ebc8b40a98b6c4337e9fb9f87ee3 Mon Sep 17 00:00:00 2001 From: Dragan Cvetic Date: Mon, 10 Oct 2022 20:02:51 +0100 Subject: [PATCH 0032/1480] staging: rtl8192e: Remove single statement braces Remove braces around single line statement, to resolve checkpatch.pl warnings "braces {} are not necessary for single statement blocks" Signed-off-by: Dragan Cvetic Link: https://lore.kernel.org/r/20221010190252.12402-1-dragan.m.cvetic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 702551056227d..d7bfaf68291c2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -267,10 +267,8 @@ static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev) "PATH=/usr/bin:/bin", NULL}; - if (priv->ResetProgress == RESET_TYPE_SILENT) { + if (priv->ResetProgress == RESET_TYPE_SILENT) return; - } - if (priv->rtllib->state != RTLLIB_LINKED) return; call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC); @@ -330,9 +328,8 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) bool bshort_gi_enabled = false; static u8 ping_rssi_state; - if (!priv->up) { + if (!priv->up) return; - } if (pra->rate_adaptive_disabled) return; @@ -777,9 +774,8 @@ static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev) tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); for (i = 0; i < OFDM_Table_Length; i++) { - if (tmpRegA == OFDMSwingTable[i]) { + if (tmpRegA == OFDMSwingTable[i]) priv->OFDM_index[0] = i; - } } TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2); @@ -1066,9 +1062,8 @@ void rtl92e_dm_restore_state(struct net_device *dev) u32 reg_ratr = priv->rate_adaptive.last_ratr; u32 ratr_value; - if (!priv->up) { + if (!priv->up) return; - } if (priv->rate_adaptive.rate_adaptive_disabled) return; -- GitLab From 2122a86d426381069f279d9e6a71323cfc0da39f Mon Sep 17 00:00:00 2001 From: Dragan Cvetic Date: Mon, 10 Oct 2022 20:04:55 +0100 Subject: [PATCH 0033/1480] staging: rtl8192e: Rename CurSTAConnectState and PreSTAConnectState Rename variable CurSTAConnectState to cur_sta_connect_state, PreSTAConnectState to pre_sta_connect_state to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Dragan Cvetic Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/20221010190457.13199-2-dragan.m.cvetic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 22 +++++++++++----------- drivers/staging/rtl8192e/rtl8192e/rtl_dm.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index d7bfaf68291c2..0572ce40290e8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -1138,8 +1138,8 @@ static void _rtl92e_dm_dig_init(struct net_device *dev) dm_digtable.dig_state = DM_STA_DIG_MAX; dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; - dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT; + dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT; + dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT; dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; @@ -1207,9 +1207,9 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev) } if (priv->rtllib->state == RTLLIB_LINKED) - dm_digtable.CurSTAConnectState = DIG_STA_CONNECT; + dm_digtable.cur_sta_connect_state = DIG_STA_CONNECT; else - dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; + dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT; dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; @@ -1218,7 +1218,7 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev) _rtl92e_dm_cs_ratio(dev); if (dm_digtable.dig_algorithm_switch) dm_digtable.dig_algorithm_switch = 0; - dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState; + dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state; } @@ -1368,8 +1368,8 @@ static void _rtl92e_dm_initial_gain(struct net_device *dev) return; } - if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { - if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { + if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { long gain_range = dm_digtable.rssi_val + 10 - dm_digtable.backoff_val; gain_range = clamp_t(long, gain_range, @@ -1419,8 +1419,8 @@ static void _rtl92e_dm_pd_th(struct net_device *dev) reset_cnt = 0; } - if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { - if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { + if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) dm_digtable.curpd_thstate = @@ -1487,8 +1487,8 @@ static void _rtl92e_dm_cs_ratio(struct net_device *dev) reset_cnt = 0; } - if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { - if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { + if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h index 51e295d389a83..89c58e38c1f7d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h @@ -66,8 +66,8 @@ struct dig_t { u8 dig_state; u8 dig_highpwr_state; - u8 CurSTAConnectState; - u8 PreSTAConnectState; + u8 cur_sta_connect_state; + u8 pre_sta_connect_state; u8 curpd_thstate; u8 prepd_thstate; -- GitLab From 9adc341cdcf63a4343fdb8c45aa46cafcd8dffae Mon Sep 17 00:00:00 2001 From: Dragan Cvetic Date: Mon, 10 Oct 2022 20:04:57 +0100 Subject: [PATCH 0034/1480] staging: rtl8192e: Rename Op, Length and Value Rename variable Op to op, Length to length and Value to value to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Dragan Cvetic Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/20221010190457.13199-4-dragan.m.cvetic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 6 +++--- drivers/staging/rtl8192e/rtl8192e/rtl_dm.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 0572ce40290e8..c9e495538e2c7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -628,9 +628,9 @@ static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) for (j = 0; j <= 30; j++) { - tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; - tx_cmd.Length = 4; - tx_cmd.Value = Value; + tx_cmd.op = TXCMD_SET_TX_PWR_TRACKING; + tx_cmd.length = 4; + tx_cmd.value = Value; rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_NORMAL, (u8 *)&tx_cmd, sizeof(struct dcmd_txcmd)); mdelay(1); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h index 89c58e38c1f7d..1d4d7d98a8599 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h @@ -152,9 +152,9 @@ enum dm_cck_rx_path_method { struct dcmd_txcmd { - u32 Op; - u32 Length; - u32 Value; + u32 op; + u32 length; + u32 value; }; /*------------------------------Define structure----------------------------*/ -- GitLab From 04a5673391a5c56831f09b11a7735035e4a1ea62 Mon Sep 17 00:00:00 2001 From: Rui Li Date: Wed, 12 Oct 2022 22:36:33 +0800 Subject: [PATCH 0035/1480] staging: rtl8192e: remove unnecessary braces for single statement blocks This commit cleans up checkpatch warning as follows: braces {} are not necessary for single statement blocks Signed-off-by: Rui Li Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/166558541522.9.15423282339326993462.68459319@lirui.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 3 +-- drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c | 9 +++------ drivers/staging/rtl8192e/rtllib_softmac_wx.c | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index c3dcaa27fd2ea..210b7ecc273ab 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1106,9 +1106,8 @@ void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, if (cb_desc->bHwSec) { static u8 tmp; - if (!tmp) { + if (!tmp) tmp = 1; - } switch (priv->rtllib->pairwise_key_type) { case KEY_TYPE_WEP40: case KEY_TYPE_WEP104: diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index a44dffa76a39e..58da2dab55bd6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -522,9 +522,8 @@ static bool _rtl92e_bb_config_para_file(struct net_device *dev) rtStatus = rtl92e_check_bb_and_rf(dev, (enum hw90_block)eCheckItem, (enum rf90_radio_path)0); - if (!rtStatus) { + if (!rtStatus) return rtStatus; - } } rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); _rtl92e_phy_config_bb(dev, BaseBand_Config_PHY_REG); @@ -1378,9 +1377,8 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, i++; } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { + if (i >= MAX_DOZE_WAITING_TIMES_9x) break; - } } rtl92e_set_rf_off(dev); break; @@ -1397,9 +1395,8 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, i++; } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { + if (i >= MAX_DOZE_WAITING_TIMES_9x) break; - } } if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index f9589c5b62bac..fdf867a5dd7a2 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -571,9 +571,8 @@ int rtllib_wx_set_power(struct rtllib_device *ieee, ieee->ps = RTLLIB_PS_DISABLED; goto exit; } - if (wrqu->power.flags & IW_POWER_TIMEOUT) { + if (wrqu->power.flags & IW_POWER_TIMEOUT) ieee->ps_timeout = wrqu->power.value / 1000; - } if (wrqu->power.flags & IW_POWER_PERIOD) ieee->ps_period = wrqu->power.value / 1000; -- GitLab From 06b764cf60877bdd6604c173963501e16236ccdf Mon Sep 17 00:00:00 2001 From: Rigel Di Scala Date: Wed, 12 Oct 2022 21:16:12 +0000 Subject: [PATCH 0036/1480] Staging: rtl8192e: fix a brace style issue Fixed a coding style issue affecting a conditional if statement. Signed-off-by: Rigel Di Scala Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/20221012211612.75871-1-zedr@zedr.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 19d13b3fcecf7..e932ad1a9e962 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -180,11 +180,10 @@ static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); - if (skb) { + if (skb) softmac_mgmt_xmit(skb, ieee); - } else { + else netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n"); - } } static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, -- GitLab From c5997186452ae29b535fd6cb65b4f5534b52ea25 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:32 +0200 Subject: [PATCH 0037/1480] staging: r8188eu: replace one GetAddr3Ptr call Define a struct ieee80211_mgmt for the message that we process in OnDeAuth. Use this struct to read the bssid. This patch removes one GetAddr3Ptr call, getting us a tiny step closer to removing GetAddr3Ptr. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 07905e2ae8e05..0c4b3b99150d7 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1457,6 +1457,7 @@ report_assoc_result: unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; unsigned short reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1464,8 +1465,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) u8 *pframe = precv_frame->rx_data; struct wifidirect_info *pwdinfo = &padapter->wdinfo; - /* check A3 */ - if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) return _SUCCESS; if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { -- GitLab From f54ded554f04cc0e7f5edcc571d9c09581f67312 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:33 +0200 Subject: [PATCH 0038/1480] staging: r8188eu: get reason code from mgmt struct Read the deauth reson code from the newly added mgmt structure instead of calculating the offset ourselves. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 0c4b3b99150d7..5c59fc91ecaec 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1473,7 +1473,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); } - reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); + reason = le16_to_cpu(mgmt->u.disassoc.reason_code); if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { struct sta_info *psta; -- GitLab From 8ea03e32f51475f10ebf430fece7c3f8b8fa476b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:34 +0200 Subject: [PATCH 0039/1480] staging: r8188eu: clarify the bBusyTraffic assignment bBusyTraffic is set only if we're not in WIFI_AP_STATE, i.e. in the else branch. If we were not in WIFI_AP_STATE, we'd go into the if branch and return _SUCCESS before making it to the bBusyTraffic assignment. Move the assignment into the else branch to make this clearer. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 5c59fc91ecaec..fd2daeca71128 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1515,8 +1515,9 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) if (!ignore_received_deauth) receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); + + pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } - pmlmepriv->LinkDetectInfo.bBusyTraffic = false; return _SUCCESS; } -- GitLab From 15697b04e42e399f1c74d484f130859df756b1ae Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:35 +0200 Subject: [PATCH 0040/1480] staging: r8188eu: use sa instead of Addr2 For management frames, Addr2 is the Source Address (SA). Use sa from the mgmt structure and remove the GetAddr2Ptr call. GetAddr2Ptr is a driver-specific function that we should eventually remove. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index fd2daeca71128..732ada6ab9325 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1479,7 +1479,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; - psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (psta) { u8 updated = 0; -- GitLab From 094fbfbac3570345dbcb946dd2785bad03b680cf Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:36 +0200 Subject: [PATCH 0041/1480] staging: r8188eu: get bssid from mgmt struct For management frames, Addr3 is the BSSID. Read it from the mgmt structure instead of calling GetAddr3Ptr. The pframe variable is now unused and can be removed. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 732ada6ab9325..742976c38cd56 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1462,7 +1462,6 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - u8 *pframe = precv_frame->rx_data; struct wifidirect_info *pwdinfo = &padapter->wdinfo; if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) @@ -1514,7 +1513,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) } if (!ignore_received_deauth) - receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); + receive_disconnect(padapter, mgmt->bssid, reason); pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } -- GitLab From ece8119070de777c7a1685211c8056a2ce6d3df8 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:37 +0200 Subject: [PATCH 0042/1480] staging: r8188eu: exit for deauth from unknown station If we receive a deauth message from an unknown station, we can drop this message and exit immediately. Reorder the code to make this clearer, don't wrap everything in an if statement. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 742976c38cd56..40df0f9982f4a 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1477,21 +1477,21 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; + u8 updated = 0; psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - u8 updated = 0; - - spin_lock_bh(&pstapriv->asoc_list_lock); - if (!list_empty(&psta->asoc_list)) { - list_del_init(&psta->asoc_list); - pstapriv->asoc_list_cnt--; - updated = ap_free_sta(padapter, psta, false, reason); - } - spin_unlock_bh(&pstapriv->asoc_list_lock); + if (!psta) + return _SUCCESS; - associated_clients_update(padapter, updated); + spin_lock_bh(&pstapriv->asoc_list_lock); + if (!list_empty(&psta->asoc_list)) { + list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, false, reason); } + spin_unlock_bh(&pstapriv->asoc_list_lock); + + associated_clients_update(padapter, updated); return _SUCCESS; } else { -- GitLab From 6325d858c48d2fefe1c93da36f74b506d7abf71d Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:38 +0200 Subject: [PATCH 0043/1480] staging: r8188eu: remove unnecessary return Remove the return statement at the end of the if branch. We can continue to the final return after the if-else. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 40df0f9982f4a..465f51bce0e30 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1492,8 +1492,6 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) spin_unlock_bh(&pstapriv->asoc_list_lock); associated_clients_update(padapter, updated); - - return _SUCCESS; } else { int ignore_received_deauth = 0; -- GitLab From 000848a511fc77b26864f2d95c8efa853e6bf82f Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:39 +0200 Subject: [PATCH 0044/1480] staging: r8188eu: summarize two flags checks Summarize the two statements to check if either WIFI_FW_AUTH_STATE or WIFI_FW_ASSOC_STATE is set. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 465f51bce0e30..09ffecc5b2b3a 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1500,8 +1500,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) * However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. * Added the following code to avoid this case. */ - if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || - (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) { + if (pmlmeinfo->state & (WIFI_FW_AUTH_STATE | WIFI_FW_ASSOC_STATE)) { if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { ignore_received_deauth = 1; } else if (reason == WLAN_REASON_PREV_AUTH_NOT_VALID) { -- GitLab From e2c532aadd86fd51ebde566e6af74b1eb1be89e0 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:24:40 +0200 Subject: [PATCH 0045/1480] staging: r8188eu: ignore_received_deauth is a boolean The ignore_received_deauth is in fact a boolean variable. Change its type to bool and use true, false for its values. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Acked-by: Pavel Skripkin Link: https://lore.kernel.org/r/20221015152440.232281-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 09ffecc5b2b3a..fda446b6779c3 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1493,7 +1493,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) associated_clients_update(padapter, updated); } else { - int ignore_received_deauth = 0; + bool ignore_received_deauth = false; /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, * we will send the deauth first. @@ -1502,10 +1502,10 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) */ if (pmlmeinfo->state & (WIFI_FW_AUTH_STATE | WIFI_FW_ASSOC_STATE)) { if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { - ignore_received_deauth = 1; + ignore_received_deauth = true; } else if (reason == WLAN_REASON_PREV_AUTH_NOT_VALID) { // TODO: 802.11r - ignore_received_deauth = 1; + ignore_received_deauth = true; } } -- GitLab From 92b81816d5f867c2b1017970786e0f50882a33f7 Mon Sep 17 00:00:00 2001 From: Anjandev Momi Date: Fri, 14 Oct 2022 01:18:37 -0700 Subject: [PATCH 0046/1480] Staging: rtl8192e: remove unnecessary parentheses This patch removes the following CHECK generated by checkpatch.pl: ./drivers/staging/rtl8192e/rtl819x_BAProc.c:116: CHECK: Unnecessary parentheses around pBA->ba_start_seq_ctrl ./drivers/staging/rtl8192e/rtl819x_BAProc.c:261: CHECK: Unnecessary parentheses around '&pTS' ./drivers/staging/rtl8192e/rtl819x_BAProc.c:346: CHECK: Unnecessary parentheses around '&pTS' Signed-off-by: Anjandev Momi Link: https://lore.kernel.org/r/20221014081839.23902-2-anjan@momi.ca Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index e932ad1a9e962..f208ee1b29555 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -111,7 +111,7 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, tag += 2; if (type == ACT_ADDBAREQ) { - memcpy(tag, (u8 *)&(pBA->ba_start_seq_ctrl), 2); + memcpy(tag, (u8 *)&pBA->ba_start_seq_ctrl, 2); tag += 2; } @@ -253,7 +253,7 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) ieee->pHTInfo->bCurrentHTSupport); goto OnADDBAReq_Fail; } - if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, (u8)(pBaParamSet->field.tid), RX_DIR, true)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); @@ -337,7 +337,7 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) goto OnADDBARsp_Reject; } - if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, (u8)(pBaParamSet->field.tid), TX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; -- GitLab From a079a4b2c9bc40b00cad01a1babf209acab1eea2 Mon Sep 17 00:00:00 2001 From: Anjandev Momi Date: Fri, 14 Oct 2022 01:18:38 -0700 Subject: [PATCH 0047/1480] Staging: rtl8192e: remove multiple blank lines This patch removes the following checks generated by checkpatch.pl: ./drivers/staging/rtl8192e/rtl819x_BAProc.c:164: CHECK: Please don't use multiple blank lines ./drivers/staging/rtl8192e/rtl819x_BAProc.c:383: CHECK: Please don't use multiple blank lines Signed-off-by: Anjandev Momi Link: https://lore.kernel.org/r/20221014081839.23902-3-anjan@momi.ca Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index f208ee1b29555..94131a5983f1e 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -159,7 +159,6 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, *tag++ = ACT_CAT_BA; *tag++ = ACT_DELBA; - put_unaligned_le16(DelbaParamSet.short_data, tag); tag += 2; @@ -374,7 +373,6 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) goto OnADDBARsp_Reject; } - pAdmittedBA->dialog_token = *pDialogToken; pAdmittedBA->ba_timeout_value = *pBaTimeoutVal; pAdmittedBA->ba_start_seq_ctrl = pPendingBA->ba_start_seq_ctrl; -- GitLab From 2f618d1167b59dc7270be86f89819cf3417c192f Mon Sep 17 00:00:00 2001 From: Anjandev Momi Date: Fri, 14 Oct 2022 01:18:39 -0700 Subject: [PATCH 0048/1480] Staging: rtl8192e: make alignment match open parenthesis This patch removes the following checks generated by checkpatch.pl: ./drivers/staging/rtl8192e/rtl819x_BAProc.c:261: CHECK: Alignment should match open parenthesis ./drivers/staging/rtl8192e/rtl819x_BAProc.c:284: CHECK: Alignment should match open parenthesis ./drivers/staging/rtl8192e/rtl819x_BAProc.c:421: CHECK: Alignment should match open parenthesis ./drivers/staging/rtl8192e/rtl819x_BAProc.c:441: CHECK: Alignment should match open parenthesis Signed-off-by: Anjandev Momi Link: https://lore.kernel.org/r/20221014081839.23902-4-anjan@momi.ca Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 94131a5983f1e..a7aa772778d39 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -253,7 +253,7 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) goto OnADDBAReq_Fail; } if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, - (u8)(pBaParamSet->field.tid), RX_DIR, true)) { + (u8)(pBaParamSet->field.tid), RX_DIR, true)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); goto OnADDBAReq_Fail; @@ -412,7 +412,7 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) } if (!ieee->current_network.qos_data.active || - !ieee->pHTInfo->bCurrentHTSupport) { + !ieee->pHTInfo->bCurrentHTSupport) { netdev_warn(ieee->dev, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network. qos_data.active, @@ -432,7 +432,7 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) struct rx_ts_record *pRxTs; if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, - (u8)pDelBaParamSet->field.tid, RX_DIR, false)) { + (u8)pDelBaParamSet->field.tid, RX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", __func__, dst, -- GitLab From 98703e4264afe64cbf2c5a4b6589d6e2a3068833 Mon Sep 17 00:00:00 2001 From: Anjandev Momi Date: Fri, 14 Oct 2022 01:18:40 -0700 Subject: [PATCH 0049/1480] Staging: rtl8192e: add blank line after function declaration This patch removes the following check generated by checkpatch.pl ./drivers/staging/rtl8192e/rtl819x_BAProc.c:65: CHECK: Please use a blank line after function/struct/union/enum declarations Signed-off-by: Anjandev Momi Link: https://lore.kernel.org/r/20221014081839.23902-5-anjan@momi.ca Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index a7aa772778d39..7c0369319f97f 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -62,6 +62,7 @@ void ResetBaEntry(struct ba_record *pBA) pBA->dialog_token = 0; pBA->ba_start_seq_ctrl.short_data = 0; } + static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, struct ba_record *pBA, u16 StatusCode, u8 type) -- GitLab From 12c6223fc1804fd9295dc50d358294539b4a4184 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:06 +0200 Subject: [PATCH 0050/1480] staging: r8188eu: fix led register settings Using an InterTech DMG-02 dongle, the led remains on when the system goes into standby mode. After wakeup, it's no longer possible to control the led. It turned out that the register settings to enable or disable the led were not correct. They worked for some dongles like the Edimax V2 but not for others like the InterTech DMG-02. This patch fixes the register settings. Bit 3 in the led_cfg2 register controls the led status, bit 5 must always be set to be able to control the led, bit 6 has no influence on the led. Setting the mac_pinmux_cfg register is not necessary. These settings were tested with Edimax V2 and InterTech DMG-02. Cc: stable@vger.kernel.org Fixes: 8cd574e6af54 ("staging: r8188eu: introduce new hal dir for RTL8188eu driver") Suggested-by: Michael Straube Signed-off-by: Martin Kaiser Tested-by: Michael Straube # InterTech DMG-02, Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 2527c252c3e95..5b214488571bb 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -31,40 +31,19 @@ static void ResetLedStatus(struct led_priv *pLed) static void SwLedOn(struct adapter *padapter, struct led_priv *pLed) { - u8 LedCfg; - int res; - if (padapter->bDriverStopped) return; - res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg); - if (res) - return; - - rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */ + rtw_write8(padapter, REG_LEDCFG2, BIT(5)); /* SW control led0 on. */ pLed->bLedOn = true; } static void SwLedOff(struct adapter *padapter, struct led_priv *pLed) { - u8 LedCfg; - int res; - if (padapter->bDriverStopped) goto exit; - res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */ - if (res) - goto exit; - - LedCfg &= 0x90; /* Set to software control. */ - rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3))); - res = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg); - if (res) - goto exit; - - LedCfg &= 0xFE; - rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg); + rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)); exit: pLed->bLedOn = false; } -- GitLab From e5931b7ba5a9ccfea6e36f9f07eac89091782e9b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:07 +0200 Subject: [PATCH 0051/1480] staging: r8188eu: handle rtw_write8 errors in SwLedOn Check the status returned by rtw_write8. Update bLedOn only if we could update the REG_LEDCFG2 register. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 5b214488571bb..4f1cad890cae7 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -34,7 +34,9 @@ static void SwLedOn(struct adapter *padapter, struct led_priv *pLed) if (padapter->bDriverStopped) return; - rtw_write8(padapter, REG_LEDCFG2, BIT(5)); /* SW control led0 on. */ + if (rtw_write8(padapter, REG_LEDCFG2, BIT(5)) != _SUCCESS) + return; + pLed->bLedOn = true; } -- GitLab From ef032c4fa43655715a39378d23cf3cc943cfdafa Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:08 +0200 Subject: [PATCH 0052/1480] staging: r8188eu: fix status updates in SwLedOff Update bLedOn only if we could update the REG_LEDCFG2 register. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 4f1cad890cae7..38433296d327f 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -43,10 +43,11 @@ static void SwLedOn(struct adapter *padapter, struct led_priv *pLed) static void SwLedOff(struct adapter *padapter, struct led_priv *pLed) { if (padapter->bDriverStopped) - goto exit; + return; + + if (rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)) != _SUCCESS) + return; - rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)); -exit: pLed->bLedOn = false; } -- GitLab From c16a98833a9979c15febdc60a3ab5d00c72c1b5e Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:09 +0200 Subject: [PATCH 0053/1480] staging: r8188eu: SwLedOn needs no padapter parameter Remove the padapter parameter from the SwLedOn function. padapter can be derived from the pLed parameter. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 38433296d327f..aa8f41edfade8 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -29,8 +29,10 @@ static void ResetLedStatus(struct led_priv *pLed) pLed->bLedScanBlinkInProgress = false; } -static void SwLedOn(struct adapter *padapter, struct led_priv *pLed) +static void SwLedOn(struct led_priv *pLed) { + struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); + if (padapter->bDriverStopped) return; @@ -67,7 +69,7 @@ static void blink_work(struct work_struct *work) if (pLed->bLedOn) SwLedOff(padapter, pLed); else - SwLedOn(padapter, pLed); + SwLedOn(pLed); switch (pLed->CurrLedState) { case LED_BLINK_SLOWLY: -- GitLab From 728a14bf8f1e095f6edddcf15f70c9307ec1f0ca Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:10 +0200 Subject: [PATCH 0054/1480] staging: r8188eu: SwLedOff needs no padapter parameter Remove the padapter parameter from the SwLedOff function. padapter can be derived from the pLed parameter. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index aa8f41edfade8..56f043d8ff38e 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -42,8 +42,10 @@ static void SwLedOn(struct led_priv *pLed) pLed->bLedOn = true; } -static void SwLedOff(struct adapter *padapter, struct led_priv *pLed) +static void SwLedOff(struct led_priv *pLed) { + struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); + if (padapter->bDriverStopped) return; @@ -61,13 +63,13 @@ static void blink_work(struct work_struct *work) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff(padapter, pLed); + SwLedOff(pLed); ResetLedStatus(pLed); return; } if (pLed->bLedOn) - SwLedOff(padapter, pLed); + SwLedOff(pLed); else SwLedOn(pLed); @@ -141,7 +143,7 @@ void rtl8188eu_DeInitSwLeds(struct adapter *padapter) cancel_delayed_work_sync(&ledpriv->blink_work); ResetLedStatus(ledpriv); - SwLedOff(padapter, ledpriv); + SwLedOff(ledpriv); } void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) @@ -258,7 +260,7 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) pLed->bLedWPSBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; cancel_delayed_work(&pLed->blink_work); - SwLedOff(padapter, pLed); + SwLedOff(pLed); break; default: break; -- GitLab From 4fc4de550eb0fb47514ee0f37f9a0abd4d4bf2c9 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:11 +0200 Subject: [PATCH 0055/1480] staging: r8188eu: remove two unused defines The C2H_MEM_SZ and FREE_CMDOBJ_SZ defines are not used by the r8188eu driver. Remove them. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_cmd.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 8bbfeb42604fa..0cb054909bc65 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -8,13 +8,9 @@ #include "rtw_rf.h" #include "rtw_led.h" -#define C2H_MEM_SZ (16*1024) - #include "osdep_service.h" #include "ieee80211.h" /* */ -#define FREE_CMDOBJ_SZ 128 - #define MAX_CMDSZ 1024 #define MAX_RSPSZ 512 #define MAX_EVTSZ 1024 -- GitLab From 5ecf2bb6b1f9659e79e99465c327bb97234bfdaf Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:12 +0200 Subject: [PATCH 0056/1480] staging: r8188eu: don't include rtw_led.h from rtw_cmd.h The rtw_cmd.h does not need any definitions from the led layer, there's no reason to include rtw_led.h. When I tried to remove this component struct led_priv { struct adapter *padapter; ... I saw compiler errors because of this chain of include files: drv_types.h -> rtw_cmd.h -> rtw_led.h rtw_led.h uses struct adapter before it sees the definiton near the end of drv_types.h. (It seems that a simple struct adapter * prevents this problem.) The best option for fixing this issue is to not include rtw_led.h in rtw_cmd.h. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_cmd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 0cb054909bc65..ee9218b1d7a94 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -6,7 +6,6 @@ #include "wlan_bssdef.h" #include "rtw_rf.h" -#include "rtw_led.h" #include "osdep_service.h" #include "ieee80211.h" /* */ -- GitLab From 1188cfa646ba2a7c295fe0cfac24529aec28ff2f Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:13 +0200 Subject: [PATCH 0057/1480] staging: r8188eu: remove padapter from struct led_priv The only struct led_priv that's used in the r8188eu driver in embedded in the driver's global struct adapter. We can use container_of to access the "outer" structure, there's no need to store a pointer to it. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 3 +-- drivers/staging/r8188eu/include/rtw_led.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 56f043d8ff38e..2dbd7b5ffdd03 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -59,7 +59,7 @@ static void blink_work(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct led_priv *pLed = container_of(dwork, struct led_priv, blink_work); - struct adapter *padapter = pLed->padapter; + struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { @@ -132,7 +132,6 @@ void rtl8188eu_InitSwLeds(struct adapter *padapter) { struct led_priv *pledpriv = &padapter->ledpriv; - pledpriv->padapter = padapter; ResetLedStatus(pledpriv); INIT_DELAYED_WORK(&pledpriv->blink_work, blink_work); } diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h index f57dcf6c8b24e..ea5f5edd90131 100644 --- a/drivers/staging/r8188eu/include/rtw_led.h +++ b/drivers/staging/r8188eu/include/rtw_led.h @@ -33,8 +33,6 @@ enum LED_STATE_871x { }; struct led_priv { - struct adapter *padapter; - bool bRegUseLed; enum LED_STATE_871x CurrLedState; /* Current LED state. */ -- GitLab From 126647d113dc6adf06cc4997ef8026f1972c34f7 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:14 +0200 Subject: [PATCH 0058/1480] staging: r8188eu: set two more state variables Set two more state variables in the blink worker when scan blinking and tx/rx blinking are finished. bLedBlinkInProgress is true during tx/rx blinking, bLedScanBlinkInProgress is true during scan blinking. If we doing neither of the two, we may safely set both variables to false. This change makes the scan and tx/rx cases almost identical, we are now ready to summarize the two cases. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index 2dbd7b5ffdd03..f8bd183fba1e5 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -90,6 +90,7 @@ static void blink_work(struct work_struct *work) pLed->CurrLedState = LED_BLINK_SLOWLY; schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); } + pLed->bLedBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; } else { schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL); @@ -106,6 +107,7 @@ static void blink_work(struct work_struct *work) schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); } pLed->bLedBlinkInProgress = false; + pLed->bLedScanBlinkInProgress = false; } else { schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL); } -- GitLab From e1445e7b003b2b2eace1145f58670200ddadd100 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 15 Oct 2022 17:11:15 +0200 Subject: [PATCH 0059/1480] staging: r8188eu: summarize tx/rx and scan blinking Summarize the code for tx/rx blinking and for scan blinking in blink_work. The only difference is the delay for scheduling the next worker. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221015151115.232095-11-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index f8bd183fba1e5..ce8de2eb7845f 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -81,21 +81,6 @@ static void blink_work(struct work_struct *work) schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); break; case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_BLINK_NORMAL; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); - } else { - pLed->CurrLedState = LED_BLINK_SLOWLY; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); - } - pLed->bLedBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; - } else { - schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL); - } - break; case LED_BLINK_TXRX: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) { @@ -109,7 +94,9 @@ static void blink_work(struct work_struct *work) pLed->bLedBlinkInProgress = false; pLed->bLedScanBlinkInProgress = false; } else { - schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL); + schedule_delayed_work(&pLed->blink_work, + pLed->CurrLedState == LED_BLINK_SCAN ? + LED_BLINK_SCAN_INTVL : LED_BLINK_FASTER_INTVL); } break; case LED_BLINK_WPS: -- GitLab From 31760f04cae2019b6eb4617af4409d8eaf0ac7ac Mon Sep 17 00:00:00 2001 From: Danijel Korent Date: Sat, 15 Oct 2022 18:50:23 +0200 Subject: [PATCH 0060/1480] staging: rtl8192e: Added spaces around operators in rtl_cam.c/rtl_eeprom.c Fixed "spaces preferred around operator" type of problems reported by checkpatch Signed-off-by: Danijel Korent Link: https://lore.kernel.org/r/20221015165023.487200-1-danijel.korent@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_cam.c | 23 +++++++++---------- .../staging/rtl8192e/rtl8192e/rtl_eeprom.c | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index 8c3ce6cc2541a..9d8d4837e6b20 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -17,7 +17,7 @@ void rtl92e_cam_reset(struct net_device *dev) { u32 ulcommand = 0; - ulcommand |= BIT31|BIT30; + ulcommand |= BIT31 | BIT30; rtl92e_writel(dev, RWCAM, ulcommand); } @@ -40,7 +40,6 @@ void rtl92e_enable_hw_security_config(struct net_device *dev) SECR_value |= SCR_TxUseDK; } - ieee->hwsec_active = 1; if ((ieee->pHTInfo->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { ieee->hwsec_active = 0; @@ -98,33 +97,33 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, } if (DefaultKey) - usConfig |= BIT15 | (KeyType<<2); + usConfig |= BIT15 | (KeyType << 2); else - usConfig |= BIT15 | (KeyType<<2) | KeyIndex; + usConfig |= BIT15 | (KeyType << 2) | KeyIndex; for (i = 0; i < CAM_CONTENT_COUNT; i++) { TargetCommand = i + CAM_CONTENT_COUNT * EntryNo; - TargetCommand |= BIT31|BIT16; + TargetCommand |= BIT31 | BIT16; if (i == 0) { - TargetContent = (u32)(*(MacAddr+0)) << 16 | - (u32)(*(MacAddr+1)) << 24 | + TargetContent = (u32)(*(MacAddr + 0)) << 16 | + (u32)(*(MacAddr + 1)) << 24 | (u32)usConfig; rtl92e_writel(dev, WCAMI, TargetContent); rtl92e_writel(dev, RWCAM, TargetCommand); } else if (i == 1) { - TargetContent = (u32)(*(MacAddr+2)) | - (u32)(*(MacAddr+3)) << 8 | - (u32)(*(MacAddr+4)) << 16 | - (u32)(*(MacAddr+5)) << 24; + TargetContent = (u32)(*(MacAddr + 2)) | + (u32)(*(MacAddr + 3)) << 8 | + (u32)(*(MacAddr + 4)) << 16 | + (u32)(*(MacAddr + 5)) << 24; rtl92e_writel(dev, WCAMI, TargetContent); rtl92e_writel(dev, RWCAM, TargetCommand); } else { if (KeyContent != NULL) { rtl92e_writel(dev, WCAMI, - (u32)(*(KeyContent+i-2))); + (u32)(*(KeyContent + i - 2))); rtl92e_writel(dev, RWCAM, TargetCommand); udelay(100); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c index 59532ed2156d3..db57c655c6953 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c @@ -79,6 +79,6 @@ u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr) ret = _rtl92e_eeprom_xfer(dev, (addr & 0x3F) | (0x6 << 6), 9); rtl92e_writeb(dev, EPROM_CMD, - (EPROM_CMD_NORMAL< Date: Thu, 20 Oct 2022 14:16:09 +0100 Subject: [PATCH 0061/1480] staging: octeon: remove redundant variable total_freed The variable total_freed is accumulating skb_to_free however it is not being used after this. The use of total_freed is redundant and hence the variable can be removed. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221020131609.1546667-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-tx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index a36e36701c743..bbf33b88bb7c2 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -73,7 +73,6 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) { int skb_to_free; int qos, queues_per_port; - int total_freed = 0; int total_remaining = 0; unsigned long flags; struct octeon_ethernet *priv = netdev_priv(dev); @@ -87,7 +86,6 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) MAX_SKB_TO_FREE); skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau + qos * 4); - total_freed += skb_to_free; if (skb_to_free > 0) { struct sk_buff *to_free_list = NULL; -- GitLab From 33a0a1e3b3d17445832177981dc7a1c6a5b009f8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 Oct 2022 18:53:15 +0200 Subject: [PATCH 0062/1480] kobject: modify kobject_get_path() to take a const * kobject_get_path() does not modify the kobject passed to it, so make the pointer constant. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20221001165315.2690141-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 +- lib/kobject.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 57fb972fea05b..592f9785b058a 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -115,7 +115,7 @@ extern void kobject_put(struct kobject *kobj); extern const void *kobject_namespace(struct kobject *kobj); extern void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid); -extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); +extern char *kobject_get_path(const struct kobject *kobj, gfp_t flag); struct kobj_type { void (*release)(struct kobject *kobj); diff --git a/lib/kobject.c b/lib/kobject.c index a0b2dbfcfa233..0380ec889a6af 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -94,10 +94,10 @@ static int create_dir(struct kobject *kobj) return 0; } -static int get_kobj_path_length(struct kobject *kobj) +static int get_kobj_path_length(const struct kobject *kobj) { int length = 1; - struct kobject *parent = kobj; + const struct kobject *parent = kobj; /* walk up the ancestors until we hit the one pointing to the * root. @@ -112,9 +112,9 @@ static int get_kobj_path_length(struct kobject *kobj) return length; } -static void fill_kobj_path(struct kobject *kobj, char *path, int length) +static void fill_kobj_path(const struct kobject *kobj, char *path, int length) { - struct kobject *parent; + const struct kobject *parent; --length; for (parent = kobj; parent; parent = parent->parent) { @@ -136,7 +136,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) * * Return: The newly allocated memory, caller must free with kfree(). */ -char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) +char *kobject_get_path(const struct kobject *kobj, gfp_t gfp_mask) { char *path; int len; -- GitLab From 3d24903a6dd27ab817b4c6c24bee245ff06f7c8e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 21 Oct 2022 09:23:10 +0200 Subject: [PATCH 0063/1480] kobject: make get_ktype() take a const pointer get_ktype() does not modify the structure passed to it, so mark the parameter as being const to allow other const structures to be passed to it in the future. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20221021072310.3931690-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 592f9785b058a..fc40fc81aeb1d 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -198,7 +198,7 @@ static inline void kset_put(struct kset *k) kobject_put(&k->kobj); } -static inline const struct kobj_type *get_ktype(struct kobject *kobj) +static inline const struct kobj_type *get_ktype(const struct kobject *kobj) { return kobj->ktype; } -- GitLab From acd50e52a7f2e75b3109523d2f114fa46a4362c0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 21 Oct 2022 19:09:50 +0100 Subject: [PATCH 0064/1480] staging: rtl8712: Remove variable xcnt The variable xcnt being incremented but it is never referenced, it is redundant and can be removed. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221021180950.29139-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_xmit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 84a22eba7ebfd..4cb01f590673e 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -601,7 +601,7 @@ int r8712_xmitframe_complete(struct _adapter *padapter, #ifdef CONFIG_R8712_TX_AGGR struct xmit_frame *p2ndxmitframe = NULL; #else - int res = _SUCCESS, xcnt = 0; + int res = _SUCCESS; #endif phwxmits = pxmitpriv->hwxmits; @@ -673,7 +673,6 @@ int r8712_xmitframe_complete(struct _adapter *padapter, dump_xframe(padapter, pxmitframe); else r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); - xcnt++; #endif } else { /* pxmitframe == NULL && p2ndxmitframe == NULL */ -- GitLab From 02119c5d84e327483595687821f9c38c88d2d929 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 16 Oct 2022 12:07:40 +0100 Subject: [PATCH 0065/1480] staging: rtl8192u: Provide a TODO file for this driver Provide a TODO file that lists the tasks that should be carried out in order to move this driver off drivers/staging. It's missing from original addition of this driver. Signed-off-by: Peter Robinson Link: https://lore.kernel.org/r/20221016110743.1448067-1-pbrobinson@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/TODO | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 drivers/staging/rtl8192u/TODO diff --git a/drivers/staging/rtl8192u/TODO b/drivers/staging/rtl8192u/TODO new file mode 100644 index 0000000000000..ab9d5d145b3bc --- /dev/null +++ b/drivers/staging/rtl8192u/TODO @@ -0,0 +1,16 @@ +To-do list: + +* Correct the coding style according to Linux guidelines; please read the document + at https://www.kernel.org/doc/html/latest/process/coding-style.html. +* Remove unnecessary debugging/printing macros; for those that are still needed + use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). +* Remove dead code such as unusued functions, variables, fields, etc.. +* Use in-kernel API and remove unnecessary wrappers where possible. +* Fix bugs due to code that sleeps in atomic context. +* Remove the HAL layer and migrate its functionality into the relevant parts of + the driver. +* Switch to use LIB80211. +* Switch to use MAC80211. +* Switch to use CFG80211. +* Improve the error handling of various functions, particularly those that use + existing kernel APIs. -- GitLab From f124c1751844c4592110a292403f342c50a89344 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 16 Oct 2022 12:07:41 +0100 Subject: [PATCH 0066/1480] staging: rtl8192e: Update the TODO file for this driver The driver directory where it was proposed to move to has changed, while add it add some more pieces this driver to update. Signed-off-by: Peter Robinson Link: https://lore.kernel.org/r/20221016110743.1448067-2-pbrobinson@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/TODO | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/TODO b/drivers/staging/rtl8192e/TODO index d51f159d1adff..7221ae65d63eb 100644 --- a/drivers/staging/rtl8192e/TODO +++ b/drivers/staging/rtl8192e/TODO @@ -1,2 +1,18 @@ -* merge into drivers/net/wireless/rtllib/rtl8192e +To-do list: + +* merge into drivers/net/wireless/realtek/rtlwifi/rtl8192* * clean up function naming +* Correct the coding style according to Linux guidelines; please read the document + at https://www.kernel.org/doc/html/latest/process/coding-style.html. +* Remove unnecessary debugging/printing macros; for those that are still needed + use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). +* Remove dead code such as unusued functions, variables, fields, etc.. +* Use in-kernel API and remove unnecessary wrappers where possible. +* Fix bugs due to code that sleeps in atomic context. +* Remove the HAL layer and migrate its functionality into the relevant parts of + the driver. +* Switch to use LIB80211. +* Switch to use MAC80211. +* Switch to use CFG80211. +* Improve the error handling of various functions, particularly those that use + existing kernel APIs. -- GitLab From ce51c0c7fae3390f070e6b515e3a57f6bfdfd18e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 16 Oct 2022 12:07:42 +0100 Subject: [PATCH 0067/1480] staging: ks7010: Update the TODO file for this driver Add move to mac80211 from wext to the todo for this driver. Signed-off-by: Peter Robinson Link: https://lore.kernel.org/r/20221016110743.1448067-3-pbrobinson@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ks7010/TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/ks7010/TODO b/drivers/staging/ks7010/TODO index ab6f39175d992..80c97543b9772 100644 --- a/drivers/staging/ks7010/TODO +++ b/drivers/staging/ks7010/TODO @@ -27,6 +27,9 @@ Now the TODOs: - fix the 'card removal' event when card is inserted when booting - check what other upstream wireless mechanisms can be used instead of the custom ones here +- Switch to use LIB80211. +- Switch to use MAC80211. +- Switch to use CFG80211. Please send any patches to: Greg Kroah-Hartman -- GitLab From 1f3e0b41919208be71f869a753609d6c11e12e85 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 16 Oct 2022 12:07:43 +0100 Subject: [PATCH 0068/1480] staging: wlan-ng: Provide a TODO file for this driver Provide a TODO file that lists the tasks that should be carried out in order to move this driver off drivers/staging. It's missing from original addition of this driver. Signed-off-by: Peter Robinson Link: https://lore.kernel.org/r/20221016110743.1448067-4-pbrobinson@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/TODO | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 drivers/staging/wlan-ng/TODO diff --git a/drivers/staging/wlan-ng/TODO b/drivers/staging/wlan-ng/TODO new file mode 100644 index 0000000000000..ab9d5d145b3bc --- /dev/null +++ b/drivers/staging/wlan-ng/TODO @@ -0,0 +1,16 @@ +To-do list: + +* Correct the coding style according to Linux guidelines; please read the document + at https://www.kernel.org/doc/html/latest/process/coding-style.html. +* Remove unnecessary debugging/printing macros; for those that are still needed + use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). +* Remove dead code such as unusued functions, variables, fields, etc.. +* Use in-kernel API and remove unnecessary wrappers where possible. +* Fix bugs due to code that sleeps in atomic context. +* Remove the HAL layer and migrate its functionality into the relevant parts of + the driver. +* Switch to use LIB80211. +* Switch to use MAC80211. +* Switch to use CFG80211. +* Improve the error handling of various functions, particularly those that use + existing kernel APIs. -- GitLab From ea679d8e032b0affc65c9d56b7bad3ef144366e1 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 20 Oct 2022 22:50:00 +0530 Subject: [PATCH 0069/1480] staging: most: dim2: correct misleading struct type name Correct the misleading struct type name dim_ch_state_t to dim_ch_state since this not a typedef but a normal structure declaration. Suggested-by: Julia Lawall Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y1GDQO+06fD24Pf/@debian-BULLSEYE-live-builder-AMD64 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/dim2/dim2.c | 4 ++-- drivers/staging/most/dim2/hal.c | 4 ++-- drivers/staging/most/dim2/hal.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 97dff82b7a5fb..7a5f80e637a0b 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -161,7 +161,7 @@ static int try_start_dim_transfer(struct hdm_channel *hdm_ch) struct list_head *head = &hdm_ch->pending_list; struct mbo *mbo; unsigned long flags; - struct dim_ch_state_t st; + struct dim_ch_state st; BUG_ON(!hdm_ch); BUG_ON(!hdm_ch->is_initialized); @@ -259,7 +259,7 @@ static void retrieve_netinfo(struct dim2_hdm *dev, struct mbo *mbo) static void service_done_flag(struct dim2_hdm *dev, int ch_idx) { struct hdm_channel *hdm_ch = dev->hch + ch_idx; - struct dim_ch_state_t st; + struct dim_ch_state st; struct list_head *head; struct mbo *mbo; int done_buffers; diff --git a/drivers/staging/most/dim2/hal.c b/drivers/staging/most/dim2/hal.c index 65282c2768628..a5d40b5b138ab 100644 --- a/drivers/staging/most/dim2/hal.c +++ b/drivers/staging/most/dim2/hal.c @@ -943,8 +943,8 @@ u8 dim_service_channel(struct dim_channel *ch) return channel_service(ch); } -struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, - struct dim_ch_state_t *state_ptr) +struct dim_ch_state *dim_get_channel_state(struct dim_channel *ch, + struct dim_ch_state *state_ptr) { if (!ch || !state_ptr) return NULL; diff --git a/drivers/staging/most/dim2/hal.h b/drivers/staging/most/dim2/hal.h index 20531449acab1..ef10a8741c10b 100644 --- a/drivers/staging/most/dim2/hal.h +++ b/drivers/staging/most/dim2/hal.h @@ -27,7 +27,7 @@ enum mlb_clk_speed { CLK_8192FS = 7, }; -struct dim_ch_state_t { +struct dim_ch_state { bool ready; /* Shows readiness to enqueue next buffer */ u16 done_buffers; /* Number of completed buffers */ }; @@ -87,8 +87,8 @@ void dim_service_ahb_int_irq(struct dim_channel *const *channels); u8 dim_service_channel(struct dim_channel *ch); -struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch, - struct dim_ch_state_t *state_ptr); +struct dim_ch_state *dim_get_channel_state(struct dim_channel *ch, + struct dim_ch_state *state_ptr); u16 dim_dbr_space(struct dim_channel *ch); -- GitLab From 6cc7b783f8295677a19e88c12e47021c06c3b6ef Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 02:56:47 +0530 Subject: [PATCH 0070/1480] staging: r8188eu: use Linux kernel variable naming convention Follow the Linux Kernel coding style variable naming convention instead of using camelCase style. Issue reported by checkpatch script for these variables: tagLen, tagType, networkAddr, ipAddr, macAddr Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/a107c527e9032c22a62e93ff12d5fae625e70212.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 112 +++++++++++----------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index 4c5f30792a46c..e509b8454e25b 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -50,17 +50,17 @@ static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) { unsigned char *cur_ptr, *start_ptr; - unsigned short tagLen, tagType; + unsigned short tag_len, tag_type; start_ptr = (unsigned char *)ph->tag; cur_ptr = (unsigned char *)ph->tag; while ((cur_ptr - start_ptr) < ntohs(ph->length)) { /* prevent un-alignment access */ - tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); - tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); - if (tagType == type) + tag_type = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); + tag_len = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); + if (tag_type == type) return cur_ptr; - cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; + cur_ptr = cur_ptr + TAG_HDR_LEN + tag_len; } return NULL; } @@ -111,32 +111,32 @@ static int __nat25_has_expired(struct nat25_network_db_entry *fdb) return 0; } -static void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, - unsigned int *ipAddr) +static void __nat25_generate_ipv4_network_addr(unsigned char *addr, + unsigned int *ip_addr) { - memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + memset(addr, 0, MAX_NETWORK_ADDR_LEN); - networkAddr[0] = NAT25_IPV4; - memcpy(networkAddr + 7, (unsigned char *)ipAddr, 4); + addr[0] = NAT25_IPV4; + memcpy(addr + 7, (unsigned char *)ip_addr, 4); } -static void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, +static void __nat25_generate_pppoe_network_addr(unsigned char *addr, unsigned char *ac_mac, __be16 *sid) { - memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + memset(addr, 0, MAX_NETWORK_ADDR_LEN); - networkAddr[0] = NAT25_PPPOE; - memcpy(networkAddr + 1, (unsigned char *)sid, 2); - memcpy(networkAddr + 3, (unsigned char *)ac_mac, 6); + addr[0] = NAT25_PPPOE; + memcpy(addr + 1, (unsigned char *)sid, 2); + memcpy(addr + 3, (unsigned char *)ac_mac, 6); } -static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, - unsigned int *ipAddr) +static void __nat25_generate_ipv6_network_addr(unsigned char *addr, + unsigned int *ip_addr) { - memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + memset(addr, 0, MAX_NETWORK_ADDR_LEN); - networkAddr[0] = NAT25_IPV6; - memcpy(networkAddr + 1, (unsigned char *)ipAddr, 16); + addr[0] = NAT25_IPV6; + memcpy(addr + 1, (unsigned char *)ip_addr, 16); } static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) @@ -200,40 +200,40 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char return 0; } -static int __nat25_network_hash(unsigned char *networkAddr) +static int __nat25_network_hash(unsigned char *addr) { - if (networkAddr[0] == NAT25_IPV4) { + if (addr[0] == NAT25_IPV4) { unsigned long x; - x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + x = addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; return x & (NAT25_HASH_SIZE - 1); - } else if (networkAddr[0] == NAT25_IPX) { + } else if (addr[0] == NAT25_IPX) { unsigned long x; - x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ - networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ + addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; return x & (NAT25_HASH_SIZE - 1); - } else if (networkAddr[0] == NAT25_APPLE) { + } else if (addr[0] == NAT25_APPLE) { unsigned long x; - x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; + x = addr[1] ^ addr[2] ^ addr[3]; return x & (NAT25_HASH_SIZE - 1); - } else if (networkAddr[0] == NAT25_PPPOE) { + } else if (addr[0] == NAT25_PPPOE) { unsigned long x; - x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; + x = addr[0] ^ addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ addr[6] ^ addr[7] ^ addr[8]; return x & (NAT25_HASH_SIZE - 1); - } else if (networkAddr[0] == NAT25_IPV6) { + } else if (addr[0] == NAT25_IPV6) { unsigned long x; - x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ - networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ - networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ - networkAddr[16]; + x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ + addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10] ^ + addr[11] ^ addr[12] ^ addr[13] ^ addr[14] ^ addr[15] ^ + addr[16]; return x & (NAT25_HASH_SIZE - 1); } else { @@ -241,7 +241,7 @@ static int __nat25_network_hash(unsigned char *networkAddr) int i; for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++) - x ^= networkAddr[i]; + x ^= addr[i]; return x & (NAT25_HASH_SIZE - 1); } @@ -269,17 +269,17 @@ static void __network_hash_unlink(struct nat25_network_db_entry *ent) } static void __nat25_db_network_insert(struct adapter *priv, - unsigned char *macAddr, unsigned char *networkAddr) + unsigned char *mac_addr, unsigned char *addr) { struct nat25_network_db_entry *db; int hash; spin_lock_bh(&priv->br_ext_lock); - hash = __nat25_network_hash(networkAddr); + hash = __nat25_network_hash(addr); db = priv->nethash[hash]; while (db) { - if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { - memcpy(db->macAddr, macAddr, ETH_ALEN); + if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) { + memcpy(db->macAddr, mac_addr, ETH_ALEN); db->ageing_timer = jiffies; spin_unlock_bh(&priv->br_ext_lock); return; @@ -291,8 +291,8 @@ static void __nat25_db_network_insert(struct adapter *priv, spin_unlock_bh(&priv->br_ext_lock); return; } - memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); - memcpy(db->macAddr, macAddr, ETH_ALEN); + memcpy(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN); + memcpy(db->macAddr, mac_addr, ETH_ALEN); atomic_set(&db->use_count, 1); db->ageing_timer = jiffies; @@ -366,7 +366,7 @@ void nat25_db_expire(struct adapter *priv) int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) { unsigned short protocol; - unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + unsigned char addr[MAX_NETWORK_ADDR_LEN]; unsigned int tmp; if (!skb) @@ -395,9 +395,9 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) if (iph->saddr == 0) return 0; tmp = be32_to_cpu(iph->saddr); - __nat25_generate_ipv4_network_addr(networkAddr, &tmp); + __nat25_generate_ipv4_network_addr(addr, &tmp); /* record source IP address and , source mac address into db */ - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); return 0; default: return -1; @@ -421,8 +421,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); arp_ptr += arp->ar_hln; sender = (unsigned int *)arp_ptr; - __nat25_generate_ipv4_network_addr(networkAddr, sender); - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + __nat25_generate_ipv4_network_addr(addr, sender); + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); return 0; default: return -1; @@ -495,9 +495,9 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) return -1; } } else { /* session phase */ - __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &ph->sid); + __nat25_generate_pppoe_network_addr(addr, skb->data, &ph->sid); - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); if (!priv->ethBrExtInfo.addPPPoETag && priv->pppoe_connection_in_progress && @@ -548,8 +548,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) return -1; case NAT25_INSERT: if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { - __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, networkAddr); + __nat25_generate_ipv6_network_addr(addr, (unsigned int *)&iph->saddr); + __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); if (iph->nexthdr == IPPROTO_ICMPV6 && skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { @@ -639,17 +639,17 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) } } -void *scdb_findEntry(struct adapter *priv, unsigned char *ipAddr) +void *scdb_findEntry(struct adapter *priv, unsigned char *ip_addr) { - unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + unsigned char addr[MAX_NETWORK_ADDR_LEN]; struct nat25_network_db_entry *db; int hash; - __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); - hash = __nat25_network_hash(networkAddr); + __nat25_generate_ipv4_network_addr(addr, (unsigned int *)ip_addr); + hash = __nat25_network_hash(addr); db = priv->nethash[hash]; while (db) { - if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { + if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) { return (void *)db; } -- GitLab From 9d76dae6c86e7945b51054cd477c5b8f0bcb3a87 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 02:57:16 +0530 Subject: [PATCH 0071/1480] staging: r8188eu: reformat long computation lines Reformat long running computation instructions to improve code readability. Address checkpatch script complaints like: CHECK: line length of 171 exceeds 100 columns Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/e07506ef1dc4ac1d3f8b076a8182628bd0e5cec0.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index e509b8454e25b..d4059f0fc3629 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -212,7 +212,7 @@ static int __nat25_network_hash(unsigned char *addr) unsigned long x; x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ - addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; + addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; return x & (NAT25_HASH_SIZE - 1); } else if (addr[0] == NAT25_APPLE) { @@ -224,16 +224,16 @@ static int __nat25_network_hash(unsigned char *addr) } else if (addr[0] == NAT25_PPPOE) { unsigned long x; - x = addr[0] ^ addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ addr[6] ^ addr[7] ^ addr[8]; + x = addr[0] ^ addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ + addr[5] ^ addr[6] ^ addr[7] ^ addr[8]; return x & (NAT25_HASH_SIZE - 1); } else if (addr[0] == NAT25_IPV6) { unsigned long x; - x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ - addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10] ^ - addr[11] ^ addr[12] ^ addr[13] ^ addr[14] ^ addr[15] ^ - addr[16]; + x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ addr[6] ^ + addr[7] ^ addr[8] ^ addr[9] ^ addr[10] ^ addr[11] ^ addr[12] ^ + addr[13] ^ addr[14] ^ addr[15] ^ addr[16]; return x & (NAT25_HASH_SIZE - 1); } else { -- GitLab From 3c480b32431272e0a4a78ee1f20bba96deaddd72 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 02:57:47 +0530 Subject: [PATCH 0072/1480] staging: r8188eu: remove {} for single statement blocks As per the Linux kernel coding-style guidelines, there is no need to use {} for single statement blocks. Issue flagged by checkpatch script. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/a50460e1507621b29a7901cc4ff9501b172417db.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index d4059f0fc3629..b418cbc307b37 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -649,9 +649,8 @@ void *scdb_findEntry(struct adapter *priv, unsigned char *ip_addr) hash = __nat25_network_hash(addr); db = priv->nethash[hash]; while (db) { - if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) { + if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) return (void *)db; - } db = db->next_hash; } -- GitLab From 227041c5d88aace2a1c95d6741438015ac1d9560 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 02:58:39 +0530 Subject: [PATCH 0073/1480] staging: r8188eu: use htons macro instead of __constant_htons Macro "htons" is more efficient and clearer. It should be used for constants instead of the __constant_htons macro. Resolves following checkpatch script complaint: WARNING: __constant_htons should be htons Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/b46adfbdce0362ed0dbe0fc957ef2f47a93c24bb.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 6 +++--- drivers/staging/r8188eu/core/rtw_xmit.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index b418cbc307b37..a23f7df373ede 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -606,14 +606,14 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) if (!priv->ethBrExtInfo.dhcp_bcst_disable) { __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN)); - if (protocol == __constant_htons(ETH_P_IP)) { /* IP */ + if (protocol == htons(ETH_P_IP)) { /* IP */ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); if (iph->protocol == IPPROTO_UDP) { /* UDP */ struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2)); - if ((udph->source == __constant_htons(CLIENT_PORT)) && - (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */ + if ((udph->source == htons(CLIENT_PORT)) && + (udph->dest == htons(SERVER_PORT))) { /* DHCP request */ struct dhcpMessage *dhcph = (struct dhcpMessage *)((size_t)udph + sizeof(struct udphdr)); u32 cookie = be32_to_cpu((__be32)dhcph->cookie); diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c index 873d2c5c36344..4f82204283282 100644 --- a/drivers/staging/r8188eu/core/rtw_xmit.c +++ b/drivers/staging/r8188eu/core/rtw_xmit.c @@ -1622,14 +1622,14 @@ static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) spin_lock_bh(&padapter->br_ext_lock); if (!(skb->data[0] & 1) && br_port && memcmp(skb->data + ETH_ALEN, padapter->br_mac, ETH_ALEN) && - *((__be16 *)(skb->data + ETH_ALEN * 2)) != __constant_htons(ETH_P_8021Q) && - *((__be16 *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP) && + *((__be16 *)(skb->data + ETH_ALEN * 2)) != htons(ETH_P_8021Q) && + *((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP) && !memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN) && padapter->scdb_entry) { memcpy(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN); padapter->scdb_entry->ageing_timer = jiffies; spin_unlock_bh(&padapter->br_ext_lock); } else { - if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_8021Q)) { + if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_8021Q)) { is_vlan_tag = 1; vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)); for (i = 0; i < 6; i++) @@ -1637,10 +1637,10 @@ static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) skb_pull(skb, 4); } if (!memcmp(skb->data + ETH_ALEN, padapter->br_mac, ETH_ALEN) && - (*((__be16 *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP))) + (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP))) memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); - if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == __constant_htons(ETH_P_IP)) { + if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP)) { if (memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN)) { padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, skb->data + WLAN_ETHHDR_LEN + 12); @@ -1669,7 +1669,7 @@ static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) skb_push(skb, 4); for (i = 0; i < 6; i++) *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); - *((__be16 *)(skb->data + ETH_ALEN * 2)) = __constant_htons(ETH_P_8021Q); + *((__be16 *)(skb->data + ETH_ALEN * 2)) = htons(ETH_P_8021Q); *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr; } @@ -1708,7 +1708,7 @@ static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) skb_push(skb, 4); for (i = 0; i < 6; i++) *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); - *((__be16 *)(skb->data + ETH_ALEN * 2)) = __constant_htons(ETH_P_8021Q); + *((__be16 *)(skb->data + ETH_ALEN * 2)) = htons(ETH_P_8021Q); *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr; } } -- GitLab From 0f2635b3ff1057d50bfe4a011c5706117e97e114 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 02:59:37 +0530 Subject: [PATCH 0074/1480] staging: r8188eu: correct misspelled words in comments Fix spelling mistakes in code comments across the driver. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/00be5f2a97b0c899279bd8f9cd27634186b77b9d.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_ioctl_set.c | 2 +- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 36 +++++++++---------- drivers/staging/r8188eu/core/rtw_recv.c | 8 ++--- drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 2 +- drivers/staging/r8188eu/hal/odm_RTL8188E.c | 2 +- .../staging/r8188eu/hal/rtl8188e_hal_init.c | 2 +- drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 16 ++++----- .../staging/r8188eu/include/Hal8188EPhyReg.h | 4 +-- .../staging/r8188eu/include/rtl8188e_hal.h | 2 +- .../staging/r8188eu/include/rtl8188e_spec.h | 6 ++-- drivers/staging/r8188eu/include/rtw_cmd.h | 4 +-- drivers/staging/r8188eu/include/rtw_recv.h | 4 +-- drivers/staging/r8188eu/include/rtw_xmit.h | 2 +- drivers/staging/r8188eu/include/wifi.h | 12 +++---- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 6 ++-- 15 files changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c index 55e6b0f41dc32..7864318266598 100644 --- a/drivers/staging/r8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/r8188eu/core/rtw_ioctl_set.c @@ -287,7 +287,7 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { if (check_fwstate(pmlmepriv, _FW_LINKED)) - rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */ + rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not */ } *pold_state = networktype; diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index fda446b6779c3..d146b94307b80 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -137,7 +137,7 @@ static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { {0x03}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */ }; -static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the conbination for max channel numbers */ +static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the combination for max channel numbers */ /* * Search the @param channel_num in given @param channel_set @@ -1751,7 +1751,7 @@ void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr) p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ /* Commented by Albert 20110306 */ - /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */ + /* According to the P2P Specification, the group negotiation request frame should contain 9 P2P attributes */ /* 1. P2P Capability */ /* 2. Group Owner Intent */ /* 3. Configuration Timeout */ @@ -2106,7 +2106,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ /* Commented by Albert 20100908 */ - /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */ + /* According to the P2P Specification, the group negotiation response frame should contain 9 P2P attributes */ /* 1. Status */ /* 2. P2P Capability */ /* 3. Group Owner Intent */ @@ -2402,7 +2402,7 @@ static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result) p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ /* Commented by Albert 20110306 */ - /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */ + /* According to the P2P Specification, the group negotiation request frame should contain 5 P2P attributes */ /* 1. Status */ /* 2. P2P Capability */ /* 3. Operating Channel */ @@ -4010,7 +4010,7 @@ struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) /**************************************************************************** -Following are some TX fuctions for WiFi MLME +Following are some TX functions for WiFi MLME *****************************************************************************/ @@ -4612,7 +4612,7 @@ exit: return ret; } -/* if psta == NULL, indiate we are station(client) now... */ +/* if psta == NULL, indicate we are station (client) now... */ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status) { struct xmit_frame *pmgntframe; @@ -5011,7 +5011,7 @@ void issue_assocreq(struct adapter *padapter) if (!padapter->registrypriv.wifi_spec) { /* Commented by Kurt 20110629 */ /* In some older APs, WPS handshake */ - /* would be fail if we append vender extensions informations to AP */ + /* would be fail if we append vendor extension information to AP */ if (!memcmp(pIE->data, WPS_OUI, 4)) pIE->Length = 14; } @@ -5166,7 +5166,7 @@ exit: kfree(pmlmepriv->assoc_req); } -/* when wait_ack is ture, this function shoule be called at process context */ +/* when wait_ack is true, this function should be called at process context */ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) { int ret = _FAIL; @@ -5235,7 +5235,7 @@ exit: return ret; } -/* when wait_ms > 0 , this function shoule be called at process context */ +/* when wait_ms > 0, this function should be called at process context */ /* da == NULL for station mode */ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) { @@ -5244,7 +5244,7 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - /* da == NULL, assum it's null data for sta to ap*/ + /* da == NULL, assume it's null data for sta to ap*/ if (!da) da = get_my_bssid(&pmlmeinfo->network); @@ -5268,7 +5268,7 @@ exit: return ret; } -/* when wait_ack is ture, this function shoule be called at process context */ +/* when wait_ack is true, this function should be called at process context */ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int wait_ack) { int ret = _FAIL; @@ -5341,7 +5341,7 @@ exit: return ret; } -/* when wait_ms > 0 , this function shoule be called at process context */ +/* when wait_ms > 0 , this function should be called at process context */ /* da == NULL for station mode */ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) { @@ -5350,7 +5350,7 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - /* da == NULL, assum it's null data for sta to ap*/ + /* da == NULL, assume it's null data for sta to ap*/ if (!da) da = get_my_bssid(&pmlmeinfo->network); @@ -5882,7 +5882,7 @@ static void rtw_set_opmode(struct adapter *adapter, u8 mode) /**************************************************************************** -Following are some utitity fuctions for WiFi MLME +Following are some utility functions for WiFi MLME *****************************************************************************/ @@ -6055,7 +6055,7 @@ void site_survey(struct adapter *padapter) } else { /* 20100721:Interrupt scan operation here. */ /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */ - /* It compares the scan result and select beter one to do connection. */ + /* It compares the scan result and selects a better one to do connection. */ if (AntDivBeforeLink8188E(padapter)) { pmlmeext->sitesurvey_res.bss_cnt = 0; pmlmeext->sitesurvey_res.channel_idx = -1; @@ -6325,7 +6325,7 @@ void start_create_ibss(struct adapter *padapter) /* update wireless mode */ update_wireless_mode(padapter); - /* udpate capability */ + /* update capability */ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); update_capinfo(padapter, caps); if (caps & cap_IBSS) {/* adhoc master */ @@ -6375,7 +6375,7 @@ void start_clnt_join(struct adapter *padapter) /* update wireless mode */ update_wireless_mode(padapter); - /* udpate capability */ + /* update capability */ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); update_capinfo(padapter, caps); if (caps & cap_ESS) { @@ -6969,7 +6969,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) /* BCN interval */ rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); - /* udpate capability */ + /* update capability */ update_capinfo(padapter, pmlmeinfo->capability); /* WMM, Update EDCA param */ diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index bb5c3b3888e08..4b68a543f68b7 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -972,7 +972,7 @@ static void validate_recv_ctrl_frame(struct adapter *padapter, if (psta->sleepq_len == 0) { pstapriv->tim_bitmap &= ~BIT(psta->aid); - /* upate BCN for TIM IE */ + /* update BCN for TIM IE */ /* update_BCNTIM(padapter); */ update_beacon(padapter, _TIM_IE_, NULL, false); } @@ -986,7 +986,7 @@ static void validate_recv_ctrl_frame(struct adapter *padapter, pstapriv->tim_bitmap &= ~BIT(psta->aid); - /* upate BCN for TIM IE */ + /* update BCN for TIM IE */ /* update_BCNTIM(padapter); */ update_beacon(padapter, _TIM_IE_, NULL, false); } @@ -1984,13 +1984,13 @@ static void rtw_signal_stat_timer_hdl(struct timer_list *t) } else { if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */ avg_signal_strength = recvpriv->signal_strength_data.avg_val; - /* after avg_vals are accquired, we can re-stat the signal values */ + /* after avg_vals are acquired, we can re-stat the signal values */ recvpriv->signal_strength_data.update_req = 1; } if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */ avg_signal_qual = recvpriv->signal_qual_data.avg_val; - /* after avg_vals are accquired, we can re-stat the signal values */ + /* after avg_vals are acquired, we can re-stat the signal values */ recvpriv->signal_qual_data.update_req = 1; } diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c index 525deab10820b..60cdfcf80daad 100644 --- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c @@ -69,7 +69,7 @@ void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/* 0 = OFDM, /*----------------------------------------------------------------------------- * Function: odm_TxPwrTrackSetPwr88E() * - * Overview: 88E change all channel tx power accordign to flag. + * Overview: 88E change all channel tx power according to flag. * OFDM & CCK are all different. * * Input: NONE diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c index c8a3c521bd607..dd9c8291f025d 100644 --- a/drivers/staging/r8188eu/hal/odm_RTL8188E.c +++ b/drivers/staging/r8188eu/hal/odm_RTL8188E.c @@ -194,7 +194,7 @@ static void odm_HWAntDiv(struct odm_dm_struct *dm_odm) for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { pEntry = dm_odm->pODM_StaInfo[i]; if (IS_STA_VALID(pEntry)) { - /* 2 Caculate RSSI per Antenna */ + /* 2 Calculate RSSI per Antenna */ Main_RSSI = (dm_fat_tbl->MainAnt_Cnt[i] != 0) ? (dm_fat_tbl->MainAnt_Sum[i] / dm_fat_tbl->MainAnt_Cnt[i]) : 0; Aux_RSSI = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ? (dm_fat_tbl->AuxAnt_Sum[i] / dm_fat_tbl->AuxAnt_Cnt[i]) : 0; TargetAnt = (Main_RSSI >= Aux_RSSI) ? MAIN_ANT : AUX_ANT; diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c index 158260547f2b2..cc29963f4b491 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c @@ -355,7 +355,7 @@ void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState) if (PwrState) { rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); - /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */ + /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), default valid */ res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16); if (res) return; diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c index 532c63bce0bf0..b7f3c7a670fb4 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c @@ -23,7 +23,7 @@ static u32 phy_calculate_bit_shift(u32 bitmask) /** * Function: PHY_QueryBBReg * -* OverView: Read "sepcific bits" from BB register +* Overview: Read "sepcific bits" from BB register * * Input: * struct adapter *Adapter, @@ -56,7 +56,7 @@ rtl8188e_PHY_QueryBBReg( /** * Function: PHY_SetBBReg * -* OverView: Write "Specific bits" to BB register (page 8~) +* Overview: Write "Specific bits" to BB register (page 8~) * * Input: * struct adapter *Adapter, @@ -94,7 +94,7 @@ void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u3 /** * Function: phy_RFSerialRead * -* OverView: Read regster from RF chips +* Overview: Read register from RF chips * * Input: * struct adapter *Adapter, @@ -160,7 +160,7 @@ phy_RFSerialRead( /** * Function: phy_RFSerialWrite * -* OverView: Write data to RF register (page 8~) +* Overview: Write data to RF register (page 8~) * * Input: * struct adapter *Adapter, @@ -235,7 +235,7 @@ phy_RFSerialWrite( /** * Function: PHY_QueryRFReg * -* OverView: Query "Specific bits" to RF register (page 8~) +* Overview: Query "Specific bits" to RF register (page 8~) * * Input: * struct adapter *Adapter, @@ -261,7 +261,7 @@ u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask) /** * Function: PHY_SetRFReg * -* OverView: Write "Specific bits" to RF register (page 8~) +* Overview: Write "Specific bits" to RF register (page 8~) * * Input: * struct adapter *Adapter, @@ -335,7 +335,7 @@ s32 PHY_MACConfig8188E(struct adapter *Adapter) /** * Function: phy_InitBBRFRegisterDefinition * -* OverView: Initialize Register definition offset for Radio Path A/B/C/D +* Overview: Initialize Register definition offset for Radio Path A/B/C/D * * Input: * struct adapter *Adapter, @@ -363,7 +363,7 @@ phy_InitBBRFRegisterDefinition( /* RF Interface (Output and) Enable */ pHalData->PHYRegDef.rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ - /* Addr of LSSI. Wirte RF register by driver */ + /* Addr of LSSI. Write RF register by driver */ pHalData->PHYRegDef.rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */ /* RF parameter */ diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyReg.h b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h index 8b8c75a1f1490..da2329be4474a 100644 --- a/drivers/staging/r8188eu/include/Hal8188EPhyReg.h +++ b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h @@ -92,7 +92,7 @@ #define rFPGA0_AdDaClockEn 0x888 #define rFPGA0_AnalogParameter4 0x88c -#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ +#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Transceiver LSSI Readback */ #define rFPGA0_XB_LSSIReadBack 0x8a4 #define rFPGA0_XC_LSSIReadBack 0x8a8 #define rFPGA0_XD_LSSIReadBack 0x8ac @@ -167,7 +167,7 @@ /* RxIQ DC offset, Rx digital filter, DC notch filter */ #define rOFDM0_XARxAFE 0xc10 -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ +#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ #define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c #define rOFDM0_XCRxAFE 0xc20 diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h index a1e88e6d5c0c7..69faaaa7d3730 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h @@ -87,7 +87,7 @@ struct txpowerinfo24g { /* 9bytes + 1byt + 5bytes and pre 1byte. */ /* For worst case: */ /* | 2byte|----8bytes----|1byte|--7bytes--| 92D */ -/* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. */ +/* PG data exclude header, dummy 7 bytes from CP test and reserved 1byte. */ #define EFUSE_OOB_PROTECT_BYTES_88E 18 #define EFUSE_PROTECT_BYTES_BANK 16 diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h index e34619140e33c..e34ecdc096886 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_spec.h +++ b/drivers/staging/r8188eu/include/rtl8188e_spec.h @@ -4,7 +4,7 @@ #ifndef __RTL8188E_SPEC_H__ #define __RTL8188E_SPEC_H__ -/* 8192C Regsiter offset definition */ +/* 8192C Register offset definition */ #define HAL_PS_TIMER_INT_DELAY 50 /* 50 microseconds */ #define HAL_92C_NAV_UPPER_UNIT 128 /* micro-second */ @@ -674,7 +674,7 @@ Current IOREG MAP #define REG_USB_HRPWM 0xFE58 #define REG_USB_HCPWM 0xFE57 -/* 8192C Regsiter Bit and Content definition */ +/* 8192C Register Bit and Content definition */ /* 0x0000h ~ 0x00FFh System Configuration */ /* 2 SYS_ISO_CTRL */ @@ -1135,7 +1135,7 @@ Current IOREG MAP #define EEPROM_Default_CrystalCap_88E 0x20 #define EEPROM_Default_ThermalMeter_88E 0x18 -/* New EFUSE deafult value */ +/* New EFUSE default value */ #define EEPROM_DEFAULT_24G_INDEX 0x2D #define EEPROM_DEFAULT_24G_HT20_DIFF 0X02 #define EEPROM_DEFAULT_24G_OFDM_DIFF 0X04 diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index ee9218b1d7a94..2896a732780b1 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -450,7 +450,7 @@ struct Tx_Beacon_param mac[0] == 0 ==> CMD mode, return H2C_SUCCESS. - The following condition must be ture under CMD mode + The following condition must be true under CMD mode mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; s2 == (b1 << 8 | b0); @@ -503,7 +503,7 @@ struct drvextra_cmd_parm { unsigned char *pbuf; }; -/*------------------- Below are used for RF/BB tunning ---------------------*/ +/*------------------- Below are used for RF/BB tuning ---------------------*/ struct setantenna_parm { u8 tx_antset; diff --git a/drivers/staging/r8188eu/include/rtw_recv.h b/drivers/staging/r8188eu/include/rtw_recv.h index 7768b0c5988c9..12026431a3d29 100644 --- a/drivers/staging/r8188eu/include/rtw_recv.h +++ b/drivers/staging/r8188eu/include/rtw_recv.h @@ -92,7 +92,7 @@ struct rx_pkt_attrib { u8 privacy; /* in frame_ctrl field */ u8 bdecrypted; u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorith */ + * indicate the encrypt algorithm */ u8 iv_len; u8 icv_len; u8 crc_err; @@ -175,7 +175,7 @@ struct recv_priv { u8 *precv_buf; /* 4 alignment */ struct __queue free_recv_buf_queue; u32 free_recv_buf_queue_cnt; - /* For display the phy informatiom */ + /* For display the phy information */ u8 is_signal_dbg; /* for debug */ u8 signal_strength_dbg; /* for debug */ s8 rssi; diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h index 82efcd54af3f9..cff065554608d 100644 --- a/drivers/staging/r8188eu/include/rtw_xmit.h +++ b/drivers/staging/r8188eu/include/rtw_xmit.h @@ -116,7 +116,7 @@ struct pkt_attrib { u32 last_txcmdsz; u8 nr_frags; u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorith */ + * indicate the encrypt algorithm */ u8 iv_len; u8 icv_len; u8 iv[18]; diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index 0254310bdf440..381385a7e1189 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -701,7 +701,7 @@ struct ADDBA_request { #define P2P_WILDCARD_SSID_LEN 7 -/* default value, used when: (1)p2p disabed or (2)p2p enabled +/* default value, used when: (1)p2p disabled or (2)p2p enabled * but only do 1 scan phase */ #define P2P_FINDPHASE_EX_NONE 0 /* used when p2p enabled and want to do 1 scan phase and @@ -766,11 +766,11 @@ enum P2P_STATE { P2P_STATE_TX_PROVISION_DIS_REQ = 6, P2P_STATE_RX_PROVISION_DIS_RSP = 7, P2P_STATE_RX_PROVISION_DIS_REQ = 8, - /* Doing the group owner negoitation handshake */ + /* Doing the group owner negotiation handshake */ P2P_STATE_GONEGO_ING = 9, - /* finish the group negoitation handshake with success */ + /* finish the group negotiation handshake with success */ P2P_STATE_GONEGO_OK = 10, - /* finish the group negoitation handshake with failure */ + /* finish the group negotiation handshake with failure */ P2P_STATE_GONEGO_FAIL = 11, /* receiving the P2P Inviation request and match with the profile. */ P2P_STATE_RECV_INVITE_REQ_MATCH = 12, @@ -790,9 +790,9 @@ enum P2P_STATE { P2P_STATE_RECV_INVITE_REQ_JOIN = 19, /* recveing the P2P Inviation response with failure */ P2P_STATE_RX_INVITE_RESP_FAIL = 20, - /* receiving p2p negoitation response with information is not available */ + /* receiving p2p negotiation response with information is not available */ P2P_STATE_RX_INFOR_NOREADY = 21, - /* sending p2p negoitation response with information is not available */ + /* sending p2p negotiation response with information is not available */ P2P_STATE_TX_INFOR_NOREADY = 22, }; diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c index 2de2e1e32738a..8516e253bb031 100644 --- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -2647,7 +2647,7 @@ static int rtw_p2p_connect(struct net_device *dev, u32 peer_channel = 0; /* Commented by Albert 20110304 */ - /* The input data contains two informations. */ + /* The input data contains two information. */ /* 1. First information is the MAC address which wants to formate with */ /* 2. Second information is the WPS PINCode or "pbc" string for push button method */ /* Format: 00:E0:4C:00:00:05 */ @@ -2721,7 +2721,7 @@ static void rtw_p2p_invite_req(struct net_device *dev, uint p2pielen = 0, attr_contentlen = 0; struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info; - /* The input data contains two informations. */ + /* The input data contains two information items. */ /* 1. First information is the P2P device address which you want to send to. */ /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */ /* Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */ @@ -2845,7 +2845,7 @@ static void rtw_p2p_prov_disc(struct net_device *dev, u8 *p2pie; uint p2pielen = 0, attr_contentlen = 0; - /* The input data contains two informations. */ + /* The input data contains two information items. */ /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */ /* 2. Second information is the WPS configuration method which wants to discovery */ /* Format: 00:E0:4C:00:00:05_display */ -- GitLab From 4b66ec6961f170cf782fb66520c36f2e950c7601 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:00:13 +0530 Subject: [PATCH 0075/1480] staging: r8188eu: Add space between function & macro parameters Space required between function and macro parameters to improve code readability. This Linux kernel coding style guideline resolves following error reported by checkpatch script: ERROR: space required after that ',' (ctx:VxV) Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/ce200b3a986628f943dfb0c4e412276793e59bbc.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- .../staging/r8188eu/include/osdep_service.h | 4 +-- .../staging/r8188eu/include/rtl8188e_hal.h | 2 +- drivers/staging/r8188eu/include/rtw_cmd.h | 18 ++++++------ drivers/staging/r8188eu/include/rtw_io.h | 28 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h index 72990a1cdc661..ec2631455f08c 100644 --- a/drivers/staging/r8188eu/include/osdep_service.h +++ b/drivers/staging/r8188eu/include/osdep_service.h @@ -53,7 +53,7 @@ static inline struct list_head *get_list_head(struct __queue *queue) return (&(queue->queue)); } -static inline void _set_timer(struct timer_list *ptimer,u32 delay_time) +static inline void _set_timer(struct timer_list *ptimer, u32 delay_time) { mod_timer(ptimer, jiffies + msecs_to_jiffies(delay_time)); } @@ -108,7 +108,7 @@ void rtw_free_netdev(struct net_device *netdev); #define FUNC_ADPT_FMT "%s(%s)" #define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name -#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1) +#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1) /* Macros for handling unaligned memory accesses */ diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h index 69faaaa7d3730..d9681f9b39153 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h @@ -164,7 +164,7 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo, void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail); -void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter,u8 *PROMContent, +void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail); void Hal_ReadThermalMeter_88E(struct adapter * dapter, u8 *PROMContent, bool AutoloadFail); diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 2896a732780b1..b4d4ac056e91b 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -725,17 +725,17 @@ Result: #define H2C_CMD_OVERFLOW 0x06 #define H2C_RESERVED 0x07 -u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num); -u8 rtw_createbss_cmd(struct adapter *padapter); +u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num); +u8 rtw_createbss_cmd(struct adapter *padapter); u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key); u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue); -u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network* pnetwork); +u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network* pnetwork); u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue); -u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); -u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); -u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); +u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); +u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); +u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); -u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset,u8 *pval); +u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset, u8 *pval); u8 rtw_setfwdig_cmd(struct adapter*padapter, u8 type); u8 rtw_setfwra_cmd(struct adapter*padapter, u8 type); @@ -746,10 +746,10 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter); u8 rtw_lps_ctrl_wk_cmd(struct adapter*padapter, u8 lps_ctrl_type, u8 enqueue); u8 rtw_rpt_timer_cfg_cmd(struct adapter*padapter, u16 minRptTime); - u8 rtw_antenna_select_cmd(struct adapter*padapter, u8 antenna,u8 enqueue); +u8 rtw_antenna_select_cmd(struct adapter*padapter, u8 antenna, u8 enqueue); u8 rtw_ps_cmd(struct adapter*padapter); -u8 rtw_chk_hi_queue_cmd(struct adapter*padapter); +u8 rtw_chk_hi_queue_cmd(struct adapter *padapter); u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan); diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h index 925c7967ac04e..87fcf6c94ff32 100644 --- a/drivers/staging/r8188eu/include/rtw_io.h +++ b/drivers/staging/r8188eu/include/rtw_io.h @@ -209,7 +209,7 @@ struct io_priv { }; uint ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); -void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue); +void sync_ioreq_enqueue(struct io_req *preq, struct io_queue *ioqueue); uint sync_ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue); struct io_req *alloc_ioreq(struct io_queue *pio_q); @@ -285,18 +285,18 @@ void bus_sync_io(struct io_queue *pio_q); u32 _ioreq2rwmem(struct io_queue *pio_q); void dev_power_down(struct adapter *Adapter, u8 bpwrup); -#define PlatformEFIOWrite1Byte(_a,_b,_c) \ - rtw_write8(_a,_b,_c) -#define PlatformEFIOWrite2Byte(_a,_b,_c) \ - rtw_write16(_a,_b,_c) -#define PlatformEFIOWrite4Byte(_a,_b,_c) \ - rtw_write32(_a,_b,_c) - -#define PlatformEFIORead1Byte(_a,_b) \ - rtw_read8(_a,_b) -#define PlatformEFIORead2Byte(_a,_b) \ - rtw_read16(_a,_b) -#define PlatformEFIORead4Byte(_a,_b) \ - rtw_read32(_a,_b) +#define PlatformEFIOWrite1Byte(_a, _b, _c) \ + rtw_write8(_a, _b, _c) +#define PlatformEFIOWrite2Byte(_a, _b, _c) \ + rtw_write16(_a, _b, _c) +#define PlatformEFIOWrite4Byte(_a, _b, _c) \ + rtw_write32(_a, _b, _c) + +#define PlatformEFIORead1Byte(_a, _b) \ + rtw_read8(_a, _b) +#define PlatformEFIORead2Byte(_a, _b) \ + rtw_read16(_a, _b) +#define PlatformEFIORead4Byte(_a, _b) \ + rtw_read32(_a, _b) #endif /* _RTL8711_IO_H_ */ -- GitLab From 2bf279885c596c7680426cacd0fe137db0e00a85 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:00:35 +0530 Subject: [PATCH 0076/1480] staging: r8188eu: Associate pointer symbol with parameter name The pointer symbol '*' should be associated with the function parameter name and not its type. This improves code readability and adheres to the coding-style guidelines. Address following checkpatch reported error: ERROR: "foo * bar" should be "foo *bar" While in there, update parameter name at one place to match other function declarations. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/d946b69bfdfb44baae3a130e412ed2e217a710a7.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtl8188e_hal.h | 2 +- drivers/staging/r8188eu/include/rtw_cmd.h | 16 ++++++++-------- drivers/staging/r8188eu/include/rtw_ioctl_set.h | 4 ++-- drivers/staging/r8188eu/include/rtw_mlme.h | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 8 ++++---- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h index d9681f9b39153..feeb37c228977 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h @@ -166,7 +166,7 @@ void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail); void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail); -void Hal_ReadThermalMeter_88E(struct adapter * dapter, u8 *PROMContent, +void Hal_ReadThermalMeter_88E(struct adapter *padapter, u8 *PROMContent, bool AutoloadFail); void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail); diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index b4d4ac056e91b..98c9a7b677198 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -729,25 +729,25 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, i u8 rtw_createbss_cmd(struct adapter *padapter); u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key); u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue); -u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network* pnetwork); +u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork); u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue); u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset, u8 *pval); -u8 rtw_setfwdig_cmd(struct adapter*padapter, u8 type); -u8 rtw_setfwra_cmd(struct adapter*padapter, u8 type); +u8 rtw_setfwdig_cmd(struct adapter *padapter, u8 type); +u8 rtw_setfwra_cmd(struct adapter *padapter, u8 type); -u8 rtw_addbareq_cmd(struct adapter*padapter, u8 tid, u8 *addr); +u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr); u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter); -u8 rtw_lps_ctrl_wk_cmd(struct adapter*padapter, u8 lps_ctrl_type, u8 enqueue); -u8 rtw_rpt_timer_cfg_cmd(struct adapter*padapter, u16 minRptTime); +u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue); +u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 minRptTime); -u8 rtw_antenna_select_cmd(struct adapter*padapter, u8 antenna, u8 enqueue); -u8 rtw_ps_cmd(struct adapter*padapter); +u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue); +u8 rtw_ps_cmd(struct adapter *padapter); u8 rtw_chk_hi_queue_cmd(struct adapter *padapter); diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_set.h b/drivers/staging/r8188eu/include/rtw_ioctl_set.h index 7365079c704f2..abe460d6504d0 100644 --- a/drivers/staging/r8188eu/include/rtw_ioctl_set.h +++ b/drivers/staging/r8188eu/include/rtw_ioctl_set.h @@ -10,10 +10,10 @@ typedef u8 NDIS_802_11_PMKID_VALUE[16]; u8 rtw_set_802_11_authentication_mode(struct adapter *adapt, enum ndis_802_11_auth_mode authmode); -u8 rtw_set_802_11_bssid(struct adapter*adapter, u8 *bssid); +u8 rtw_set_802_11_bssid(struct adapter *adapter, u8 *bssid); u8 rtw_set_802_11_add_wep(struct adapter *adapter, struct ndis_802_11_wep *wep); u8 rtw_set_802_11_disassociate(struct adapter *adapter); -u8 rtw_set_802_11_bssid_list_scan(struct adapter*adapter, +u8 rtw_set_802_11_bssid_list_scan(struct adapter *adapter, struct ndis_802_11_ssid *pssid, int ssid_max_num); u8 rtw_set_802_11_infrastructure_mode(struct adapter *adapter, diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h index b69989cbab21d..7658f864136e8 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme.h +++ b/drivers/staging/r8188eu/include/rtw_mlme.h @@ -547,7 +547,7 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork); -struct wlan_network* _rtw_find_network(struct __queue *scanned_queue, u8 *addr); +struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr); void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index b322d0848db9b..be470f913a94a 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -479,11 +479,11 @@ void report_survey_event(struct adapter *padapter, struct recv_frame *precv_fram void report_surveydone_event(struct adapter *padapter); void report_del_sta_event(struct adapter *padapter, unsigned char *addr, unsigned short reason); -void report_add_sta_event(struct adapter *padapter, unsigned char* addr, +void report_add_sta_event(struct adapter *padapter, unsigned char *addr, int cam_idx); void beacon_timing_control(struct adapter *padapter); -extern u8 set_tx_beacon_cmd(struct adapter*padapter); +extern u8 set_tx_beacon_cmd(struct adapter *padapter); unsigned int setup_beacon_frame(struct adapter *padapter, unsigned char *beacon_frame); void update_mgnt_tx_rate(struct adapter *padapter, u8 rate); @@ -502,7 +502,7 @@ void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr); void issue_probereq_p2p(struct adapter *padapter, u8 *da); void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 success); -void issue_p2p_invitation_request(struct adapter *padapter, u8* raddr); +void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr); void issue_beacon(struct adapter *padapter, int timeout_ms); void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq); @@ -514,7 +514,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da); s32 issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, - u8* da, int try_cnt, int wait_ms); + u8 *da, int try_cnt, int wait_ms); int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, -- GitLab From 285e8d027ecccb4623331c62896d225371502262 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:01:05 +0530 Subject: [PATCH 0077/1480] staging: r8188eu: replace leading spaces by tabs Spaces are prohibited as per the Linux coding style guidelines. Replace those by tabs wherever possible to improve code alignment. Error reported by checkpatch script. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/c32b702c61ea3367d60f0a4c2443093d6ce45a69.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_cmd.h | 10 +++++----- drivers/staging/r8188eu/include/rtw_mlme.h | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 98c9a7b677198..45734d32fec60 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -587,14 +587,14 @@ struct setratable_parm { }; struct getratable_parm { - uint rsvd; + uint rsvd; }; struct getratable_rsp { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; }; /* to get TX,RX retry count */ diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h index 7658f864136e8..ebf7168a7ef9c 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme.h +++ b/drivers/staging/r8188eu/include/rtw_mlme.h @@ -528,7 +528,7 @@ void rtw_indicate_scan_done(struct adapter *padapter); int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len); int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, - uint in_len, uint initial_out_len); + uint in_len, uint initial_out_len); void rtw_init_registrypriv_dev_network(struct adapter *adapter); void rtw_update_registrypriv_dev_network(struct adapter *adapter); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index be470f913a94a..413b94e387446 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -449,7 +449,7 @@ void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); void VCS_update(struct adapter *padapter, struct sta_info *psta); void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len, - struct sta_info *psta); + struct sta_info *psta); int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len); void update_IOT_info(struct adapter *padapter); void update_capinfo(struct adapter *adapter, u16 updatecap); -- GitLab From d119c18fa41dd455c6237e0b3dbb266de6a3c065 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:01:37 +0530 Subject: [PATCH 0078/1480] staging: r8188eu: Put '{" on the symbol declaration line Open braces '{" should be placed on the line of symbol declaration as per the coding-style guidelines. Improves readability and matches with style used in rest of the code. Issue reported by checkpatch script. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/375f742936493b562bd4dfba90eb75bd8ab84f8a.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_cmd.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index 45734d32fec60..a740a9a101d88 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -440,8 +440,7 @@ struct getrfintfs_parm { u8 rfintfs; }; -struct Tx_Beacon_param -{ +struct Tx_Beacon_param { struct wlan_bssid_ex network; }; @@ -677,26 +676,22 @@ struct set_ch_parm { }; /*H2C Handler index: 59 */ -struct SetChannelPlan_param -{ +struct SetChannelPlan_param { u8 channel_plan; }; /*H2C Handler index: 60 */ -struct LedBlink_param -{ +struct LedBlink_param { struct LED_871x *pLed; }; /*H2C Handler index: 61 */ -struct SetChannelSwitch_param -{ +struct SetChannelSwitch_param { u8 new_ch_no; }; /*H2C Handler index: 62 */ -struct TDLSoption_param -{ +struct TDLSoption_param { u8 addr[ETH_ALEN]; u8 option; }; @@ -854,8 +849,7 @@ enum rtw_h2c_cmd { #define _SetRFReg_CMD_ _Write_RFREG_CMD_ #ifdef _RTW_CMD_C_ -static struct _cmd_callback rtw_cmd_callback[] = -{ +static struct _cmd_callback rtw_cmd_callback[] = { {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ {GEN_CMD_CODE(_Write_MACREG), NULL}, {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, -- GitLab From c61c8480e3a59d469d4ff7d6ed9c88d43ba1722e Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:02:12 +0530 Subject: [PATCH 0079/1480] staging: r8188eu: Correct missing or extra space in the statements Properly spacing out code statements/instructions improves code readability. Add missing or remove extra space as necessary according to the Linux Kernel coding-style guidelines. Following errors reported by checkpatch script for inconsistent code spacing: ERROR: space prohibited before that close parenthesis ')' ERROR: space prohibited before that ',' (ctx:WxW) CHECK: spaces preferred around that '&' (ctx:VxV) Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/4559d1a406b9f32379ec01cfadacea13a11803ac.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- .../staging/r8188eu/include/rtl8188e_spec.h | 12 ++++++------ drivers/staging/r8188eu/include/rtw_mlme.h | 18 +++++++++--------- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h index e34ecdc096886..3fa3b3e5dd646 100644 --- a/drivers/staging/r8188eu/include/rtl8188e_spec.h +++ b/drivers/staging/r8188eu/include/rtl8188e_spec.h @@ -900,12 +900,12 @@ Current IOREG MAP #define HQSEL_HIQ BIT(5) /* For normal driver, 0x10C */ -#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) -#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) -#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) -#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) -#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) -#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) +#define _TXDMA_HIQ_MAP(x) (((x) & 0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x) & 0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x) & 0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x) & 0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x) & 0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x) & 0x3) << 4) #define QUEUE_LOW 1 #define QUEUE_NORMAL 2 diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h index ebf7168a7ef9c..ca539c652f26d 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme.h +++ b/drivers/staging/r8188eu/include/rtw_mlme.h @@ -101,17 +101,17 @@ struct rt_link_detect { struct profile_info { u8 ssidlen; - u8 ssid[ WLAN_SSID_MAXLEN ]; - u8 peermac[ ETH_ALEN ]; + u8 ssid[WLAN_SSID_MAXLEN]; + u8 peermac[ETH_ALEN]; }; struct tx_invite_req_info { u8 token; u8 benable; - u8 go_ssid[ WLAN_SSID_MAXLEN ]; + u8 go_ssid[WLAN_SSID_MAXLEN]; u8 ssidlen; - u8 go_bssid[ ETH_ALEN ]; - u8 peer_macaddr[ ETH_ALEN ]; + u8 go_bssid[ETH_ALEN]; + u8 peer_macaddr[ETH_ALEN]; u8 operating_ch; /* This information will be set by using the * p2p_set op_ch=x */ u8 peer_ch; /* The listen channel for peer P2P device */ @@ -154,9 +154,9 @@ struct tx_nego_req_info { }; struct group_id_info { - u8 go_device_addr[ ETH_ALEN ]; /* The GO's device address of + u8 go_device_addr[ETH_ALEN]; /* The GO's device address of * this P2P group */ - u8 ssid[ WLAN_SSID_MAXLEN ]; /* The SSID of this P2P group */ + u8 ssid[WLAN_SSID_MAXLEN]; /* The SSID of this P2P group */ }; struct scan_limit_info { @@ -459,7 +459,7 @@ static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state) { pmlmepriv->fw_state |= state; /* FOR HW integration */ - if (_FW_UNDER_SURVEY==state) + if (_FW_UNDER_SURVEY == state) pmlmepriv->bScanInProcess = true; } @@ -467,7 +467,7 @@ static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) { pmlmepriv->fw_state &= ~state; /* FOR HW integration */ - if (_FW_UNDER_SURVEY==state) + if (_FW_UNDER_SURVEY == state) pmlmepriv->bScanInProcess = false; } diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 413b94e387446..66aa8b497aa1d 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -729,7 +729,7 @@ enum rtw_c2h_event { GEN_EVT_CODE(_Survey), /*8*/ GEN_EVT_CODE(_SurveyDone), /*9*/ - GEN_EVT_CODE(_JoinBss) , /*10*/ + GEN_EVT_CODE(_JoinBss), /*10*/ GEN_EVT_CODE(_AddSTA), GEN_EVT_CODE(_DelSTA), GEN_EVT_CODE(_AtimDone), -- GitLab From 325d0d2c9d1187143eb0a3d5a6f16308a986bdb4 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Fri, 21 Oct 2022 03:02:35 +0530 Subject: [PATCH 0080/1480] staging: r8188eu: Remove unused macros Simple variants of macros PlatformEFIOWrite and PlatformEFIORead are defined but never used. As they do not appear to be designed for anything significant, we can remove them to avoid unexpected usage. Suggested-by: Julia Lawall Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/efaf637a14b6f7fdd0178e2aecf8abf17e6922f6.1666299151.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_io.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h index 87fcf6c94ff32..e9744694204bc 100644 --- a/drivers/staging/r8188eu/include/rtw_io.h +++ b/drivers/staging/r8188eu/include/rtw_io.h @@ -285,18 +285,4 @@ void bus_sync_io(struct io_queue *pio_q); u32 _ioreq2rwmem(struct io_queue *pio_q); void dev_power_down(struct adapter *Adapter, u8 bpwrup); -#define PlatformEFIOWrite1Byte(_a, _b, _c) \ - rtw_write8(_a, _b, _c) -#define PlatformEFIOWrite2Byte(_a, _b, _c) \ - rtw_write16(_a, _b, _c) -#define PlatformEFIOWrite4Byte(_a, _b, _c) \ - rtw_write32(_a, _b, _c) - -#define PlatformEFIORead1Byte(_a, _b) \ - rtw_read8(_a, _b) -#define PlatformEFIORead2Byte(_a, _b) \ - rtw_read16(_a, _b) -#define PlatformEFIORead4Byte(_a, _b) \ - rtw_read32(_a, _b) - #endif /* _RTL8711_IO_H_ */ -- GitLab From 302baa63e7553e7bf57df2f98d82855461d81bbe Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Fri, 21 Oct 2022 12:54:55 -0700 Subject: [PATCH 0081/1480] staging: rtl8723bs: remove tab in variable definition Remove unnecessary tab in variable definition in rtw_ioctl_set. Issue found by checkpatch. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/ee1bcccb23b3d24eb87d0b08bfa817b4af692dc5.1666380274.git.eperi1024@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index 8c7daab141db4..ede7d29308444 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -367,7 +367,7 @@ u8 rtw_set_802_11_disassociate(struct adapter *padapter) u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) { - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; u8 res = true; if (!padapter) { -- GitLab From 83df6f3f2690533bf094c18bef39a016311b7a46 Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Fri, 21 Oct 2022 12:54:56 -0700 Subject: [PATCH 0082/1480] staging: rtl8723bs: add newline after variable declaration Fix checkpatch style warning by adding newline after variable declaration in rtw_ioctl_set Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/76e1bfd210d79e6d3f7cc09233621c8b741b2370.1666380274.git.eperi1024@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index ede7d29308444..47323160e72d8 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -78,6 +78,7 @@ u8 rtw_do_join(struct adapter *padapter) goto exit; } else { int select_ret; + spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); if (select_ret == _SUCCESS) { -- GitLab From 19cbe487f55fd04bc0b83bc34b6175f9dc6ab4e4 Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Fri, 21 Oct 2022 12:54:57 -0700 Subject: [PATCH 0083/1480] staging: rtl8723bs: use tab instead of spaces for indent Replace spaces with tab for indent and correct alignment for closing brace in rtw_ioctl_set. Issue found by checkpatch. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/0516cac046c617b55718fddb2aac3a50d543d84c.1666380274.git.eperi1024@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_ioctl_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index 47323160e72d8..3b44f0dd5b0ae 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -312,7 +312,7 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not */ - } + } *pold_state = networktype; -- GitLab From 375ac0b2c1f11d8274999e91546d69e3140c6c6a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 20 Oct 2022 14:06:49 +0100 Subject: [PATCH 0084/1480] usb: ftdi-elan: remove variable err_count Variable err_count is just being incremented and it's never used anywhere else. The variable and the increment are redundant so remove it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221020130649.1546112-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index b2f980409d0b5..33b35788bd0ba 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -1956,7 +1956,6 @@ static int ftdi_elan_synchronize(struct usb_ftdi *ftdi) int long_stop = 10; int retry_on_timeout = 5; int retry_on_empty = 10; - int err_count = 0; retval = ftdi_elan_flush_input_fifo(ftdi); if (retval) return retval; @@ -2051,7 +2050,6 @@ static int ftdi_elan_synchronize(struct usb_ftdi *ftdi) continue; } } else { - err_count += 1; dev_err(&ftdi->udev->dev, "error = %d\n", retval); if (read_stop-- > 0) { -- GitLab From 13cc02f115d010d078851fac7f347890e62c097d Mon Sep 17 00:00:00 2001 From: Jules Irenge Date: Sat, 1 Oct 2022 15:56:33 +0100 Subject: [PATCH 0085/1480] usbip: vudc: Convert snprintf() to sysfs_emit() Coccinnelle reports a warning Warning: Use scnprintf or sprintf Following the advice on kernel documentation https://www.kernel.org/doc/html/latest/filesystems/sysfs.html For show(device *...) functions we should only use sysfs_emit() or sysfs_emit_at() especially when formatting the value to be returned to user space. Convert snprintf() to sysfs_emit() Signed-off-by: Jules Irenge Reviewed-by: Shuah Khan Link: https://lore.kernel.org/r/YzhVIaNGdM33pcts@octinomon Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vudc_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c index c95e6b2bfd32a..907a43a008964 100644 --- a/drivers/usb/usbip/vudc_sysfs.c +++ b/drivers/usb/usbip/vudc_sysfs.c @@ -242,7 +242,7 @@ static ssize_t usbip_status_show(struct device *dev, status = udc->ud.status; spin_unlock_irq(&udc->ud.lock); - return snprintf(out, PAGE_SIZE, "%d\n", status); + return sysfs_emit(out, "%d\n", status); } static DEVICE_ATTR_RO(usbip_status); -- GitLab From 27ef01e381c777521084724248c5736cd1cdda63 Mon Sep 17 00:00:00 2001 From: Xuezhi Zhang Date: Fri, 14 Oct 2022 19:06:06 +0800 Subject: [PATCH 0086/1480] usbip: convert sysfs snprintf to sysfs_emit Follow the advice of the Documentation/filesystems/sysfs.rst and show() should only use sysfs_emit() or sysfs_emit_at() when formatting the value to be returned to user space. Signed-off-by: Xuezhi Zhang Reviewed-by: Shuah Khan Link: https://lore.kernel.org/r/20221014110606.599352-1-zhangxuezhi3@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 3c6d452e3bf40..f92047d860f07 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -30,7 +30,7 @@ static ssize_t usbip_status_show(struct device *dev, status = sdev->ud.status; spin_unlock_irq(&sdev->ud.lock); - return snprintf(buf, PAGE_SIZE, "%d\n", status); + return sysfs_emit(buf, "%d\n", status); } static DEVICE_ATTR_RO(usbip_status); -- GitLab From 90732f1769165dcf0778d723ad188f6441a930f5 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Sun, 9 Oct 2022 15:23:05 +0800 Subject: [PATCH 0087/1480] usb: cdns3: adjust the partial logic of cdnsp_pci_remove In cdnsp_pci_remove, if pci_is_enabled returns true, it will call cdns_remove; else it will call kfree. Then both control flow goes to pci_dev_put. Adjust this logic by modifying it to an if else. Signed-off-by: Dongliang Mu Acked-by: Pawel Laszczak Link: https://lore.kernel.org/r/20221009072305.1593707-1-dzm91@hust.edu.cn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdnsp-pci.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c index fe8a114c586cc..efd54ed918b97 100644 --- a/drivers/usb/cdns3/cdnsp-pci.c +++ b/drivers/usb/cdns3/cdnsp-pci.c @@ -192,14 +192,12 @@ static void cdnsp_pci_remove(struct pci_dev *pdev) if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); - if (!pci_is_enabled(func)) { + if (pci_is_enabled(func)) { + cdns_remove(cdnsp); + } else { kfree(cdnsp); - goto pci_put; } - cdns_remove(cdnsp); - -pci_put: pci_dev_put(func); } -- GitLab From 4e74b483a3ce87e173634ba238a84b7fe404061b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 7 Oct 2022 21:32:10 +0100 Subject: [PATCH 0088/1480] USB: host: Kconfig: Fix spelling mistake "firwmare" -> "firmware" There is a spelling mistake in a Kconfig description. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221007203210.2756505-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 247568bc17a2b..8e8db71021a54 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -47,7 +47,7 @@ config USB_XHCI_PCI_RENESAS tristate "Support for additional Renesas xHCI controller with firmware" help Say 'Y' to enable the support for the Renesas xHCI controller with - firmware. Make sure you have the firwmare for the device and + firmware. Make sure you have the firmware for the device and installed on your system for this device to work. If unsure, say 'N'. -- GitLab From 61dd457c0188c0deef68c2b919c0a2defe5db388 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 5 Oct 2022 12:55:55 +0200 Subject: [PATCH 0089/1480] dt-bindings: usb: dwc2: Add some missing Lantiq variants These IP block variants appear in various vendor trees and are distinct variants which needs to be handled. Cc: devicetree@vger.kernel.org Signed-off-by: Linus Walleij Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221005105555.2665485-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/dwc2.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.yaml b/Documentation/devicetree/bindings/usb/dwc2.yaml index dc4988c0009cf..1ab85489a3f8f 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.yaml +++ b/Documentation/devicetree/bindings/usb/dwc2.yaml @@ -43,7 +43,10 @@ properties: - const: rockchip,rk3066-usb - const: snps,dwc2 - const: lantiq,arx100-usb + - const: lantiq,ase-usb + - const: lantiq,danube-usb - const: lantiq,xrx200-usb + - const: lantiq,xrx300-usb - items: - enum: - amlogic,meson8-usb -- GitLab From 9b6447e04bc2a4d06f2ef74a583848c573a25dbc Mon Sep 17 00:00:00 2001 From: Jose Ignacio Tornos Martinez Date: Mon, 3 Oct 2022 11:10:16 +0200 Subject: [PATCH 0090/1480] USB: usbip: missing lock in stub down Missing lock in sysfs operation when we want to close the connection in order to check the status and send the down event in a safe way. Signed-off-by: Jose Ignacio Tornos Martinez Reviewed-by: Shuah Khan Link: https://lore.kernel.org/r/20221003091016.641900-1-jtornosm@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index f92047d860f07..9c6954aad6c88 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -118,6 +118,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a } else { dev_info(dev, "stub down\n"); + mutex_lock(&sdev->ud.sysfs_lock); + spin_lock_irq(&sdev->ud.lock); if (sdev->ud.status != SDEV_ST_USED) goto err; -- GitLab From d182bf156c4cb8b08ce4a75e82b3357b14a4382d Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Tue, 11 Oct 2022 09:53:48 +0200 Subject: [PATCH 0091/1480] usb: gadget: uvc: default the ctrl request interface offsets For the userspace it is needed to distinguish between requests for the control or streaming interface. The userspace would have to parse the configfs to know which interface index it has to compare the ctrl requests against. Since the interface numbers are not fixed, e.g. for composite gadgets, the interface offset depends on the setup. The kernel has this information when handing over the ctrl request to the userspace. This patch removes the offset from the interface numbers and expose the default interface defines in the uapi g_uvc.h. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20221011075348.1786897-1-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_uvc.c | 15 ++++++++++++--- include/uapi/linux/usb/g_uvc.h | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 6e196e06181ec..6e131624011a5 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -39,9 +39,6 @@ MODULE_PARM_DESC(trace, "Trace level bitmask"); /* string IDs are assigned dynamically */ -#define UVC_STRING_CONTROL_IDX 0 -#define UVC_STRING_STREAMING_IDX 1 - static struct usb_string uvc_en_us_strings[] = { /* [UVC_STRING_CONTROL_IDX].s = DYNAMIC, */ [UVC_STRING_STREAMING_IDX].s = "Video Streaming", @@ -228,6 +225,8 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) struct uvc_device *uvc = to_uvc(f); struct v4l2_event v4l2_event; struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; + unsigned int interface = le16_to_cpu(ctrl->wIndex) & 0xff; + struct usb_ctrlrequest *mctrl; if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) { uvcg_info(f, "invalid request type\n"); @@ -248,6 +247,16 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_SETUP; memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); + + /* check for the interface number, fixup the interface number in + * the ctrl request so the userspace doesn't have to bother with + * offset and configfs parsing + */ + mctrl = &uvc_event->req; + mctrl->wIndex &= ~cpu_to_le16(0xff); + if (interface == uvc->streaming_intf) + mctrl->wIndex = cpu_to_le16(UVC_STRING_STREAMING_IDX); + v4l2_event_queue(&uvc->vdev, &v4l2_event); return 0; diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h index 652f169a019e7..8d7824dde1b2f 100644 --- a/include/uapi/linux/usb/g_uvc.h +++ b/include/uapi/linux/usb/g_uvc.h @@ -21,6 +21,9 @@ #define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5) #define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5) +#define UVC_STRING_CONTROL_IDX 0 +#define UVC_STRING_STREAMING_IDX 1 + struct uvc_request_data { __s32 length; __u8 data[60]; -- GitLab From a84436a987e7f4ee8eeb62a8a5abcfc60b356d16 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Oct 2022 17:55:52 +0300 Subject: [PATCH 0092/1480] usb: typec: retimer: Use device type for matching Device name is not reliable so using the type instead in retimer_fwnode_match(). This will also introduce is_typec_retimer() helper, and remove the static keyword from the retimer device type. That will make it accessible also in the main typec class. Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221019145552.32493-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/retimer.c | 16 ++-------------- drivers/usb/typec/retimer.h | 4 ++++ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c index ee94dbbe47453..3a4146ea6e7cf 100644 --- a/drivers/usb/typec/retimer.c +++ b/drivers/usb/typec/retimer.c @@ -17,21 +17,9 @@ #include "class.h" #include "retimer.h" -static bool dev_name_ends_with(struct device *dev, const char *suffix) -{ - const char *name = dev_name(dev); - const int name_len = strlen(name); - const int suffix_len = strlen(suffix); - - if (suffix_len > name_len) - return false; - - return strcmp(name + (name_len - suffix_len), suffix) == 0; -} - static int retimer_fwnode_match(struct device *dev, const void *fwnode) { - return device_match_fwnode(dev, fwnode) && dev_name_ends_with(dev, "-retimer"); + return is_typec_retimer(dev) && device_match_fwnode(dev, fwnode); } static void *typec_retimer_match(struct fwnode_handle *fwnode, const char *id, void *data) @@ -97,7 +85,7 @@ static void typec_retimer_release(struct device *dev) kfree(to_typec_retimer(dev)); } -static const struct device_type typec_retimer_dev_type = { +const struct device_type typec_retimer_dev_type = { .name = "typec_retimer", .release = typec_retimer_release, }; diff --git a/drivers/usb/typec/retimer.h b/drivers/usb/typec/retimer.h index fa15951d48468..e34bd23323be5 100644 --- a/drivers/usb/typec/retimer.h +++ b/drivers/usb/typec/retimer.h @@ -12,4 +12,8 @@ struct typec_retimer { #define to_typec_retimer(_dev_) container_of(_dev_, struct typec_retimer, dev) +const struct device_type typec_retimer_dev_type; + +#define is_typec_retimer(dev) ((dev)->type == &typec_retimer_dev_type) + #endif /* __USB_TYPEC_RETIMER__ */ -- GitLab From 32fee1df51109a117eb5063e950c372278688098 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 19 Oct 2022 17:29:31 +0200 Subject: [PATCH 0093/1480] usb: musb: remove unused davinci support The musb-davinci driver was only used on dm644x, which got removed in linux-6.0. The only remaining davinci machines are da8xx devicetree based and do not use this hardware. Signed-off-by: Arnd Bergmann Acked-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20221019152947.3857217-6-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/Kconfig | 12 - drivers/usb/musb/Makefile | 2 - drivers/usb/musb/cppi_dma.c | 1547 ----------------------------------- drivers/usb/musb/davinci.c | 606 -------------- drivers/usb/musb/davinci.h | 103 --- 5 files changed, 2270 deletions(-) delete mode 100644 drivers/usb/musb/cppi_dma.c delete mode 100644 drivers/usb/musb/davinci.c delete mode 100644 drivers/usb/musb/davinci.h diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 6c8f7763e75e4..f9eec666103cb 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -70,12 +70,6 @@ config USB_MUSB_SUNXI select GENERIC_PHY select SUNXI_SRAM -config USB_MUSB_DAVINCI - tristate "DaVinci" - depends on ARCH_DAVINCI_DMx - depends on NOP_USB_XCEIV - depends on BROKEN - config USB_MUSB_DA8XX tristate "DA8xx/OMAP-L1x" depends on ARCH_DAVINCI_DA8XX @@ -161,12 +155,6 @@ config USB_INVENTRA_DMA help Enable DMA transfers using Mentor's engine. -config USB_TI_CPPI_DMA - bool 'TI CPPI (Davinci)' - depends on USB_MUSB_DAVINCI - help - Enable DMA transfers when TI CPPI DMA is available. - config USB_TI_CPPI41_DMA bool 'TI CPPI 4.1' depends on (ARCH_OMAP || ARCH_DAVINCI_DA8XX) && DMADEVICES diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 51dd54a8de497..44a9e27b2157a 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o obj-$(CONFIG_USB_MUSB_TUSB6010) += tusb6010.o -obj-$(CONFIG_USB_MUSB_DAVINCI) += davinci.o obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_UX500) += ux500.o obj-$(CONFIG_USB_MUSB_JZ4740) += jz4740.o @@ -33,7 +32,6 @@ obj-$(CONFIG_USB_MUSB_POLARFIRE_SOC) += mpfs.o # though PIO is always there to back up DMA, and for ep0 musb_hdrc-$(CONFIG_USB_INVENTRA_DMA) += musbhsdma.o -musb_hdrc-$(CONFIG_USB_TI_CPPI_DMA) += cppi_dma.o musb_hdrc-$(CONFIG_USB_TUSB_OMAP_DMA) += tusb6010_omap.o musb_hdrc-$(CONFIG_USB_UX500_DMA) += ux500_dma.o musb_hdrc-$(CONFIG_USB_TI_CPPI41_DMA) += musb_cppi41.o diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c deleted file mode 100644 index edb5b63d70634..0000000000000 --- a/drivers/usb/musb/cppi_dma.c +++ /dev/null @@ -1,1547 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2005-2006 by Texas Instruments - * - * This file implements a DMA interface using TI's CPPI DMA. - * For now it's DaVinci-only, but CPPI isn't specific to DaVinci or USB. - * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci. - */ - -#include -#include -#include -#include - -#include "musb_core.h" -#include "musb_debug.h" -#include "cppi_dma.h" -#include "davinci.h" - - -/* CPPI DMA status 7-mar-2006: - * - * - See musb_{host,gadget}.c for more info - * - * - Correct RX DMA generally forces the engine into irq-per-packet mode, - * which can easily saturate the CPU under non-mass-storage loads. - * - * NOTES 24-aug-2006 (2.6.18-rc4): - * - * - peripheral RXDMA wedged in a test with packets of length 512/512/1. - * evidently after the 1 byte packet was received and acked, the queue - * of BDs got garbaged so it wouldn't empty the fifo. (rxcsr 0x2003, - * and RX DMA0: 4 left, 80000000 8feff880, 8feff860 8feff860; 8f321401 - * 004001ff 00000001 .. 8feff860) Host was just getting NAKed on tx - * of its next (512 byte) packet. IRQ issues? - * - * REVISIT: the "transfer DMA" glue between CPPI and USB fifos will - * evidently also directly update the RX and TX CSRs ... so audit all - * host and peripheral side DMA code to avoid CSR access after DMA has - * been started. - */ - -/* REVISIT now we can avoid preallocating these descriptors; or - * more simply, switch to a global freelist not per-channel ones. - * Note: at full speed, 64 descriptors == 4K bulk data. - */ -#define NUM_TXCHAN_BD 64 -#define NUM_RXCHAN_BD 64 - -static inline void cpu_drain_writebuffer(void) -{ - wmb(); -#ifdef CONFIG_CPU_ARM926T - /* REVISIT this "should not be needed", - * but lack of it sure seemed to hurt ... - */ - asm("mcr p15, 0, r0, c7, c10, 4 @ drain write buffer\n"); -#endif -} - -static inline struct cppi_descriptor *cppi_bd_alloc(struct cppi_channel *c) -{ - struct cppi_descriptor *bd = c->freelist; - - if (bd) - c->freelist = bd->next; - return bd; -} - -static inline void -cppi_bd_free(struct cppi_channel *c, struct cppi_descriptor *bd) -{ - if (!bd) - return; - bd->next = c->freelist; - c->freelist = bd; -} - -/* - * Start DMA controller - * - * Initialize the DMA controller as necessary. - */ - -/* zero out entire rx state RAM entry for the channel */ -static void cppi_reset_rx(struct cppi_rx_stateram __iomem *rx) -{ - musb_writel(&rx->rx_skipbytes, 0, 0); - musb_writel(&rx->rx_head, 0, 0); - musb_writel(&rx->rx_sop, 0, 0); - musb_writel(&rx->rx_current, 0, 0); - musb_writel(&rx->rx_buf_current, 0, 0); - musb_writel(&rx->rx_len_len, 0, 0); - musb_writel(&rx->rx_cnt_cnt, 0, 0); -} - -/* zero out entire tx state RAM entry for the channel */ -static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr) -{ - musb_writel(&tx->tx_head, 0, 0); - musb_writel(&tx->tx_buf, 0, 0); - musb_writel(&tx->tx_current, 0, 0); - musb_writel(&tx->tx_buf_current, 0, 0); - musb_writel(&tx->tx_info, 0, 0); - musb_writel(&tx->tx_rem_len, 0, 0); - /* musb_writel(&tx->tx_dummy, 0, 0); */ - musb_writel(&tx->tx_complete, 0, ptr); -} - -static void cppi_pool_init(struct cppi *cppi, struct cppi_channel *c) -{ - int j; - - /* initialize channel fields */ - c->head = NULL; - c->tail = NULL; - c->last_processed = NULL; - c->channel.status = MUSB_DMA_STATUS_UNKNOWN; - c->controller = cppi; - c->is_rndis = 0; - c->freelist = NULL; - - /* build the BD Free list for the channel */ - for (j = 0; j < NUM_TXCHAN_BD + 1; j++) { - struct cppi_descriptor *bd; - dma_addr_t dma; - - bd = dma_pool_alloc(cppi->pool, GFP_KERNEL, &dma); - bd->dma = dma; - cppi_bd_free(c, bd); - } -} - -static int cppi_channel_abort(struct dma_channel *); - -static void cppi_pool_free(struct cppi_channel *c) -{ - struct cppi *cppi = c->controller; - struct cppi_descriptor *bd; - - (void) cppi_channel_abort(&c->channel); - c->channel.status = MUSB_DMA_STATUS_UNKNOWN; - c->controller = NULL; - - /* free all its bds */ - bd = c->last_processed; - do { - if (bd) - dma_pool_free(cppi->pool, bd, bd->dma); - bd = cppi_bd_alloc(c); - } while (bd); - c->last_processed = NULL; -} - -static void cppi_controller_start(struct cppi *controller) -{ - void __iomem *tibase; - int i; - - /* do whatever is necessary to start controller */ - for (i = 0; i < ARRAY_SIZE(controller->tx); i++) { - controller->tx[i].transmit = true; - controller->tx[i].index = i; - } - for (i = 0; i < ARRAY_SIZE(controller->rx); i++) { - controller->rx[i].transmit = false; - controller->rx[i].index = i; - } - - /* setup BD list on a per channel basis */ - for (i = 0; i < ARRAY_SIZE(controller->tx); i++) - cppi_pool_init(controller, controller->tx + i); - for (i = 0; i < ARRAY_SIZE(controller->rx); i++) - cppi_pool_init(controller, controller->rx + i); - - tibase = controller->tibase; - INIT_LIST_HEAD(&controller->tx_complete); - - /* initialise tx/rx channel head pointers to zero */ - for (i = 0; i < ARRAY_SIZE(controller->tx); i++) { - struct cppi_channel *tx_ch = controller->tx + i; - struct cppi_tx_stateram __iomem *tx; - - INIT_LIST_HEAD(&tx_ch->tx_complete); - - tx = tibase + DAVINCI_TXCPPI_STATERAM_OFFSET(i); - tx_ch->state_ram = tx; - cppi_reset_tx(tx, 0); - } - for (i = 0; i < ARRAY_SIZE(controller->rx); i++) { - struct cppi_channel *rx_ch = controller->rx + i; - struct cppi_rx_stateram __iomem *rx; - - INIT_LIST_HEAD(&rx_ch->tx_complete); - - rx = tibase + DAVINCI_RXCPPI_STATERAM_OFFSET(i); - rx_ch->state_ram = rx; - cppi_reset_rx(rx); - } - - /* enable individual cppi channels */ - musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG, - DAVINCI_DMA_ALL_CHANNELS_ENABLE); - musb_writel(tibase, DAVINCI_RXCPPI_INTENAB_REG, - DAVINCI_DMA_ALL_CHANNELS_ENABLE); - - /* enable tx/rx CPPI control */ - musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_ENABLE); - musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_ENABLE); - - /* disable RNDIS mode, also host rx RNDIS autorequest */ - musb_writel(tibase, DAVINCI_RNDIS_REG, 0); - musb_writel(tibase, DAVINCI_AUTOREQ_REG, 0); -} - -/* - * Stop DMA controller - * - * De-Init the DMA controller as necessary. - */ - -static void cppi_controller_stop(struct cppi *controller) -{ - void __iomem *tibase; - int i; - struct musb *musb; - - musb = controller->controller.musb; - - tibase = controller->tibase; - /* DISABLE INDIVIDUAL CHANNEL Interrupts */ - musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG, - DAVINCI_DMA_ALL_CHANNELS_ENABLE); - musb_writel(tibase, DAVINCI_RXCPPI_INTCLR_REG, - DAVINCI_DMA_ALL_CHANNELS_ENABLE); - - musb_dbg(musb, "Tearing down RX and TX Channels"); - for (i = 0; i < ARRAY_SIZE(controller->tx); i++) { - /* FIXME restructure of txdma to use bds like rxdma */ - controller->tx[i].last_processed = NULL; - cppi_pool_free(controller->tx + i); - } - for (i = 0; i < ARRAY_SIZE(controller->rx); i++) - cppi_pool_free(controller->rx + i); - - /* in Tx Case proper teardown is supported. We resort to disabling - * Tx/Rx CPPI after cleanup of Tx channels. Before TX teardown is - * complete TX CPPI cannot be disabled. - */ - /*disable tx/rx cppi */ - musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE); - musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE); -} - -/* While dma channel is allocated, we only want the core irqs active - * for fault reports, otherwise we'd get irqs that we don't care about. - * Except for TX irqs, where dma done != fifo empty and reusable ... - * - * NOTE: docs don't say either way, but irq masking **enables** irqs. - * - * REVISIT same issue applies to pure PIO usage too, and non-cppi dma... - */ -static inline void core_rxirq_disable(void __iomem *tibase, unsigned epnum) -{ - musb_writel(tibase, DAVINCI_USB_INT_MASK_CLR_REG, 1 << (epnum + 8)); -} - -static inline void core_rxirq_enable(void __iomem *tibase, unsigned epnum) -{ - musb_writel(tibase, DAVINCI_USB_INT_MASK_SET_REG, 1 << (epnum + 8)); -} - - -/* - * Allocate a CPPI Channel for DMA. With CPPI, channels are bound to - * each transfer direction of a non-control endpoint, so allocating - * (and deallocating) is mostly a way to notice bad housekeeping on - * the software side. We assume the irqs are always active. - */ -static struct dma_channel * -cppi_channel_allocate(struct dma_controller *c, - struct musb_hw_ep *ep, u8 transmit) -{ - struct cppi *controller; - u8 index; - struct cppi_channel *cppi_ch; - void __iomem *tibase; - struct musb *musb; - - controller = container_of(c, struct cppi, controller); - tibase = controller->tibase; - musb = c->musb; - - /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */ - index = ep->epnum - 1; - - /* return the corresponding CPPI Channel Handle, and - * probably disable the non-CPPI irq until we need it. - */ - if (transmit) { - if (index >= ARRAY_SIZE(controller->tx)) { - musb_dbg(musb, "no %cX%d CPPI channel", 'T', index); - return NULL; - } - cppi_ch = controller->tx + index; - } else { - if (index >= ARRAY_SIZE(controller->rx)) { - musb_dbg(musb, "no %cX%d CPPI channel", 'R', index); - return NULL; - } - cppi_ch = controller->rx + index; - core_rxirq_disable(tibase, ep->epnum); - } - - /* REVISIT make this an error later once the same driver code works - * with the other DMA engine too - */ - if (cppi_ch->hw_ep) - musb_dbg(musb, "re-allocating DMA%d %cX channel %p", - index, transmit ? 'T' : 'R', cppi_ch); - cppi_ch->hw_ep = ep; - cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; - cppi_ch->channel.max_len = 0x7fffffff; - - musb_dbg(musb, "Allocate CPPI%d %cX", index, transmit ? 'T' : 'R'); - return &cppi_ch->channel; -} - -/* Release a CPPI Channel. */ -static void cppi_channel_release(struct dma_channel *channel) -{ - struct cppi_channel *c; - void __iomem *tibase; - - /* REVISIT: for paranoia, check state and abort if needed... */ - - c = container_of(channel, struct cppi_channel, channel); - tibase = c->controller->tibase; - if (!c->hw_ep) - musb_dbg(c->controller->controller.musb, - "releasing idle DMA channel %p", c); - else if (!c->transmit) - core_rxirq_enable(tibase, c->index + 1); - - /* for now, leave its cppi IRQ enabled (we won't trigger it) */ - c->hw_ep = NULL; - channel->status = MUSB_DMA_STATUS_UNKNOWN; -} - -/* Context: controller irqlocked */ -static void -cppi_dump_rx(int level, struct cppi_channel *c, const char *tag) -{ - void __iomem *base = c->controller->mregs; - struct cppi_rx_stateram __iomem *rx = c->state_ram; - - musb_ep_select(base, c->index + 1); - - musb_dbg(c->controller->controller.musb, - "RX DMA%d%s: %d left, csr %04x, " - "%08x H%08x S%08x C%08x, " - "B%08x L%08x %08x .. %08x", - c->index, tag, - musb_readl(c->controller->tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index), - musb_readw(c->hw_ep->regs, MUSB_RXCSR), - - musb_readl(&rx->rx_skipbytes, 0), - musb_readl(&rx->rx_head, 0), - musb_readl(&rx->rx_sop, 0), - musb_readl(&rx->rx_current, 0), - - musb_readl(&rx->rx_buf_current, 0), - musb_readl(&rx->rx_len_len, 0), - musb_readl(&rx->rx_cnt_cnt, 0), - musb_readl(&rx->rx_complete, 0) - ); -} - -/* Context: controller irqlocked */ -static void -cppi_dump_tx(int level, struct cppi_channel *c, const char *tag) -{ - void __iomem *base = c->controller->mregs; - struct cppi_tx_stateram __iomem *tx = c->state_ram; - - musb_ep_select(base, c->index + 1); - - musb_dbg(c->controller->controller.musb, - "TX DMA%d%s: csr %04x, " - "H%08x S%08x C%08x %08x, " - "F%08x L%08x .. %08x", - c->index, tag, - musb_readw(c->hw_ep->regs, MUSB_TXCSR), - - musb_readl(&tx->tx_head, 0), - musb_readl(&tx->tx_buf, 0), - musb_readl(&tx->tx_current, 0), - musb_readl(&tx->tx_buf_current, 0), - - musb_readl(&tx->tx_info, 0), - musb_readl(&tx->tx_rem_len, 0), - /* dummy/unused word 6 */ - musb_readl(&tx->tx_complete, 0) - ); -} - -/* Context: controller irqlocked */ -static inline void -cppi_rndis_update(struct cppi_channel *c, int is_rx, - void __iomem *tibase, int is_rndis) -{ - /* we may need to change the rndis flag for this cppi channel */ - if (c->is_rndis != is_rndis) { - u32 value = musb_readl(tibase, DAVINCI_RNDIS_REG); - u32 temp = 1 << (c->index); - - if (is_rx) - temp <<= 16; - if (is_rndis) - value |= temp; - else - value &= ~temp; - musb_writel(tibase, DAVINCI_RNDIS_REG, value); - c->is_rndis = is_rndis; - } -} - -static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) -{ - pr_debug("RXBD/%s %08x: " - "nxt %08x buf %08x off.blen %08x opt.plen %08x\n", - tag, bd->dma, - bd->hw_next, bd->hw_bufp, bd->hw_off_len, - bd->hw_options); -} - -static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx) -{ - struct cppi_descriptor *bd; - - cppi_dump_rx(level, rx, tag); - if (rx->last_processed) - cppi_dump_rxbd("last", rx->last_processed); - for (bd = rx->head; bd; bd = bd->next) - cppi_dump_rxbd("active", bd); -} - - -/* NOTE: DaVinci autoreq is ignored except for host side "RNDIS" mode RX; - * so we won't ever use it (see "CPPI RX Woes" below). - */ -static inline int cppi_autoreq_update(struct cppi_channel *rx, - void __iomem *tibase, int onepacket, unsigned n_bds) -{ - u32 val; - -#ifdef RNDIS_RX_IS_USABLE - u32 tmp; - /* assert(is_host_active(musb)) */ - - /* start from "AutoReq never" */ - tmp = musb_readl(tibase, DAVINCI_AUTOREQ_REG); - val = tmp & ~((0x3) << (rx->index * 2)); - - /* HCD arranged reqpkt for packet #1. we arrange int - * for all but the last one, maybe in two segments. - */ - if (!onepacket) { -#if 0 - /* use two segments, autoreq "all" then the last "never" */ - val |= ((0x3) << (rx->index * 2)); - n_bds--; -#else - /* one segment, autoreq "all-but-last" */ - val |= ((0x1) << (rx->index * 2)); -#endif - } - - if (val != tmp) { - int n = 100; - - /* make sure that autoreq is updated before continuing */ - musb_writel(tibase, DAVINCI_AUTOREQ_REG, val); - do { - tmp = musb_readl(tibase, DAVINCI_AUTOREQ_REG); - if (tmp == val) - break; - cpu_relax(); - } while (n-- > 0); - } -#endif - - /* REQPKT is turned off after each segment */ - if (n_bds && rx->channel.actual_len) { - void __iomem *regs = rx->hw_ep->regs; - - val = musb_readw(regs, MUSB_RXCSR); - if (!(val & MUSB_RXCSR_H_REQPKT)) { - val |= MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_H_WZC_BITS; - musb_writew(regs, MUSB_RXCSR, val); - /* flush writebuffer */ - val = musb_readw(regs, MUSB_RXCSR); - } - } - return n_bds; -} - - -/* Buffer enqueuing Logic: - * - * - RX builds new queues each time, to help handle routine "early - * termination" cases (faults, including errors and short reads) - * more correctly. - * - * - for now, TX reuses the same queue of BDs every time - * - * REVISIT long term, we want a normal dynamic model. - * ... the goal will be to append to the - * existing queue, processing completed "dma buffers" (segments) on the fly. - * - * Otherwise we force an IRQ latency between requests, which slows us a lot - * (especially in "transparent" dma). Unfortunately that model seems to be - * inherent in the DMA model from the Mentor code, except in the rare case - * of transfers big enough (~128+ KB) that we could append "middle" segments - * in the TX paths. (RX can't do this, see below.) - * - * That's true even in the CPPI- friendly iso case, where most urbs have - * several small segments provided in a group and where the "packet at a time" - * "transparent" DMA model is always correct, even on the RX side. - */ - -/* - * CPPI TX: - * ======== - * TX is a lot more reasonable than RX; it doesn't need to run in - * irq-per-packet mode very often. RNDIS mode seems to behave too - * (except how it handles the exactly-N-packets case). Building a - * txdma queue with multiple requests (urb or usb_request) looks - * like it would work ... but fault handling would need much testing. - * - * The main issue with TX mode RNDIS relates to transfer lengths that - * are an exact multiple of the packet length. It appears that there's - * a hiccup in that case (maybe the DMA completes before the ZLP gets - * written?) boiling down to not being able to rely on CPPI writing any - * terminating zero length packet before the next transfer is written. - * So that's punted to PIO; better yet, gadget drivers can avoid it. - * - * Plus, there's allegedly an undocumented constraint that rndis transfer - * length be a multiple of 64 bytes ... but the chip doesn't act that - * way, and we really don't _want_ that behavior anyway. - * - * On TX, "transparent" mode works ... although experiments have shown - * problems trying to use the SOP/EOP bits in different USB packets. - * - * REVISIT try to handle terminating zero length packets using CPPI - * instead of doing it by PIO after an IRQ. (Meanwhile, make Ethernet - * links avoid that issue by forcing them to avoid zlps.) - */ -static void -cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) -{ - unsigned maxpacket = tx->maxpacket; - dma_addr_t addr = tx->buf_dma + tx->offset; - size_t length = tx->buf_len - tx->offset; - struct cppi_descriptor *bd; - unsigned n_bds; - unsigned i; - struct cppi_tx_stateram __iomem *tx_ram = tx->state_ram; - int rndis; - - /* TX can use the CPPI "rndis" mode, where we can probably fit this - * transfer in one BD and one IRQ. The only time we would NOT want - * to use it is when hardware constraints prevent it, or if we'd - * trigger the "send a ZLP?" confusion. - */ - rndis = (maxpacket & 0x3f) == 0 - && length > maxpacket - && length < 0xffff - && (length % maxpacket) != 0; - - if (rndis) { - maxpacket = length; - n_bds = 1; - } else { - if (length) - n_bds = DIV_ROUND_UP(length, maxpacket); - else - n_bds = 1; - n_bds = min(n_bds, (unsigned) NUM_TXCHAN_BD); - length = min(n_bds * maxpacket, length); - } - - musb_dbg(musb, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u", - tx->index, - maxpacket, - rndis ? "rndis" : "transparent", - n_bds, - (unsigned long long)addr, length); - - cppi_rndis_update(tx, 0, musb->ctrl_base, rndis); - - /* assuming here that channel_program is called during - * transfer initiation ... current code maintains state - * for one outstanding request only (no queues, not even - * the implicit ones of an iso urb). - */ - - bd = tx->freelist; - tx->head = bd; - tx->last_processed = NULL; - - /* FIXME use BD pool like RX side does, and just queue - * the minimum number for this request. - */ - - /* Prepare queue of BDs first, then hand it to hardware. - * All BDs except maybe the last should be of full packet - * size; for RNDIS there _is_ only that last packet. - */ - for (i = 0; i < n_bds; ) { - if (++i < n_bds && bd->next) - bd->hw_next = bd->next->dma; - else - bd->hw_next = 0; - - bd->hw_bufp = tx->buf_dma + tx->offset; - - /* FIXME set EOP only on the last packet, - * SOP only on the first ... avoid IRQs - */ - if ((tx->offset + maxpacket) <= tx->buf_len) { - tx->offset += maxpacket; - bd->hw_off_len = maxpacket; - bd->hw_options = CPPI_SOP_SET | CPPI_EOP_SET - | CPPI_OWN_SET | maxpacket; - } else { - /* only this one may be a partial USB Packet */ - u32 partial_len; - - partial_len = tx->buf_len - tx->offset; - tx->offset = tx->buf_len; - bd->hw_off_len = partial_len; - - bd->hw_options = CPPI_SOP_SET | CPPI_EOP_SET - | CPPI_OWN_SET | partial_len; - if (partial_len == 0) - bd->hw_options |= CPPI_ZERO_SET; - } - - musb_dbg(musb, "TXBD %p: nxt %08x buf %08x len %04x opt %08x", - bd, bd->hw_next, bd->hw_bufp, - bd->hw_off_len, bd->hw_options); - - /* update the last BD enqueued to the list */ - tx->tail = bd; - bd = bd->next; - } - - /* BDs live in DMA-coherent memory, but writes might be pending */ - cpu_drain_writebuffer(); - - /* Write to the HeadPtr in state RAM to trigger */ - musb_writel(&tx_ram->tx_head, 0, (u32)tx->freelist->dma); - - cppi_dump_tx(5, tx, "/S"); -} - -/* - * CPPI RX Woes: - * ============= - * Consider a 1KB bulk RX buffer in two scenarios: (a) it's fed two 300 byte - * packets back-to-back, and (b) it's fed two 512 byte packets back-to-back. - * (Full speed transfers have similar scenarios.) - * - * The correct behavior for Linux is that (a) fills the buffer with 300 bytes, - * and the next packet goes into a buffer that's queued later; while (b) fills - * the buffer with 1024 bytes. How to do that with CPPI? - * - * - RX queues in "rndis" mode -- one single BD -- handle (a) correctly, but - * (b) loses **BADLY** because nothing (!) happens when that second packet - * fills the buffer, much less when a third one arrives. (Which makes this - * not a "true" RNDIS mode. In the RNDIS protocol short-packet termination - * is optional, and it's fine if peripherals -- not hosts! -- pad messages - * out to end-of-buffer. Standard PCI host controller DMA descriptors - * implement that mode by default ... which is no accident.) - * - * - RX queues in "transparent" mode -- two BDs with 512 bytes each -- have - * converse problems: (b) is handled right, but (a) loses badly. CPPI RX - * ignores SOP/EOP markings and processes both of those BDs; so both packets - * are loaded into the buffer (with a 212 byte gap between them), and the next - * buffer queued will NOT get its 300 bytes of data. (It seems like SOP/EOP - * are intended as outputs for RX queues, not inputs...) - * - * - A variant of "transparent" mode -- one BD at a time -- is the only way to - * reliably make both cases work, with software handling both cases correctly - * and at the significant penalty of needing an IRQ per packet. (The lack of - * I/O overlap can be slightly ameliorated by enabling double buffering.) - * - * So how to get rid of IRQ-per-packet? The transparent multi-BD case could - * be used in special cases like mass storage, which sets URB_SHORT_NOT_OK - * (or maybe its peripheral side counterpart) to flag (a) scenarios as errors - * with guaranteed driver level fault recovery and scrubbing out what's left - * of that garbaged datastream. - * - * But there seems to be no way to identify the cases where CPPI RNDIS mode - * is appropriate -- which do NOT include RNDIS host drivers, but do include - * the CDC Ethernet driver! -- and the documentation is incomplete/wrong. - * So we can't _ever_ use RX RNDIS mode ... except by using a heuristic - * that applies best on the peripheral side (and which could fail rudely). - * - * Leaving only "transparent" mode; we avoid multi-bd modes in almost all - * cases other than mass storage class. Otherwise we're correct but slow, - * since CPPI penalizes our need for a "true RNDIS" default mode. - */ - - -/* Heuristic, intended to kick in for ethernet/rndis peripheral ONLY - * - * IFF - * (a) peripheral mode ... since rndis peripherals could pad their - * writes to hosts, causing i/o failure; or we'd have to cope with - * a largely unknowable variety of host side protocol variants - * (b) and short reads are NOT errors ... since full reads would - * cause those same i/o failures - * (c) and read length is - * - less than 64KB (max per cppi descriptor) - * - not a multiple of 4096 (g_zero default, full reads typical) - * - N (>1) packets long, ditto (full reads not EXPECTED) - * THEN - * try rx rndis mode - * - * Cost of heuristic failing: RXDMA wedges at the end of transfers that - * fill out the whole buffer. Buggy host side usb network drivers could - * trigger that, but "in the field" such bugs seem to be all but unknown. - * - * So this module parameter lets the heuristic be disabled. When using - * gadgetfs, the heuristic will probably need to be disabled. - */ -static bool cppi_rx_rndis = 1; - -module_param(cppi_rx_rndis, bool, 0); -MODULE_PARM_DESC(cppi_rx_rndis, "enable/disable RX RNDIS heuristic"); - - -/** - * cppi_next_rx_segment - dma read for the next chunk of a buffer - * @musb: the controller - * @rx: dma channel - * @onepacket: true unless caller treats short reads as errors, and - * performs fault recovery above usbcore. - * Context: controller irqlocked - * - * See above notes about why we can't use multi-BD RX queues except in - * rare cases (mass storage class), and can never use the hardware "rndis" - * mode (since it's not a "true" RNDIS mode) with complete safety.. - * - * It's ESSENTIAL that callers specify "onepacket" mode unless they kick in - * code to recover from corrupted datastreams after each short transfer. - */ -static void -cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) -{ - unsigned maxpacket = rx->maxpacket; - dma_addr_t addr = rx->buf_dma + rx->offset; - size_t length = rx->buf_len - rx->offset; - struct cppi_descriptor *bd, *tail; - unsigned n_bds; - unsigned i; - void __iomem *tibase = musb->ctrl_base; - int is_rndis = 0; - struct cppi_rx_stateram __iomem *rx_ram = rx->state_ram; - struct cppi_descriptor *d; - - if (onepacket) { - /* almost every USB driver, host or peripheral side */ - n_bds = 1; - - /* maybe apply the heuristic above */ - if (cppi_rx_rndis - && is_peripheral_active(musb) - && length > maxpacket - && (length & ~0xffff) == 0 - && (length & 0x0fff) != 0 - && (length & (maxpacket - 1)) == 0) { - maxpacket = length; - is_rndis = 1; - } - } else { - /* virtually nothing except mass storage class */ - if (length > 0xffff) { - n_bds = 0xffff / maxpacket; - length = n_bds * maxpacket; - } else { - n_bds = DIV_ROUND_UP(length, maxpacket); - } - if (n_bds == 1) - onepacket = 1; - else - n_bds = min(n_bds, (unsigned) NUM_RXCHAN_BD); - } - - /* In host mode, autorequest logic can generate some IN tokens; it's - * tricky since we can't leave REQPKT set in RXCSR after the transfer - * finishes. So: multipacket transfers involve two or more segments. - * And always at least two IRQs ... RNDIS mode is not an option. - */ - if (is_host_active(musb)) - n_bds = cppi_autoreq_update(rx, tibase, onepacket, n_bds); - - cppi_rndis_update(rx, 1, musb->ctrl_base, is_rndis); - - length = min(n_bds * maxpacket, length); - - musb_dbg(musb, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " - "dma 0x%llx len %u %u/%u", - rx->index, maxpacket, - onepacket - ? (is_rndis ? "rndis" : "onepacket") - : "multipacket", - n_bds, - musb_readl(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) - & 0xffff, - (unsigned long long)addr, length, - rx->channel.actual_len, rx->buf_len); - - /* only queue one segment at a time, since the hardware prevents - * correct queue shutdown after unexpected short packets - */ - bd = cppi_bd_alloc(rx); - rx->head = bd; - - /* Build BDs for all packets in this segment */ - for (i = 0, tail = NULL; bd && i < n_bds; i++, tail = bd) { - u32 bd_len; - - if (i) { - bd = cppi_bd_alloc(rx); - if (!bd) - break; - tail->next = bd; - tail->hw_next = bd->dma; - } - bd->hw_next = 0; - - /* all but the last packet will be maxpacket size */ - if (maxpacket < length) - bd_len = maxpacket; - else - bd_len = length; - - bd->hw_bufp = addr; - addr += bd_len; - rx->offset += bd_len; - - bd->hw_off_len = (0 /*offset*/ << 16) + bd_len; - bd->buflen = bd_len; - - bd->hw_options = CPPI_OWN_SET | (i == 0 ? length : 0); - length -= bd_len; - } - - /* we always expect at least one reusable BD! */ - if (!tail) { - WARNING("rx dma%d -- no BDs? need %d\n", rx->index, n_bds); - return; - } else if (i < n_bds) - WARNING("rx dma%d -- only %d of %d BDs\n", rx->index, i, n_bds); - - tail->next = NULL; - tail->hw_next = 0; - - bd = rx->head; - rx->tail = tail; - - /* short reads and other faults should terminate this entire - * dma segment. we want one "dma packet" per dma segment, not - * one per USB packet, terminating the whole queue at once... - * NOTE that current hardware seems to ignore SOP and EOP. - */ - bd->hw_options |= CPPI_SOP_SET; - tail->hw_options |= CPPI_EOP_SET; - - for (d = rx->head; d; d = d->next) - cppi_dump_rxbd("S", d); - - /* in case the preceding transfer left some state... */ - tail = rx->last_processed; - if (tail) { - tail->next = bd; - tail->hw_next = bd->dma; - } - - core_rxirq_enable(tibase, rx->index + 1); - - /* BDs live in DMA-coherent memory, but writes might be pending */ - cpu_drain_writebuffer(); - - /* REVISIT specs say to write this AFTER the BUFCNT register - * below ... but that loses badly. - */ - musb_writel(&rx_ram->rx_head, 0, bd->dma); - - /* bufferCount must be at least 3, and zeroes on completion - * unless it underflows below zero, or stops at two, or keeps - * growing ... grr. - */ - i = musb_readl(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) - & 0xffff; - - if (!i) - musb_writel(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4), - n_bds + 2); - else if (n_bds > (i - 3)) - musb_writel(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4), - n_bds - (i - 3)); - - i = musb_readl(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) - & 0xffff; - if (i < (2 + n_bds)) { - musb_dbg(musb, "bufcnt%d underrun - %d (for %d)", - rx->index, i, n_bds); - musb_writel(tibase, - DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4), - n_bds + 2); - } - - cppi_dump_rx(4, rx, "/S"); -} - -/** - * cppi_channel_program - program channel for data transfer - * @ch: the channel - * @maxpacket: max packet size - * @mode: For RX, 1 unless the usb protocol driver promised to treat - * all short reads as errors and kick in high level fault recovery. - * For TX, ignored because of RNDIS mode races/glitches. - * @dma_addr: dma address of buffer - * @len: length of buffer - * Context: controller irqlocked - */ -static int cppi_channel_program(struct dma_channel *ch, - u16 maxpacket, u8 mode, - dma_addr_t dma_addr, u32 len) -{ - struct cppi_channel *cppi_ch; - struct cppi *controller; - struct musb *musb; - - cppi_ch = container_of(ch, struct cppi_channel, channel); - controller = cppi_ch->controller; - musb = controller->controller.musb; - - switch (ch->status) { - case MUSB_DMA_STATUS_BUS_ABORT: - case MUSB_DMA_STATUS_CORE_ABORT: - /* fault irq handler should have handled cleanup */ - WARNING("%cX DMA%d not cleaned up after abort!\n", - cppi_ch->transmit ? 'T' : 'R', - cppi_ch->index); - /* WARN_ON(1); */ - break; - case MUSB_DMA_STATUS_BUSY: - WARNING("program active channel? %cX DMA%d\n", - cppi_ch->transmit ? 'T' : 'R', - cppi_ch->index); - /* WARN_ON(1); */ - break; - case MUSB_DMA_STATUS_UNKNOWN: - musb_dbg(musb, "%cX DMA%d not allocated!", - cppi_ch->transmit ? 'T' : 'R', - cppi_ch->index); - fallthrough; - case MUSB_DMA_STATUS_FREE: - break; - } - - ch->status = MUSB_DMA_STATUS_BUSY; - - /* set transfer parameters, then queue up its first segment */ - cppi_ch->buf_dma = dma_addr; - cppi_ch->offset = 0; - cppi_ch->maxpacket = maxpacket; - cppi_ch->buf_len = len; - cppi_ch->channel.actual_len = 0; - - /* TX channel? or RX? */ - if (cppi_ch->transmit) - cppi_next_tx_segment(musb, cppi_ch); - else - cppi_next_rx_segment(musb, cppi_ch, mode); - - return true; -} - -static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) -{ - struct cppi_channel *rx = &cppi->rx[ch]; - struct cppi_rx_stateram __iomem *state = rx->state_ram; - struct cppi_descriptor *bd; - struct cppi_descriptor *last = rx->last_processed; - bool completed = false; - bool acked = false; - int i; - dma_addr_t safe2ack; - void __iomem *regs = rx->hw_ep->regs; - struct musb *musb = cppi->controller.musb; - - cppi_dump_rx(6, rx, "/K"); - - bd = last ? last->next : rx->head; - if (!bd) - return false; - - /* run through all completed BDs */ - for (i = 0, safe2ack = musb_readl(&state->rx_complete, 0); - (safe2ack || completed) && bd && i < NUM_RXCHAN_BD; - i++, bd = bd->next) { - u16 len; - - /* catch latest BD writes from CPPI */ - rmb(); - if (!completed && (bd->hw_options & CPPI_OWN_SET)) - break; - - musb_dbg(musb, "C/RXBD %llx: nxt %08x buf %08x " - "off.len %08x opt.len %08x (%d)", - (unsigned long long)bd->dma, bd->hw_next, bd->hw_bufp, - bd->hw_off_len, bd->hw_options, - rx->channel.actual_len); - - /* actual packet received length */ - if ((bd->hw_options & CPPI_SOP_SET) && !completed) - len = bd->hw_off_len & CPPI_RECV_PKTLEN_MASK; - else - len = 0; - - if (bd->hw_options & CPPI_EOQ_MASK) - completed = true; - - if (!completed && len < bd->buflen) { - /* NOTE: when we get a short packet, RXCSR_H_REQPKT - * must have been cleared, and no more DMA packets may - * active be in the queue... TI docs didn't say, but - * CPPI ignores those BDs even though OWN is still set. - */ - completed = true; - musb_dbg(musb, "rx short %d/%d (%d)", - len, bd->buflen, - rx->channel.actual_len); - } - - /* If we got here, we expect to ack at least one BD; meanwhile - * CPPI may completing other BDs while we scan this list... - * - * RACE: we can notice OWN cleared before CPPI raises the - * matching irq by writing that BD as the completion pointer. - * In such cases, stop scanning and wait for the irq, avoiding - * lost acks and states where BD ownership is unclear. - */ - if (bd->dma == safe2ack) { - musb_writel(&state->rx_complete, 0, safe2ack); - safe2ack = musb_readl(&state->rx_complete, 0); - acked = true; - if (bd->dma == safe2ack) - safe2ack = 0; - } - - rx->channel.actual_len += len; - - cppi_bd_free(rx, last); - last = bd; - - /* stop scanning on end-of-segment */ - if (bd->hw_next == 0) - completed = true; - } - rx->last_processed = last; - - /* dma abort, lost ack, or ... */ - if (!acked && last) { - int csr; - - if (safe2ack == 0 || safe2ack == rx->last_processed->dma) - musb_writel(&state->rx_complete, 0, safe2ack); - if (safe2ack == 0) { - cppi_bd_free(rx, last); - rx->last_processed = NULL; - - /* if we land here on the host side, H_REQPKT will - * be clear and we need to restart the queue... - */ - WARN_ON(rx->head); - } - musb_ep_select(cppi->mregs, rx->index + 1); - csr = musb_readw(regs, MUSB_RXCSR); - if (csr & MUSB_RXCSR_DMAENAB) { - musb_dbg(musb, "list%d %p/%p, last %llx%s, csr %04x", - rx->index, - rx->head, rx->tail, - rx->last_processed - ? (unsigned long long) - rx->last_processed->dma - : 0, - completed ? ", completed" : "", - csr); - cppi_dump_rxq(4, "/what?", rx); - } - } - if (!completed) { - int csr; - - rx->head = bd; - - /* REVISIT seems like "autoreq all but EOP" doesn't... - * setting it here "should" be racey, but seems to work - */ - csr = musb_readw(rx->hw_ep->regs, MUSB_RXCSR); - if (is_host_active(cppi->controller.musb) - && bd - && !(csr & MUSB_RXCSR_H_REQPKT)) { - csr |= MUSB_RXCSR_H_REQPKT; - musb_writew(regs, MUSB_RXCSR, - MUSB_RXCSR_H_WZC_BITS | csr); - csr = musb_readw(rx->hw_ep->regs, MUSB_RXCSR); - } - } else { - rx->head = NULL; - rx->tail = NULL; - } - - cppi_dump_rx(6, rx, completed ? "/completed" : "/cleaned"); - return completed; -} - -irqreturn_t cppi_interrupt(int irq, void *dev_id) -{ - struct musb *musb = dev_id; - struct cppi *cppi; - void __iomem *tibase; - struct musb_hw_ep *hw_ep = NULL; - u32 rx, tx; - int i, index; - unsigned long flags; - - cppi = container_of(musb->dma_controller, struct cppi, controller); - if (cppi->irq) - spin_lock_irqsave(&musb->lock, flags); - - tibase = musb->ctrl_base; - - tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); - rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); - - if (!tx && !rx) { - if (cppi->irq) - spin_unlock_irqrestore(&musb->lock, flags); - return IRQ_NONE; - } - - musb_dbg(musb, "CPPI IRQ Tx%x Rx%x", tx, rx); - - /* process TX channels */ - for (index = 0; tx; tx = tx >> 1, index++) { - struct cppi_channel *tx_ch; - struct cppi_tx_stateram __iomem *tx_ram; - bool completed = false; - struct cppi_descriptor *bd; - - if (!(tx & 1)) - continue; - - tx_ch = cppi->tx + index; - tx_ram = tx_ch->state_ram; - - /* FIXME need a cppi_tx_scan() routine, which - * can also be called from abort code - */ - - cppi_dump_tx(5, tx_ch, "/E"); - - bd = tx_ch->head; - - /* - * If Head is null then this could mean that a abort interrupt - * that needs to be acknowledged. - */ - if (NULL == bd) { - musb_dbg(musb, "null BD"); - musb_writel(&tx_ram->tx_complete, 0, 0); - continue; - } - - /* run through all completed BDs */ - for (i = 0; !completed && bd && i < NUM_TXCHAN_BD; - i++, bd = bd->next) { - u16 len; - - /* catch latest BD writes from CPPI */ - rmb(); - if (bd->hw_options & CPPI_OWN_SET) - break; - - musb_dbg(musb, "C/TXBD %p n %x b %x off %x opt %x", - bd, bd->hw_next, bd->hw_bufp, - bd->hw_off_len, bd->hw_options); - - len = bd->hw_off_len & CPPI_BUFFER_LEN_MASK; - tx_ch->channel.actual_len += len; - - tx_ch->last_processed = bd; - - /* write completion register to acknowledge - * processing of completed BDs, and possibly - * release the IRQ; EOQ might not be set ... - * - * REVISIT use the same ack strategy as rx - * - * REVISIT have observed bit 18 set; huh?? - */ - /* if ((bd->hw_options & CPPI_EOQ_MASK)) */ - musb_writel(&tx_ram->tx_complete, 0, bd->dma); - - /* stop scanning on end-of-segment */ - if (bd->hw_next == 0) - completed = true; - } - - /* on end of segment, maybe go to next one */ - if (completed) { - /* cppi_dump_tx(4, tx_ch, "/complete"); */ - - /* transfer more, or report completion */ - if (tx_ch->offset >= tx_ch->buf_len) { - tx_ch->head = NULL; - tx_ch->tail = NULL; - tx_ch->channel.status = MUSB_DMA_STATUS_FREE; - - hw_ep = tx_ch->hw_ep; - - musb_dma_completion(musb, index + 1, 1); - - } else { - /* Bigger transfer than we could fit in - * that first batch of descriptors... - */ - cppi_next_tx_segment(musb, tx_ch); - } - } else - tx_ch->head = bd; - } - - /* Start processing the RX block */ - for (index = 0; rx; rx = rx >> 1, index++) { - - if (rx & 1) { - struct cppi_channel *rx_ch; - - rx_ch = cppi->rx + index; - - /* let incomplete dma segments finish */ - if (!cppi_rx_scan(cppi, index)) - continue; - - /* start another dma segment if needed */ - if (rx_ch->channel.actual_len != rx_ch->buf_len - && rx_ch->channel.actual_len - == rx_ch->offset) { - cppi_next_rx_segment(musb, rx_ch, 1); - continue; - } - - /* all segments completed! */ - rx_ch->channel.status = MUSB_DMA_STATUS_FREE; - - hw_ep = rx_ch->hw_ep; - - core_rxirq_disable(tibase, index + 1); - musb_dma_completion(musb, index + 1, 0); - } - } - - /* write to CPPI EOI register to re-enable interrupts */ - musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); - - if (cppi->irq) - spin_unlock_irqrestore(&musb->lock, flags); - - return IRQ_HANDLED; -} -EXPORT_SYMBOL_GPL(cppi_interrupt); - -/* Instantiate a software object representing a DMA controller. */ -struct dma_controller * -cppi_dma_controller_create(struct musb *musb, void __iomem *mregs) -{ - struct cppi *controller; - struct device *dev = musb->controller; - struct platform_device *pdev = to_platform_device(dev); - int irq = platform_get_irq_byname(pdev, "dma"); - - controller = kzalloc(sizeof *controller, GFP_KERNEL); - if (!controller) - return NULL; - - controller->mregs = mregs; - controller->tibase = mregs - DAVINCI_BASE_OFFSET; - - controller->controller.musb = musb; - controller->controller.channel_alloc = cppi_channel_allocate; - controller->controller.channel_release = cppi_channel_release; - controller->controller.channel_program = cppi_channel_program; - controller->controller.channel_abort = cppi_channel_abort; - - /* NOTE: allocating from on-chip SRAM would give the least - * contention for memory access, if that ever matters here. - */ - - /* setup BufferPool */ - controller->pool = dma_pool_create("cppi", - controller->controller.musb->controller, - sizeof(struct cppi_descriptor), - CPPI_DESCRIPTOR_ALIGN, 0); - if (!controller->pool) { - kfree(controller); - return NULL; - } - - if (irq > 0) { - if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) { - dev_err(dev, "request_irq %d failed!\n", irq); - musb_dma_controller_destroy(&controller->controller); - return NULL; - } - controller->irq = irq; - } - - cppi_controller_start(controller); - return &controller->controller; -} -EXPORT_SYMBOL_GPL(cppi_dma_controller_create); - -/* - * Destroy a previously-instantiated DMA controller. - */ -void cppi_dma_controller_destroy(struct dma_controller *c) -{ - struct cppi *cppi; - - cppi = container_of(c, struct cppi, controller); - - cppi_controller_stop(cppi); - - if (cppi->irq) - free_irq(cppi->irq, cppi->controller.musb); - - /* assert: caller stopped the controller first */ - dma_pool_destroy(cppi->pool); - - kfree(cppi); -} -EXPORT_SYMBOL_GPL(cppi_dma_controller_destroy); - -/* - * Context: controller irqlocked, endpoint selected - */ -static int cppi_channel_abort(struct dma_channel *channel) -{ - struct cppi_channel *cppi_ch; - struct cppi *controller; - void __iomem *mbase; - void __iomem *tibase; - void __iomem *regs; - u32 value; - struct cppi_descriptor *queue; - - cppi_ch = container_of(channel, struct cppi_channel, channel); - - controller = cppi_ch->controller; - - switch (channel->status) { - case MUSB_DMA_STATUS_BUS_ABORT: - case MUSB_DMA_STATUS_CORE_ABORT: - /* from RX or TX fault irq handler */ - case MUSB_DMA_STATUS_BUSY: - /* the hardware needs shutting down */ - regs = cppi_ch->hw_ep->regs; - break; - case MUSB_DMA_STATUS_UNKNOWN: - case MUSB_DMA_STATUS_FREE: - return 0; - default: - return -EINVAL; - } - - if (!cppi_ch->transmit && cppi_ch->head) - cppi_dump_rxq(3, "/abort", cppi_ch); - - mbase = controller->mregs; - tibase = controller->tibase; - - queue = cppi_ch->head; - cppi_ch->head = NULL; - cppi_ch->tail = NULL; - - /* REVISIT should rely on caller having done this, - * and caller should rely on us not changing it. - * peripheral code is safe ... check host too. - */ - musb_ep_select(mbase, cppi_ch->index + 1); - - if (cppi_ch->transmit) { - struct cppi_tx_stateram __iomem *tx_ram; - /* REVISIT put timeouts on these controller handshakes */ - - cppi_dump_tx(6, cppi_ch, " (teardown)"); - - /* teardown DMA engine then usb core */ - do { - value = musb_readl(tibase, DAVINCI_TXCPPI_TEAR_REG); - } while (!(value & CPPI_TEAR_READY)); - musb_writel(tibase, DAVINCI_TXCPPI_TEAR_REG, cppi_ch->index); - - tx_ram = cppi_ch->state_ram; - do { - value = musb_readl(&tx_ram->tx_complete, 0); - } while (0xFFFFFFFC != value); - - /* FIXME clean up the transfer state ... here? - * the completion routine should get called with - * an appropriate status code. - */ - - value = musb_readw(regs, MUSB_TXCSR); - value &= ~MUSB_TXCSR_DMAENAB; - value |= MUSB_TXCSR_FLUSHFIFO; - musb_writew(regs, MUSB_TXCSR, value); - musb_writew(regs, MUSB_TXCSR, value); - - /* - * 1. Write to completion Ptr value 0x1(bit 0 set) - * (write back mode) - * 2. Wait for abort interrupt and then put the channel in - * compare mode by writing 1 to the tx_complete register. - */ - cppi_reset_tx(tx_ram, 1); - cppi_ch->head = NULL; - musb_writel(&tx_ram->tx_complete, 0, 1); - cppi_dump_tx(5, cppi_ch, " (done teardown)"); - - /* REVISIT tx side _should_ clean up the same way - * as the RX side ... this does no cleanup at all! - */ - - } else /* RX */ { - u16 csr; - - /* NOTE: docs don't guarantee any of this works ... we - * expect that if the usb core stops telling the cppi core - * to pull more data from it, then it'll be safe to flush - * current RX DMA state iff any pending fifo transfer is done. - */ - - core_rxirq_disable(tibase, cppi_ch->index + 1); - - /* for host, ensure ReqPkt is never set again */ - if (is_host_active(cppi_ch->controller->controller.musb)) { - value = musb_readl(tibase, DAVINCI_AUTOREQ_REG); - value &= ~((0x3) << (cppi_ch->index * 2)); - musb_writel(tibase, DAVINCI_AUTOREQ_REG, value); - } - - csr = musb_readw(regs, MUSB_RXCSR); - - /* for host, clear (just) ReqPkt at end of current packet(s) */ - if (is_host_active(cppi_ch->controller->controller.musb)) { - csr |= MUSB_RXCSR_H_WZC_BITS; - csr &= ~MUSB_RXCSR_H_REQPKT; - } else - csr |= MUSB_RXCSR_P_WZC_BITS; - - /* clear dma enable */ - csr &= ~(MUSB_RXCSR_DMAENAB); - musb_writew(regs, MUSB_RXCSR, csr); - csr = musb_readw(regs, MUSB_RXCSR); - - /* Quiesce: wait for current dma to finish (if not cleanup). - * We can't use bit zero of stateram->rx_sop, since that - * refers to an entire "DMA packet" not just emptying the - * current fifo. Most segments need multiple usb packets. - */ - if (channel->status == MUSB_DMA_STATUS_BUSY) - udelay(50); - - /* scan the current list, reporting any data that was - * transferred and acking any IRQ - */ - cppi_rx_scan(controller, cppi_ch->index); - - /* clobber the existing state once it's idle - * - * NOTE: arguably, we should also wait for all the other - * RX channels to quiesce (how??) and then temporarily - * disable RXCPPI_CTRL_REG ... but it seems that we can - * rely on the controller restarting from state ram, with - * only RXCPPI_BUFCNT state being bogus. BUFCNT will - * correct itself after the next DMA transfer though. - * - * REVISIT does using rndis mode change that? - */ - cppi_reset_rx(cppi_ch->state_ram); - - /* next DMA request _should_ load cppi head ptr */ - - /* ... we don't "free" that list, only mutate it in place. */ - cppi_dump_rx(5, cppi_ch, " (done abort)"); - - /* clean up previously pending bds */ - cppi_bd_free(cppi_ch, cppi_ch->last_processed); - cppi_ch->last_processed = NULL; - - while (queue) { - struct cppi_descriptor *tmp = queue->next; - - cppi_bd_free(cppi_ch, queue); - queue = tmp; - } - } - - channel->status = MUSB_DMA_STATUS_FREE; - cppi_ch->buf_dma = 0; - cppi_ch->offset = 0; - cppi_ch->buf_len = 0; - cppi_ch->maxpacket = 0; - return 0; -} - -/* TBD Queries: - * - * Power Management ... probably turn off cppi during suspend, restart; - * check state ram? Clocking is presumably shared with usb core. - */ diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c deleted file mode 100644 index 7044355263943..0000000000000 --- a/drivers/usb/musb/davinci.c +++ /dev/null @@ -1,606 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2005-2006 by Texas Instruments - * - * This file is part of the Inventra Controller Driver for Linux. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "musb_core.h" - -#include "davinci.h" -#include "cppi_dma.h" - - -#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) -#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) - -struct davinci_glue { - struct device *dev; - struct platform_device *musb; - struct clk *clk; - bool vbus_state; - struct gpio_desc *vbus; - struct work_struct vbus_work; -}; - -/* REVISIT (PM) we should be able to keep the PHY in low power mode most - * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 - * and, when in host mode, autosuspending idle root ports... PHYPLLON - * (overriding SUSPENDM?) then likely needs to stay off. - */ - -static inline void phy_on(void) -{ - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - /* power everything up; start the on-chip PHY and its PLL */ - phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); - phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; - __raw_writel(phy_ctrl, USB_PHY_CTRL); - - /* wait for PLL to lock before proceeding */ - while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0) - cpu_relax(); -} - -static inline void phy_off(void) -{ - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - /* powerdown the on-chip PHY, its PLL, and the OTG block */ - phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON); - phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN; - __raw_writel(phy_ctrl, USB_PHY_CTRL); -} - -static int dma_off = 1; - -static void davinci_musb_enable(struct musb *musb) -{ - u32 tmp, old, val; - - /* workaround: setup irqs through both register sets */ - tmp = (musb->epmask & DAVINCI_USB_TX_ENDPTS_MASK) - << DAVINCI_USB_TXINT_SHIFT; - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp); - old = tmp; - tmp = (musb->epmask & (0xfffe & DAVINCI_USB_RX_ENDPTS_MASK)) - << DAVINCI_USB_RXINT_SHIFT; - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp); - tmp |= old; - - val = ~MUSB_INTR_SOF; - tmp |= ((val & 0x01ff) << DAVINCI_USB_USBINT_SHIFT); - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp); - - if (is_dma_capable() && !dma_off) - printk(KERN_WARNING "%s %s: dma not reactivated\n", - __FILE__, __func__); - else - dma_off = 0; - - /* force a DRVVBUS irq so we can start polling for ID change */ - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, - DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT); -} - -/* - * Disable the HDRC and flush interrupts - */ -static void davinci_musb_disable(struct musb *musb) -{ - /* because we don't set CTRLR.UINT, "important" to: - * - not read/write INTRUSB/INTRUSBE - * - (except during initial setup, as workaround) - * - use INTSETR/INTCLRR instead - */ - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG, - DAVINCI_USB_USBINT_MASK - | DAVINCI_USB_TXINT_MASK - | DAVINCI_USB_RXINT_MASK); - musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0); - - if (is_dma_capable() && !dma_off) - WARNING("dma still active\n"); -} - - -#define portstate(stmt) stmt - -/* - * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM, - * which doesn't wire DRVVBUS to the FET that switches it. Unclear - * if that's a problem with the DM6446 chip or just with that board. - * - * In either case, the DM355 EVM automates DRVVBUS the normal way, - * when J10 is out, and TI documents it as handling OTG. - */ - -/* I2C operations are always synchronous, and require a task context. - * With unloaded systems, using the shared workqueue seems to suffice - * to satisfy the 100msec A_WAIT_VRISE timeout... - */ -static void evm_deferred_drvvbus(struct work_struct *work) -{ - struct davinci_glue *glue = container_of(work, struct davinci_glue, - vbus_work); - - gpiod_set_value_cansleep(glue->vbus, glue->vbus_state); - glue->vbus_state = !glue->vbus_state; -} - -static void davinci_musb_source_power(struct musb *musb, int is_on, - int immediate) -{ - struct davinci_glue *glue = dev_get_drvdata(musb->controller->parent); - - /* This GPIO handling is entirely optional */ - if (!glue->vbus) - return; - - if (is_on) - is_on = 1; - - if (glue->vbus_state == is_on) - return; - /* 0/1 vs "-1 == unknown/init" */ - glue->vbus_state = !is_on; - - if (machine_is_davinci_evm()) { - if (immediate) - gpiod_set_value_cansleep(glue->vbus, glue->vbus_state); - else - schedule_work(&glue->vbus_work); - } - if (immediate) - glue->vbus_state = is_on; -} - -static void davinci_musb_set_vbus(struct musb *musb, int is_on) -{ - WARN_ON(is_on && is_peripheral_active(musb)); - davinci_musb_source_power(musb, is_on, 0); -} - - -#define POLL_SECONDS 2 - -static void otg_timer(struct timer_list *t) -{ - struct musb *musb = from_timer(musb, t, dev_timer); - void __iomem *mregs = musb->mregs; - u8 devctl; - unsigned long flags; - - /* We poll because DaVinci's won't expose several OTG-critical - * status change events (from the transceiver) otherwise. - */ - devctl = musb_readb(mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->otg->state)); - - spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->otg->state) { - case OTG_STATE_A_WAIT_VFALL: - /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL - * seems to mis-handle session "start" otherwise (or in our - * case "recover"), in routine "VBUS was valid by the time - * VBUSERR got reported during enumeration" cases. - */ - if (devctl & MUSB_DEVCTL_VBUS) { - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - break; - } - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, - MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); - break; - case OTG_STATE_B_IDLE: - /* - * There's no ID-changed IRQ, so we have no good way to tell - * when to switch to the A-Default state machine (by setting - * the DEVCTL.SESSION flag). - * - * Workaround: whenever we're in B_IDLE, try setting the - * session flag every few seconds. If it works, ID was - * grounded and we're now in the A-Default state machine. - * - * NOTE setting the session flag is _supposed_ to trigger - * SRP, but clearly it doesn't. - */ - musb_writeb(mregs, MUSB_DEVCTL, - devctl | MUSB_DEVCTL_SESSION); - devctl = musb_readb(mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - else - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - break; - default: - break; - } - spin_unlock_irqrestore(&musb->lock, flags); -} - -static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) -{ - unsigned long flags; - irqreturn_t retval = IRQ_NONE; - struct musb *musb = __hci; - struct usb_otg *otg = musb->xceiv->otg; - void __iomem *tibase = musb->ctrl_base; - struct cppi *cppi; - u32 tmp; - - spin_lock_irqsave(&musb->lock, flags); - - /* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through - * the Mentor registers (except for setup), use the TI ones and EOI. - * - * Docs describe irq "vector" registers associated with the CPPI and - * USB EOI registers. These hold a bitmask corresponding to the - * current IRQ, not an irq handler address. Would using those bits - * resolve some of the races observed in this dispatch code?? - */ - - /* CPPI interrupts share the same IRQ line, but have their own - * mask, state, "vector", and EOI registers. - */ - cppi = container_of(musb->dma_controller, struct cppi, controller); - if (is_cppi_enabled(musb) && musb->dma_controller && !cppi->irq) - retval = cppi_interrupt(irq, __hci); - - /* ack and handle non-CPPI interrupts */ - tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); - musb_writel(tibase, DAVINCI_USB_INT_SRC_CLR_REG, tmp); - dev_dbg(musb->controller, "IRQ %08x\n", tmp); - - musb->int_rx = (tmp & DAVINCI_USB_RXINT_MASK) - >> DAVINCI_USB_RXINT_SHIFT; - musb->int_tx = (tmp & DAVINCI_USB_TXINT_MASK) - >> DAVINCI_USB_TXINT_SHIFT; - musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK) - >> DAVINCI_USB_USBINT_SHIFT; - - /* DRVVBUS irqs are the only proxy we have (a very poor one!) for - * DaVinci's missing ID change IRQ. We need an ID change IRQ to - * switch appropriately between halves of the OTG state machine. - * Managing DEVCTL.SESSION per Mentor docs requires we know its - * value, but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. - * Also, DRVVBUS pulses for SRP (but not at 5V) ... - */ - if (tmp & (DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT)) { - int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG); - void __iomem *mregs = musb->mregs; - u8 devctl = musb_readb(mregs, MUSB_DEVCTL); - int err = musb->int_usb & MUSB_INTR_VBUSERROR; - - err = musb->int_usb & MUSB_INTR_VBUSERROR; - if (err) { - /* The Mentor core doesn't debounce VBUS as needed - * to cope with device connect current spikes. This - * means it's not uncommon for bus-powered devices - * to get VBUS errors during enumeration. - * - * This is a workaround, but newer RTL from Mentor - * seems to allow a better one: "re"starting sessions - * without waiting (on EVM, a **long** time) for VBUS - * to stop registering in devctl. - */ - musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - WARNING("VBUS error workaround (delay coming)\n"); - } else if (drvvbus) { - MUSB_HST_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - portstate(musb->port1_status |= USB_PORT_STAT_POWER); - del_timer(&musb->dev_timer); - } else { - musb->is_active = 0; - MUSB_DEV_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); - } - - /* NOTE: this must complete poweron within 100 msec - * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. - */ - davinci_musb_source_power(musb, drvvbus, 0); - dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", - drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->otg->state), - err ? " ERROR" : "", - devctl); - retval = IRQ_HANDLED; - } - - if (musb->int_tx || musb->int_rx || musb->int_usb) - retval |= musb_interrupt(musb); - - /* irq stays asserted until EOI is written */ - musb_writel(tibase, DAVINCI_USB_EOI_REG, 0); - - /* poll for ID change */ - if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - - spin_unlock_irqrestore(&musb->lock, flags); - - return retval; -} - -static int davinci_musb_set_mode(struct musb *musb, u8 mode) -{ - /* EVM can't do this (right?) */ - return -EIO; -} - -static int davinci_musb_init(struct musb *musb) -{ - void __iomem *tibase = musb->ctrl_base; - u32 revision; - int ret = -ENODEV; - - musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(musb->xceiv)) { - ret = -EPROBE_DEFER; - goto unregister; - } - - musb->mregs += DAVINCI_BASE_OFFSET; - - /* returns zero if e.g. not clocked */ - revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); - if (revision == 0) - goto fail; - - timer_setup(&musb->dev_timer, otg_timer, 0); - - davinci_musb_source_power(musb, 0, 1); - - /* dm355 EVM swaps D+/D- for signal integrity, and - * is clocked from the main 24 MHz crystal. - */ - if (machine_is_davinci_dm355_evm()) { - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - phy_ctrl &= ~(3 << 9); - phy_ctrl |= USBPHY_DATAPOL; - __raw_writel(phy_ctrl, USB_PHY_CTRL); - } - - /* On dm355, the default-A state machine needs DRVVBUS control. - * If we won't be a host, there's no need to turn it on. - */ - if (cpu_is_davinci_dm355()) { - u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); - - deepsleep &= ~DRVVBUS_FORCE; - __raw_writel(deepsleep, DM355_DEEPSLEEP); - } - - /* reset the controller */ - musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); - - /* start the on-chip PHY and its PLL */ - phy_on(); - - msleep(5); - - /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ - pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", - revision, __raw_readl(USB_PHY_CTRL), - musb_readb(tibase, DAVINCI_USB_CTRL_REG)); - - musb->isr = davinci_musb_interrupt; - return 0; - -fail: - usb_put_phy(musb->xceiv); -unregister: - usb_phy_generic_unregister(); - return ret; -} - -static int davinci_musb_exit(struct musb *musb) -{ - int maxdelay = 30; - u8 devctl, warn = 0; - - del_timer_sync(&musb->dev_timer); - - /* force VBUS off */ - if (cpu_is_davinci_dm355()) { - u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); - - deepsleep &= ~DRVVBUS_FORCE; - deepsleep |= DRVVBUS_OVERRIDE; - __raw_writel(deepsleep, DM355_DEEPSLEEP); - } - - davinci_musb_source_power(musb, 0 /*off*/, 1); - - /* - * delay, to avoid problems with module reload. - * if there's no peripheral connected, this can take a - * long time to fall, especially on EVM with huge C133. - */ - do { - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (!(devctl & MUSB_DEVCTL_VBUS)) - break; - if ((devctl & MUSB_DEVCTL_VBUS) != warn) { - warn = devctl & MUSB_DEVCTL_VBUS; - dev_dbg(musb->controller, "VBUS %d\n", - warn >> MUSB_DEVCTL_VBUS_SHIFT); - } - msleep(1000); - maxdelay--; - } while (maxdelay > 0); - - /* in OTG mode, another host might be connected */ - if (devctl & MUSB_DEVCTL_VBUS) - dev_dbg(musb->controller, "VBUS off timeout (devctl %02x)\n", devctl); - - phy_off(); - - usb_put_phy(musb->xceiv); - - return 0; -} - -static const struct musb_platform_ops davinci_ops = { - .quirks = MUSB_DMA_CPPI, - .init = davinci_musb_init, - .exit = davinci_musb_exit, - -#ifdef CONFIG_USB_TI_CPPI_DMA - .dma_init = cppi_dma_controller_create, - .dma_exit = cppi_dma_controller_destroy, -#endif - .enable = davinci_musb_enable, - .disable = davinci_musb_disable, - - .set_mode = davinci_musb_set_mode, - - .set_vbus = davinci_musb_set_vbus, -}; - -static const struct platform_device_info davinci_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; - -static int davinci_probe(struct platform_device *pdev) -{ - struct resource musb_resources[3]; - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct davinci_glue *glue; - struct platform_device_info pinfo; - struct clk *clk; - - int ret = -ENOMEM; - - glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) - goto err0; - - clk = devm_clk_get(&pdev->dev, "usb"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); - ret = PTR_ERR(clk); - goto err0; - } - - ret = clk_enable(clk); - if (ret) { - dev_err(&pdev->dev, "failed to enable clock\n"); - goto err0; - } - - glue->dev = &pdev->dev; - glue->clk = clk; - - pdata->platform_ops = &davinci_ops; - - glue->vbus = devm_gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); - if (IS_ERR(glue->vbus)) { - ret = PTR_ERR(glue->vbus); - goto err0; - } else { - glue->vbus_state = -1; - INIT_WORK(&glue->vbus_work, evm_deferred_drvvbus); - } - - usb_phy_generic_register(); - platform_set_drvdata(pdev, glue); - - memset(musb_resources, 0x00, sizeof(*musb_resources) * - ARRAY_SIZE(musb_resources)); - - musb_resources[0].name = pdev->resource[0].name; - musb_resources[0].start = pdev->resource[0].start; - musb_resources[0].end = pdev->resource[0].end; - musb_resources[0].flags = pdev->resource[0].flags; - - musb_resources[1].name = pdev->resource[1].name; - musb_resources[1].start = pdev->resource[1].start; - musb_resources[1].end = pdev->resource[1].end; - musb_resources[1].flags = pdev->resource[1].flags; - - /* - * For DM6467 3 resources are passed. A placeholder for the 3rd - * resource is always there, so it's safe to always copy it... - */ - musb_resources[2].name = pdev->resource[2].name; - musb_resources[2].start = pdev->resource[2].start; - musb_resources[2].end = pdev->resource[2].end; - musb_resources[2].flags = pdev->resource[2].flags; - - pinfo = davinci_dev_info; - pinfo.parent = &pdev->dev; - pinfo.res = musb_resources; - pinfo.num_res = ARRAY_SIZE(musb_resources); - pinfo.data = pdata; - pinfo.size_data = sizeof(*pdata); - - glue->musb = musb = platform_device_register_full(&pinfo); - if (IS_ERR(musb)) { - ret = PTR_ERR(musb); - dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err1; - } - - return 0; - -err1: - clk_disable(clk); - -err0: - return ret; -} - -static int davinci_remove(struct platform_device *pdev) -{ - struct davinci_glue *glue = platform_get_drvdata(pdev); - - platform_device_unregister(glue->musb); - usb_phy_generic_unregister(); - clk_disable(glue->clk); - - return 0; -} - -static struct platform_driver davinci_driver = { - .probe = davinci_probe, - .remove = davinci_remove, - .driver = { - .name = "musb-davinci", - }, -}; - -MODULE_DESCRIPTION("DaVinci MUSB Glue Layer"); -MODULE_AUTHOR("Felipe Balbi "); -MODULE_LICENSE("GPL v2"); -module_platform_driver(davinci_driver); diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h deleted file mode 100644 index c8e67d15b510b..0000000000000 --- a/drivers/usb/musb/davinci.h +++ /dev/null @@ -1,103 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2005-2006 by Texas Instruments - */ - -#ifndef __MUSB_HDRDF_H__ -#define __MUSB_HDRDF_H__ - -/* - * DaVinci-specific definitions - */ - -/* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR 0x01c40034 -#define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ -#define USBPHY_PHYCLKGD BIT(8) -#define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ -#define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */ -#define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */ -#define USBPHY_PHYPLLON BIT(4) /* override pll suspend */ -#define USBPHY_CLKO1SEL BIT(3) -#define USBPHY_OSCPDWN BIT(2) -#define USBPHY_OTGPDWN BIT(1) -#define USBPHY_PHYPDWN BIT(0) - -#define DM355_DEEPSLEEP_PADDR 0x01c40048 -#define DRVVBUS_FORCE BIT(2) -#define DRVVBUS_OVERRIDE BIT(1) - -/* For now include usb OTG module registers here */ -#define DAVINCI_USB_VERSION_REG 0x00 -#define DAVINCI_USB_CTRL_REG 0x04 -#define DAVINCI_USB_STAT_REG 0x08 -#define DAVINCI_RNDIS_REG 0x10 -#define DAVINCI_AUTOREQ_REG 0x14 -#define DAVINCI_USB_INT_SOURCE_REG 0x20 -#define DAVINCI_USB_INT_SET_REG 0x24 -#define DAVINCI_USB_INT_SRC_CLR_REG 0x28 -#define DAVINCI_USB_INT_MASK_REG 0x2c -#define DAVINCI_USB_INT_MASK_SET_REG 0x30 -#define DAVINCI_USB_INT_MASK_CLR_REG 0x34 -#define DAVINCI_USB_INT_SRC_MASKED_REG 0x38 -#define DAVINCI_USB_EOI_REG 0x3c -#define DAVINCI_USB_EOI_INTVEC 0x40 - -/* BEGIN CPPI-generic (?) */ - -/* CPPI related registers */ -#define DAVINCI_TXCPPI_CTRL_REG 0x80 -#define DAVINCI_TXCPPI_TEAR_REG 0x84 -#define DAVINCI_CPPI_EOI_REG 0x88 -#define DAVINCI_CPPI_INTVEC_REG 0x8c -#define DAVINCI_TXCPPI_MASKED_REG 0x90 -#define DAVINCI_TXCPPI_RAW_REG 0x94 -#define DAVINCI_TXCPPI_INTENAB_REG 0x98 -#define DAVINCI_TXCPPI_INTCLR_REG 0x9c - -#define DAVINCI_RXCPPI_CTRL_REG 0xC0 -#define DAVINCI_RXCPPI_MASKED_REG 0xD0 -#define DAVINCI_RXCPPI_RAW_REG 0xD4 -#define DAVINCI_RXCPPI_INTENAB_REG 0xD8 -#define DAVINCI_RXCPPI_INTCLR_REG 0xDC - -#define DAVINCI_RXCPPI_BUFCNT0_REG 0xE0 -#define DAVINCI_RXCPPI_BUFCNT1_REG 0xE4 -#define DAVINCI_RXCPPI_BUFCNT2_REG 0xE8 -#define DAVINCI_RXCPPI_BUFCNT3_REG 0xEC - -/* CPPI state RAM entries */ -#define DAVINCI_CPPI_STATERAM_BASE_OFFSET 0x100 - -#define DAVINCI_TXCPPI_STATERAM_OFFSET(chnum) \ - (DAVINCI_CPPI_STATERAM_BASE_OFFSET + ((chnum) * 0x40)) -#define DAVINCI_RXCPPI_STATERAM_OFFSET(chnum) \ - (DAVINCI_CPPI_STATERAM_BASE_OFFSET + 0x20 + ((chnum) * 0x40)) - -/* CPPI masks */ -#define DAVINCI_DMA_CTRL_ENABLE 1 -#define DAVINCI_DMA_CTRL_DISABLE 0 - -#define DAVINCI_DMA_ALL_CHANNELS_ENABLE 0xF -#define DAVINCI_DMA_ALL_CHANNELS_DISABLE 0xF - -/* END CPPI-generic (?) */ - -#define DAVINCI_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */ -#define DAVINCI_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */ - -#define DAVINCI_USB_USBINT_SHIFT 16 -#define DAVINCI_USB_TXINT_SHIFT 0 -#define DAVINCI_USB_RXINT_SHIFT 8 - -#define DAVINCI_INTR_DRVVBUS 0x0100 - -#define DAVINCI_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */ -#define DAVINCI_USB_TXINT_MASK \ - (DAVINCI_USB_TX_ENDPTS_MASK << DAVINCI_USB_TXINT_SHIFT) -#define DAVINCI_USB_RXINT_MASK \ - (DAVINCI_USB_RX_ENDPTS_MASK << DAVINCI_USB_RXINT_SHIFT) - -#define DAVINCI_BASE_OFFSET 0x400 - -#endif /* __MUSB_HDRDF_H__ */ -- GitLab From 55f223b8b408cbfd85fb1c5b74ab85ccab319a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 17 Oct 2022 21:59:14 +0200 Subject: [PATCH 0094/1480] usb: dwc2: platform: Improve error reporting for problems during .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning an error value in a platform driver's remove callback results in a generic error message being emitted by the driver core, but otherwise it doesn't make a difference. The device goes away anyhow. For each case where ret is non-zero the driver already emits an error message, so suppress the generic error message by returning zero unconditionally. (Side note: The return value handling was unreliable anyhow as the value returned by dwc2_exit_hibernation() was overwritten anyhow if hsotg->in_ppd was non-zero.) Signed-off-by: Uwe Kleine-König Acked-by: Minas Harutyunyan Link: https://lore.kernel.org/r/20221017195914.1426297-1-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ec4ace0107f5f..262c13b6362ac 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -321,7 +321,7 @@ static int dwc2_driver_remove(struct platform_device *dev) reset_control_assert(hsotg->reset); reset_control_assert(hsotg->reset_ecc); - return ret; + return 0; } /** -- GitLab From b295d484b97081feba72b071ffcb72fb4638ccfd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Oct 2022 12:21:25 +0300 Subject: [PATCH 0095/1480] device property: Allow const parameter to dev_fwnode() It's not fully correct to take a const parameter pointer to a struct and return a non-const pointer to a member of that struct. Instead, introduce a const version of the dev_fwnode() API which takes and returns const pointers and use it where it's applicable. With this, convert dev_fwnode() to be a macro wrapper on top of const and non-const APIs that chooses one based on the type. Suggested-by: Sakari Ailus Fixes: aade55c86033 ("device property: Add const qualifier to device_get_match_data() parameter") Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Reviewed-by: Sakari Ailus Link: https://lore.kernel.org/r/20221004092129.19412-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 11 +++++++++-- include/linux/property.h | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index 4d6278a848686..d77302d285662 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -17,12 +17,19 @@ #include #include -struct fwnode_handle *dev_fwnode(const struct device *dev) +struct fwnode_handle *__dev_fwnode(struct device *dev) { return IS_ENABLED(CONFIG_OF) && dev->of_node ? of_fwnode_handle(dev->of_node) : dev->fwnode; } -EXPORT_SYMBOL_GPL(dev_fwnode); +EXPORT_SYMBOL_GPL(__dev_fwnode); + +const struct fwnode_handle *__dev_fwnode_const(const struct device *dev) +{ + return IS_ENABLED(CONFIG_OF) && dev->of_node ? + of_fwnode_handle(dev->of_node) : dev->fwnode; +} +EXPORT_SYMBOL_GPL(__dev_fwnode_const); /** * device_property_present - check if a property of a device is present diff --git a/include/linux/property.h b/include/linux/property.h index 117cc200c656d..587b5b666b5bb 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -32,7 +32,12 @@ enum dev_dma_attr { DEV_DMA_COHERENT, }; -struct fwnode_handle *dev_fwnode(const struct device *dev); +const struct fwnode_handle *__dev_fwnode_const(const struct device *dev); +struct fwnode_handle *__dev_fwnode(struct device *dev); +#define dev_fwnode(dev) \ + _Generic((dev), \ + const struct device *: __dev_fwnode_const, \ + struct device *: __dev_fwnode)(dev) bool device_property_present(struct device *dev, const char *propname); int device_property_read_u8_array(struct device *dev, const char *propname, -- GitLab From 23ead33bc6ed62abc9adc5fe27b9911e2ef5d209 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Oct 2022 12:21:26 +0300 Subject: [PATCH 0096/1480] device property: Constify fwnode connection match APIs The fwnode and device parameters are not altered in the fwnode connection match APIs, constify them. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Reviewed-by: Sakari Ailus Link: https://lore.kernel.org/r/20221004092129.19412-3-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 8 ++++---- drivers/usb/roles/class.c | 2 +- drivers/usb/typec/mux.c | 8 ++++---- drivers/usb/typec/retimer.c | 2 +- include/linux/property.h | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index d77302d285662..58b8158add5c8 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1213,7 +1213,7 @@ const void *device_get_match_data(const struct device *dev) } EXPORT_SYMBOL_GPL(device_get_match_data); -static unsigned int fwnode_graph_devcon_matches(struct fwnode_handle *fwnode, +static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match, void **matches, @@ -1247,7 +1247,7 @@ static unsigned int fwnode_graph_devcon_matches(struct fwnode_handle *fwnode, return count; } -static unsigned int fwnode_devcon_matches(struct fwnode_handle *fwnode, +static unsigned int fwnode_devcon_matches(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match, void **matches, @@ -1289,7 +1289,7 @@ static unsigned int fwnode_devcon_matches(struct fwnode_handle *fwnode, * device node. @match will be used to convert the connection description to * data the caller is expecting to be returned. */ -void *fwnode_connection_find_match(struct fwnode_handle *fwnode, +void *fwnode_connection_find_match(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match) { @@ -1326,7 +1326,7 @@ EXPORT_SYMBOL_GPL(fwnode_connection_find_match); * * Return: Number of matches resolved, or negative errno. */ -int fwnode_connection_find_matches(struct fwnode_handle *fwnode, +int fwnode_connection_find_matches(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match, void **matches, unsigned int matches_len) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index dfaed7eee94fc..a3575a5a18ce3 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -87,7 +87,7 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) } EXPORT_SYMBOL_GPL(usb_role_switch_get_role); -static void *usb_role_switch_match(struct fwnode_handle *fwnode, const char *id, +static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const char *id, void *data) { struct device *dev; diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 941735c731619..c7177ddd4f127 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -32,8 +32,8 @@ static int switch_fwnode_match(struct device *dev, const void *fwnode) return device_match_fwnode(dev, fwnode); } -static void *typec_switch_match(struct fwnode_handle *fwnode, const char *id, - void *data) +static void *typec_switch_match(const struct fwnode_handle *fwnode, + const char *id, void *data) { struct device *dev; @@ -262,8 +262,8 @@ static int mux_fwnode_match(struct device *dev, const void *fwnode) return device_match_fwnode(dev, fwnode); } -static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id, - void *data) +static void *typec_mux_match(const struct fwnode_handle *fwnode, + const char *id, void *data) { const struct typec_altmode_desc *desc = data; struct device *dev; diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c index ee94dbbe47453..8e1055783fe22 100644 --- a/drivers/usb/typec/retimer.c +++ b/drivers/usb/typec/retimer.c @@ -34,7 +34,7 @@ static int retimer_fwnode_match(struct device *dev, const void *fwnode) return device_match_fwnode(dev, fwnode) && dev_name_ends_with(dev, "-retimer"); } -static void *typec_retimer_match(struct fwnode_handle *fwnode, const char *id, void *data) +static void *typec_retimer_match(const struct fwnode_handle *fwnode, const char *id, void *data) { struct device *dev; diff --git a/include/linux/property.h b/include/linux/property.h index 587b5b666b5bb..8d82775a901a9 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -442,21 +442,21 @@ unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode, int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); -typedef void *(*devcon_match_fn_t)(struct fwnode_handle *fwnode, const char *id, +typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode, const char *id, void *data); -void *fwnode_connection_find_match(struct fwnode_handle *fwnode, +void *fwnode_connection_find_match(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match); -static inline void *device_connection_find_match(struct device *dev, +static inline void *device_connection_find_match(const struct device *dev, const char *con_id, void *data, devcon_match_fn_t match) { return fwnode_connection_find_match(dev_fwnode(dev), con_id, data, match); } -int fwnode_connection_find_matches(struct fwnode_handle *fwnode, +int fwnode_connection_find_matches(const struct fwnode_handle *fwnode, const char *con_id, void *data, devcon_match_fn_t match, void **matches, unsigned int matches_len); -- GitLab From a1bfed6094ac6868c43aaa43d021bf562cd93d07 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Oct 2022 12:21:27 +0300 Subject: [PATCH 0097/1480] device property: Constify parameter in fwnode_graph_is_endpoint() Constify parameter in fwnode_graph_is_endpoint() since it doesn't alter anything related to it. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Reviewed-by: Sakari Ailus Link: https://lore.kernel.org/r/20221004092129.19412-4-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/property.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/property.h b/include/linux/property.h index 8d82775a901a9..7abb1792044f7 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -410,7 +410,7 @@ struct fwnode_handle *fwnode_graph_get_remote_port( struct fwnode_handle *fwnode_graph_get_remote_endpoint( const struct fwnode_handle *fwnode); -static inline bool fwnode_graph_is_endpoint(struct fwnode_handle *fwnode) +static inline bool fwnode_graph_is_endpoint(const struct fwnode_handle *fwnode) { return fwnode_property_present(fwnode, "remote-endpoint"); } -- GitLab From 7952cd2b8213f20a1752634c25dfd215da537722 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Oct 2022 12:21:28 +0300 Subject: [PATCH 0098/1480] device property: Constify device child node APIs The device parameter is not altered in the device child node APIs, constify them. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Reviewed-by: Sakari Ailus Link: https://lore.kernel.org/r/20221004092129.19412-5-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 6 +++--- include/linux/property.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index 58b8158add5c8..d3ea5f82978f3 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -763,7 +763,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node); * @dev: Device to find the next child node for. * @child: Handle to one of the device's child nodes or a null handle. */ -struct fwnode_handle *device_get_next_child_node(struct device *dev, +struct fwnode_handle *device_get_next_child_node(const struct device *dev, struct fwnode_handle *child) { const struct fwnode_handle *fwnode = dev_fwnode(dev); @@ -800,7 +800,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_named_child_node); * @dev: Device to find the named child node for. * @childname: String to match child node name against. */ -struct fwnode_handle *device_get_named_child_node(struct device *dev, +struct fwnode_handle *device_get_named_child_node(const struct device *dev, const char *childname) { return fwnode_get_named_child_node(dev_fwnode(dev), childname); @@ -859,7 +859,7 @@ EXPORT_SYMBOL_GPL(fwnode_device_is_available); * device_get_child_node_count - return the number of child nodes for device * @dev: Device to cound the child nodes for */ -unsigned int device_get_child_node_count(struct device *dev) +unsigned int device_get_child_node_count(const struct device *dev) { struct fwnode_handle *child; unsigned int count = 0; diff --git a/include/linux/property.h b/include/linux/property.h index 7abb1792044f7..472689e53ade5 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -114,16 +114,16 @@ struct fwnode_handle *fwnode_get_next_available_child_node( for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ child = fwnode_get_next_available_child_node(fwnode, child)) -struct fwnode_handle *device_get_next_child_node( - struct device *dev, struct fwnode_handle *child); +struct fwnode_handle *device_get_next_child_node(const struct device *dev, + struct fwnode_handle *child); #define device_for_each_child_node(dev, child) \ for (child = device_get_next_child_node(dev, NULL); child; \ child = device_get_next_child_node(dev, child)) -struct fwnode_handle *fwnode_get_named_child_node( - const struct fwnode_handle *fwnode, const char *childname); -struct fwnode_handle *device_get_named_child_node(struct device *dev, +struct fwnode_handle *fwnode_get_named_child_node(const struct fwnode_handle *fwnode, + const char *childname); +struct fwnode_handle *device_get_named_child_node(const struct device *dev, const char *childname); struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode); @@ -132,7 +132,7 @@ void fwnode_handle_put(struct fwnode_handle *fwnode); int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index); int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name); -unsigned int device_get_child_node_count(struct device *dev); +unsigned int device_get_child_node_count(const struct device *dev); static inline bool device_property_read_bool(struct device *dev, const char *propname) -- GitLab From 59789f3418dd3c0a187490d49e900a59a5c8d732 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Oct 2022 12:21:29 +0300 Subject: [PATCH 0099/1480] device property: Constify parameter in device_dma_supported() and device_get_dma_attr() Constify parameter in device_dma_supported() and device_get_dma_attr() since they don't alter anything related to it. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Reviewed-by: Sakari Ailus Link: https://lore.kernel.org/r/20221004092129.19412-6-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 4 ++-- include/linux/property.h | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index d3ea5f82978f3..68f61d3e38577 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -871,13 +871,13 @@ unsigned int device_get_child_node_count(const struct device *dev) } EXPORT_SYMBOL_GPL(device_get_child_node_count); -bool device_dma_supported(struct device *dev) +bool device_dma_supported(const struct device *dev) { return fwnode_call_bool_op(dev_fwnode(dev), device_dma_supported); } EXPORT_SYMBOL_GPL(device_dma_supported); -enum dev_dma_attr device_get_dma_attr(struct device *dev) +enum dev_dma_attr device_get_dma_attr(const struct device *dev) { if (!fwnode_has_op(dev_fwnode(dev), device_get_dma_attr)) return DEV_DMA_NOT_SUPPORTED; diff --git a/include/linux/property.h b/include/linux/property.h index 472689e53ade5..83674f968a8fd 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -388,9 +388,8 @@ property_entries_dup(const struct property_entry *properties); void property_entries_free(const struct property_entry *properties); -bool device_dma_supported(struct device *dev); - -enum dev_dma_attr device_get_dma_attr(struct device *dev); +bool device_dma_supported(const struct device *dev); +enum dev_dma_attr device_get_dma_attr(const struct device *dev); const void *device_get_match_data(const struct device *dev); -- GitLab From 87fa05b6db47403fa4fbe3a8ce8fa619f7c8667e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 8 Oct 2022 22:45:01 +0300 Subject: [PATCH 0100/1480] thunderbolt: Use str_enabled_disabled() helper Use str_enabled_disabled() helper instead of open coding the same. Signed-off-by: Andy Shevchenko Signed-off-by: Mika Westerberg --- drivers/thunderbolt/switch.c | 5 +++-- drivers/thunderbolt/xdomain.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 60da5c23ccaf4..363d712aa3643 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -8,12 +8,13 @@ #include #include +#include #include #include #include #include #include -#include +#include #include "tb.h" @@ -644,7 +645,7 @@ static int __tb_port_enable(struct tb_port *port, bool enable) if (ret) return ret; - tb_port_dbg(port, "lane %sabled\n", enable ? "en" : "dis"); + tb_port_dbg(port, "lane %s\n", str_enabled_disabled(enable)); return 0; } diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c index f00b2f62d8e3c..ddd8fd2d06f86 100644 --- a/drivers/thunderbolt/xdomain.c +++ b/drivers/thunderbolt/xdomain.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1344,7 +1345,7 @@ static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd) tb_port_update_credits(port); tb_xdomain_update_link_attributes(xd); - dev_dbg(&xd->dev, "lane bonding %sabled\n", width == 2 ? "en" : "dis"); + dev_dbg(&xd->dev, "lane bonding %s\n", str_enabled_disabled(width == 2)); return 0; } -- GitLab From b9589c417fedab6b963cf084ef305665166f5326 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 19 Oct 2022 23:57:09 +0100 Subject: [PATCH 0101/1480] thunderbolt: Remove redundant assignment to variable len The variable len is assigned a value that is never read. It is re-assigned a new value in the following do-while loop and never referenced after the loop. The assignment is redundant and can be removed. Cleans up clang scan build warning: drivers/thunderbolt/xdomain.c:344:2: warning: Value stored to 'len' is never read [deadcode.DeadStores] Signed-off-by: Colin Ian King Signed-off-by: Mika Westerberg --- drivers/thunderbolt/xdomain.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c index ddd8fd2d06f86..cfa83486c9dad 100644 --- a/drivers/thunderbolt/xdomain.c +++ b/drivers/thunderbolt/xdomain.c @@ -342,7 +342,6 @@ static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route, memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid)); memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid)); - len = 0; data_len = 0; do { -- GitLab From 32c6fefb291bf84c5a4dbc7d52b56a1605ed9aae Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Oct 2022 15:27:54 +0200 Subject: [PATCH 0102/1480] usb: phy: generic: make vcc regulator optional phy-generic uses the existance of the property "vcc-supply" to see if a regulator is optional or not. Use devm_regulator_get_optional() instead which exists for this purpose. Using devm_regulator_get_optional() avoids "supply vcc not found, using dummy regulator" messages. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20221012132754.292151-1-s.hauer@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/phy-generic.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 3dc5c04e7cbf9..8ed9327cc4a52 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -209,7 +209,7 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) int err = 0; u32 clk_rate = 0; - bool needs_vcc = false, needs_clk = false; + bool needs_clk = false; if (dev->of_node) { struct device_node *node = dev->of_node; @@ -217,7 +217,6 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; - needs_vcc = of_property_read_bool(node, "vcc-supply"); needs_clk = of_property_read_bool(node, "clocks"); } nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", @@ -257,13 +256,10 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) } } - nop->vcc = devm_regulator_get(dev, "vcc"); - if (IS_ERR(nop->vcc)) { - dev_dbg(dev, "Error getting vcc regulator: %ld\n", - PTR_ERR(nop->vcc)); - if (needs_vcc) - return -EPROBE_DEFER; - } + nop->vcc = devm_regulator_get_optional(dev, "vcc"); + if (IS_ERR(nop->vcc) && PTR_ERR(nop->vcc) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(nop->vcc), + "could not get vcc regulator\n"); nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus"); if (PTR_ERR(nop->vbus_draw) == -ENODEV) -- GitLab From e1b5d2bed67c60c30d01a89df32152d74cfc8e63 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Sun, 9 Oct 2022 23:53:36 +0800 Subject: [PATCH 0103/1480] usb: chipidea: core: handle usb role switch in a common way Currently, ci_usb_role_switch_set() may be called before system resume stage when suspended. Worse yet, ci_hdrc device may stay at RPM_ACTIVE state which will cause pm_runtime_get_sync() fail to resume the device. In this case, role-switch may unable to complete transition process due to not exit from lpm state or due to lack some means after system resume. Same as ci_cable_notifier(), usb_role_switch could handle its events based on ci_hdrc_cable mechanism. Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20221009155336.766960-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 55 ++++++++++++++----------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 6330fa9117926..ae90fee75a32d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -608,49 +608,32 @@ static int ci_usb_role_switch_set(struct usb_role_switch *sw, enum usb_role role) { struct ci_hdrc *ci = usb_role_switch_get_drvdata(sw); - struct ci_hdrc_cable *cable = NULL; - enum usb_role current_role = ci_role_to_usb_role(ci); - enum ci_role ci_role = usb_role_to_ci_role(role); - unsigned long flags; - - if ((ci_role != CI_ROLE_END && !ci->roles[ci_role]) || - (current_role == role)) - return 0; + struct ci_hdrc_cable *cable; - pm_runtime_get_sync(ci->dev); - /* Stop current role */ - spin_lock_irqsave(&ci->lock, flags); - if (current_role == USB_ROLE_DEVICE) + if (role == USB_ROLE_HOST) { + cable = &ci->platdata->id_extcon; + cable->changed = true; + cable->connected = true; cable = &ci->platdata->vbus_extcon; - else if (current_role == USB_ROLE_HOST) + cable->changed = true; + cable->connected = false; + } else if (role == USB_ROLE_DEVICE) { cable = &ci->platdata->id_extcon; - - if (cable) { cable->changed = true; cable->connected = false; - ci_irq(ci); - spin_unlock_irqrestore(&ci->lock, flags); - if (ci->wq && role != USB_ROLE_NONE) - flush_workqueue(ci->wq); - spin_lock_irqsave(&ci->lock, flags); - } - - cable = NULL; - - /* Start target role */ - if (role == USB_ROLE_DEVICE) cable = &ci->platdata->vbus_extcon; - else if (role == USB_ROLE_HOST) - cable = &ci->platdata->id_extcon; - - if (cable) { cable->changed = true; cable->connected = true; - ci_irq(ci); + } else { + cable = &ci->platdata->id_extcon; + cable->changed = true; + cable->connected = false; + cable = &ci->platdata->vbus_extcon; + cable->changed = true; + cable->connected = false; } - spin_unlock_irqrestore(&ci->lock, flags); - pm_runtime_put_sync(ci->dev); + ci_irq(ci); return 0; } @@ -1305,11 +1288,13 @@ static void ci_extcon_wakeup_int(struct ci_hdrc *ci) cable_id = &ci->platdata->id_extcon; cable_vbus = &ci->platdata->vbus_extcon; - if (!IS_ERR(cable_id->edev) && ci->is_otg && + if ((!IS_ERR(cable_id->edev) || !IS_ERR(ci->role_switch)) + && ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) ci_irq(ci); - if (!IS_ERR(cable_vbus->edev) && ci->is_otg && + if ((!IS_ERR(cable_vbus->edev) || !IS_ERR(ci->role_switch)) + && ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) ci_irq(ci); } -- GitLab From caa7b74493f9c903fb6cd4bdec295bcae0507cc6 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 14 Oct 2022 17:55:50 +0800 Subject: [PATCH 0104/1480] dt-bindings: phy: imx8mq-usb: add power-domains property Add optional power-domains property for usb phy. Signed-off-by: Peng Fan Acked-by: Alexander Stein Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221014095550.2125018-1-peng.fan@oss.nxp.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index 2936f3510a6ad..5ba9570ad7bf2 100644 --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml @@ -28,6 +28,9 @@ properties: items: - const: phy + power-domains: + maxItems: 1 + vbus-supply: description: A phandle to the regulator for USB VBUS. -- GitLab From 74494b33211d067427db25824cd8b53fa0eab1ef Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 13 Oct 2022 23:14:35 +0800 Subject: [PATCH 0105/1480] usb: chipidea: core: add controller resume support when controller is powered off For some SoCs, the controler's power will be off during the system suspend, and it needs some recovery operation to let the system back to workable. We add this support in this patch. Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20221013151442.3262951-2-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 80 ++++++++++++++++++++++++++++--------- drivers/usb/chipidea/otg.c | 2 +- drivers/usb/chipidea/otg.h | 1 + 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ae90fee75a32d..80267b973c26a 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -637,6 +637,49 @@ static int ci_usb_role_switch_set(struct usb_role_switch *sw, return 0; } +static enum ci_role ci_get_role(struct ci_hdrc *ci) +{ + enum ci_role role; + + if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) { + if (ci->is_otg) { + role = ci_otg_role(ci); + hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE); + } else { + /* + * If the controller is not OTG capable, but support + * role switch, the defalt role is gadget, and the + * user can switch it through debugfs. + */ + role = CI_ROLE_GADGET; + } + } else { + role = ci->roles[CI_ROLE_HOST] ? CI_ROLE_HOST + : CI_ROLE_GADGET; + } + + return role; +} + +static void ci_handle_power_lost(struct ci_hdrc *ci) +{ + enum ci_role role; + + disable_irq_nosync(ci->irq); + if (!ci_otg_is_fsm_mode(ci)) { + role = ci_get_role(ci); + + if (ci->role != role) { + ci_handle_id_switch(ci); + } else if (role == CI_ROLE_GADGET) { + if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV)) + usb_gadget_vbus_connect(&ci->gadget); + } + } + + enable_irq(ci->irq); +} + static struct usb_role_switch_desc ci_role_switch = { .set = ci_usb_role_switch_set, .get = ci_usb_role_switch_get, @@ -1134,25 +1177,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) } } - if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) { - if (ci->is_otg) { - ci->role = ci_otg_role(ci); - /* Enable ID change irq */ - hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE); - } else { - /* - * If the controller is not OTG capable, but support - * role switch, the defalt role is gadget, and the - * user can switch it through debugfs. - */ - ci->role = CI_ROLE_GADGET; - } - } else { - ci->role = ci->roles[CI_ROLE_HOST] - ? CI_ROLE_HOST - : CI_ROLE_GADGET; - } - + ci->role = ci_get_role(ci); if (!ci_otg_is_fsm_mode(ci)) { /* only update vbus status for peripheral */ if (ci->role == CI_ROLE_GADGET) { @@ -1374,8 +1399,16 @@ static int ci_suspend(struct device *dev) static int ci_resume(struct device *dev) { struct ci_hdrc *ci = dev_get_drvdata(dev); + bool power_lost; int ret; + /* Since ASYNCLISTADDR (host mode) and ENDPTLISTADDR (device + * mode) share the same register address. We can check if + * controller resume from power lost based on this address + * due to this register will be reset after power lost. + */ + power_lost = !hw_read(ci, OP_ENDPTLISTADDR, ~0); + if (device_may_wakeup(dev)) disable_irq_wake(ci->irq); @@ -1383,6 +1416,15 @@ static int ci_resume(struct device *dev) if (ret) return ret; + if (power_lost) { + /* shutdown and re-init for phy */ + ci_usb_phy_exit(ci); + ci_usb_phy_init(ci); + } + + if (power_lost) + ci_handle_power_lost(ci); + if (ci->supports_runtime_pm) { pm_runtime_disable(dev); pm_runtime_set_active(dev); diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index 7b53274ef9664..622c3b68aa1e6 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -165,7 +165,7 @@ static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci) return 0; } -static void ci_handle_id_switch(struct ci_hdrc *ci) +void ci_handle_id_switch(struct ci_hdrc *ci) { enum ci_role role = ci_otg_role(ci); diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h index 5e7a6e571dd2f..87629b81e03ea 100644 --- a/drivers/usb/chipidea/otg.h +++ b/drivers/usb/chipidea/otg.h @@ -14,6 +14,7 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci); void ci_hdrc_otg_destroy(struct ci_hdrc *ci); enum ci_role ci_otg_role(struct ci_hdrc *ci); void ci_handle_vbus_change(struct ci_hdrc *ci); +void ci_handle_id_switch(struct ci_hdrc *ci); static inline void ci_otg_queue_work(struct ci_hdrc *ci) { disable_irq_nosync(ci->irq); -- GitLab From 450857c6058f092167f17bad97a2cc9c2a39b9a0 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 13 Oct 2022 23:14:36 +0800 Subject: [PATCH 0106/1480] usb: chipidea: core: handle suspend/resume for each role There may be a need to handle suspend/resume per role. This patch will add this support. Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20221013151442.3262951-3-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci.h | 4 ++++ drivers/usb/chipidea/core.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index a4a3be0499109..005c67cb3afb7 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -127,12 +127,16 @@ enum ci_revision { * struct ci_role_driver - host/gadget role driver * @start: start this role * @stop: stop this role + * @suspend: system suspend handler for this role + * @resume: system resume handler for this role * @irq: irq handler for this role * @name: role name string (host/gadget) */ struct ci_role_driver { int (*start)(struct ci_hdrc *); void (*stop)(struct ci_hdrc *); + void (*suspend)(struct ci_hdrc *ci); + void (*resume)(struct ci_hdrc *ci, bool power_lost); irqreturn_t (*irq)(struct ci_hdrc *); const char *name; }; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 80267b973c26a..2b170b434d012 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -1383,6 +1383,10 @@ static int ci_suspend(struct device *dev) return 0; } + /* Extra routine per role before system suspend */ + if (ci->role != CI_ROLE_END && ci_role(ci)->suspend) + ci_role(ci)->suspend(ci); + if (device_may_wakeup(dev)) { if (ci_otg_is_fsm_mode(ci)) ci_otg_fsm_suspend_for_srp(ci); @@ -1422,6 +1426,10 @@ static int ci_resume(struct device *dev) ci_usb_phy_init(ci); } + /* Extra routine per role after system resume */ + if (ci->role != CI_ROLE_END && ci_role(ci)->resume) + ci_role(ci)->resume(ci, power_lost); + if (power_lost) ci_handle_power_lost(ci); -- GitLab From 2f64d6a6cdfbd992e8a8c481ebf79bfa9a71325b Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 13 Oct 2022 23:14:37 +0800 Subject: [PATCH 0107/1480] usb: chipidea: host: add suspend/resume support for host controller The controller's power may be powered off during system suspend. This will add suspend/resume support when the controller suffers power lost. Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20221013151442.3262951-4-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/host.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index bc3634a54c6b7..ebe7400243b12 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -459,6 +459,18 @@ static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) ci_hdrc_free_dma_aligned_buffer(urb); } +#ifdef CONFIG_PM_SLEEP +static void ci_hdrc_host_suspend(struct ci_hdrc *ci) +{ + ehci_suspend(ci->hcd, device_may_wakeup(ci->dev)); +} + +static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost) +{ + ehci_resume(ci->hcd, power_lost); +} +#endif + int ci_hdrc_host_init(struct ci_hdrc *ci) { struct ci_role_driver *rdrv; @@ -472,6 +484,10 @@ int ci_hdrc_host_init(struct ci_hdrc *ci) rdrv->start = host_start; rdrv->stop = host_stop; +#ifdef CONFIG_PM_SLEEP + rdrv->suspend = ci_hdrc_host_suspend; + rdrv->resume = ci_hdrc_host_resume; +#endif rdrv->irq = host_irq; rdrv->name = "host"; ci->roles[CI_ROLE_HOST] = rdrv; -- GitLab From 235ffc17d0146d806f6ad8c094c24ff4878f2edb Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 13 Oct 2022 23:14:38 +0800 Subject: [PATCH 0108/1480] usb: chipidea: udc: add suspend/resume support for device controller The controller's power may be powered off during system suspend. This will add suspend/resume support when the controller suffers power lost. Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20221013151442.3262951-5-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/udc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 8c3e3a635ac2d..54c09245ad055 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -2181,6 +2181,34 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci) ci->platdata->pins_default); } +#ifdef CONFIG_PM_SLEEP +static void udc_suspend(struct ci_hdrc *ci) +{ + /* + * Set OP_ENDPTLISTADDR to be non-zero for + * checking if controller resume from power lost + * in non-host mode. + */ + if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0) + hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0); +} + +static void udc_resume(struct ci_hdrc *ci, bool power_lost) +{ + if (power_lost) { + if (ci->is_otg) + hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, + OTGSC_BSVIS | OTGSC_BSVIE); + if (ci->vbus_active) + usb_gadget_vbus_disconnect(&ci->gadget); + } + + /* Restore value 0 if it was set for power lost check */ + if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0xFFFFFFFF) + hw_write(ci, OP_ENDPTLISTADDR, ~0, 0); +} +#endif + /** * ci_hdrc_gadget_init - initialize device related bits * @ci: the controller @@ -2201,6 +2229,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci) rdrv->start = udc_id_switch_for_device; rdrv->stop = udc_id_switch_for_host; +#ifdef CONFIG_PM_SLEEP + rdrv->suspend = udc_suspend; + rdrv->resume = udc_resume; +#endif rdrv->irq = udc_irq; rdrv->name = "gadget"; -- GitLab From b332d6d5c804085ac26d2e7e1a953b59b49644f3 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 13 Oct 2022 23:14:39 +0800 Subject: [PATCH 0109/1480] usb: chipidea: usbmisc: group usbmisc operations for PM As there maybe more APIs of usbmisc for suspend and resume, group them into imx_usbmisc_suspend/resume. Besides, introduced .power_lost_check API, so that proper resume operations can be performed in power lost case. Signed-off-by: Li Jun Link: https://lore.kernel.org/r/20221013151442.3262951-6-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 49 ++++-------- drivers/usb/chipidea/ci_hdrc_imx.h | 4 +- drivers/usb/chipidea/usbmisc_imx.c | 119 +++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 66 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 9ffcecd3058c1..923f5c00a1d96 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -527,16 +527,19 @@ static void ci_hdrc_imx_shutdown(struct platform_device *pdev) ci_hdrc_imx_remove(pdev); } -static int __maybe_unused imx_controller_suspend(struct device *dev) +static int __maybe_unused imx_controller_suspend(struct device *dev, + pm_message_t msg) { struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); int ret = 0; dev_dbg(dev, "at %s\n", __func__); - ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false); + ret = imx_usbmisc_suspend(data->usbmisc_data, + PMSG_IS_AUTO(msg) || device_may_wakeup(dev)); if (ret) { - dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret); + dev_err(dev, + "usbmisc suspend failed, ret=%d\n", ret); return ret; } @@ -549,7 +552,8 @@ static int __maybe_unused imx_controller_suspend(struct device *dev) return 0; } -static int __maybe_unused imx_controller_resume(struct device *dev) +static int __maybe_unused imx_controller_resume(struct device *dev, + pm_message_t msg) { struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); int ret = 0; @@ -570,22 +574,15 @@ static int __maybe_unused imx_controller_resume(struct device *dev) data->in_lpm = false; - ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false); + ret = imx_usbmisc_resume(data->usbmisc_data, + PMSG_IS_AUTO(msg) || device_may_wakeup(dev)); if (ret) { - dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret); + dev_err(dev, "usbmisc resume failed, ret=%d\n", ret); goto clk_disable; } - ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true); - if (ret) { - dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret); - goto hsic_set_clk_fail; - } - return 0; -hsic_set_clk_fail: - imx_usbmisc_set_wakeup(data->usbmisc_data, true); clk_disable: imx_disable_unprepare_clks(dev); return ret; @@ -601,16 +598,7 @@ static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev) /* The core's suspend doesn't run */ return 0; - if (device_may_wakeup(dev)) { - ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true); - if (ret) { - dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", - ret); - return ret; - } - } - - ret = imx_controller_suspend(dev); + ret = imx_controller_suspend(dev, PMSG_SUSPEND); if (ret) return ret; @@ -624,7 +612,7 @@ static int __maybe_unused ci_hdrc_imx_resume(struct device *dev) int ret; pinctrl_pm_select_default_state(dev); - ret = imx_controller_resume(dev); + ret = imx_controller_resume(dev, PMSG_RESUME); if (!ret && data->supports_runtime_pm) { pm_runtime_disable(dev); pm_runtime_set_active(dev); @@ -637,25 +625,18 @@ static int __maybe_unused ci_hdrc_imx_resume(struct device *dev) static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev) { struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); - int ret; if (data->in_lpm) { WARN_ON(1); return 0; } - ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true); - if (ret) { - dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret); - return ret; - } - - return imx_controller_suspend(dev); + return imx_controller_suspend(dev, PMSG_AUTO_SUSPEND); } static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev) { - return imx_controller_resume(dev); + return imx_controller_resume(dev, PMSG_AUTO_RESUME); } static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h index 7daccb9c5006a..7135b9a5d9138 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.h +++ b/drivers/usb/chipidea/ci_hdrc_imx.h @@ -32,9 +32,9 @@ struct imx_usbmisc_data { int imx_usbmisc_init(struct imx_usbmisc_data *data); int imx_usbmisc_init_post(struct imx_usbmisc_data *data); -int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled); int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data); -int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on); int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect); +int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup); +int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup); #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */ diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index bac0f5458cab9..aa815f6d3fe9a 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -150,6 +150,8 @@ struct usbmisc_ops { int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); /* usb charger detection */ int (*charger_detection)(struct imx_usbmisc_data *data); + /* It's called when system resume from usb power lost */ + int (*power_lost_check)(struct imx_usbmisc_data *data); }; struct imx_usbmisc { @@ -1009,30 +1011,29 @@ EXPORT_SYMBOL_GPL(imx_usbmisc_init); int imx_usbmisc_init_post(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc; + int ret = 0; if (!data) return 0; usbmisc = dev_get_drvdata(data->dev); - if (!usbmisc->ops->post) - return 0; - return usbmisc->ops->post(data); -} -EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); - -int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled) -{ - struct imx_usbmisc *usbmisc; + if (usbmisc->ops->post) + ret = usbmisc->ops->post(data); + if (ret) { + dev_err(data->dev, "post init failed, ret=%d\n", ret); + return ret; + } - if (!data) - return 0; + if (usbmisc->ops->set_wakeup) + ret = usbmisc->ops->set_wakeup(data, false); + if (ret) { + dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); + return ret; + } - usbmisc = dev_get_drvdata(data->dev); - if (!usbmisc->ops->set_wakeup) - return 0; - return usbmisc->ops->set_wakeup(data, enabled); + return 0; } -EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup); +EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) { @@ -1048,20 +1049,6 @@ int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) } EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect); -int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on) -{ - struct imx_usbmisc *usbmisc; - - if (!data) - return 0; - - usbmisc = dev_get_drvdata(data->dev); - if (!usbmisc->ops->hsic_set_clk || !data->hsic) - return 0; - return usbmisc->ops->hsic_set_clk(data, on); -} -EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk); - int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) { struct imx_usbmisc *usbmisc; @@ -1094,6 +1081,78 @@ int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) } EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection); +int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup) +{ + struct imx_usbmisc *usbmisc; + int ret = 0; + + if (!data) + return 0; + + usbmisc = dev_get_drvdata(data->dev); + + if (wakeup && usbmisc->ops->set_wakeup) + ret = usbmisc->ops->set_wakeup(data, true); + if (ret) { + dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); + return ret; + } + + if (usbmisc->ops->hsic_set_clk && data->hsic) + ret = usbmisc->ops->hsic_set_clk(data, false); + if (ret) { + dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); + return ret; + } + + return ret; +} +EXPORT_SYMBOL_GPL(imx_usbmisc_suspend); + +int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup) +{ + struct imx_usbmisc *usbmisc; + int ret = 0; + + if (!data) + return 0; + + usbmisc = dev_get_drvdata(data->dev); + + if (usbmisc->ops->power_lost_check) + ret = usbmisc->ops->power_lost_check(data); + if (ret > 0) { + /* re-init if resume from power lost */ + ret = imx_usbmisc_init(data); + if (ret) { + dev_err(data->dev, "re-init failed, ret=%d\n", ret); + return ret; + } + } + + if (wakeup && usbmisc->ops->set_wakeup) + ret = usbmisc->ops->set_wakeup(data, false); + if (ret) { + dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); + return ret; + } + + if (usbmisc->ops->hsic_set_clk && data->hsic) + ret = usbmisc->ops->hsic_set_clk(data, true); + if (ret) { + dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); + goto hsic_set_clk_fail; + } + + return 0; + +hsic_set_clk_fail: + if (wakeup && usbmisc->ops->set_wakeup) + usbmisc->ops->set_wakeup(data, true); + return ret; +} +EXPORT_SYMBOL_GPL(imx_usbmisc_resume); + static const struct of_device_id usbmisc_imx_dt_ids[] = { { .compatible = "fsl,imx25-usbmisc", -- GitLab From 04ff4d31af40e268c6cde78814be465a6412212d Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 13 Oct 2022 23:14:40 +0800 Subject: [PATCH 0110/1480] usb: chipidea: usbmisc: add power lost check for imx6sx imx6sx mega off can shutdown domain power supply if none of peripheral in this domain is registered as wakeup source, this patch add related codes to check if power is lost. Signed-off-by: Li Jun Link: https://lore.kernel.org/r/20221013151442.3262951-7-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index aa815f6d3fe9a..7bfbfc83cfe3c 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -939,6 +939,25 @@ static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) return 0; } +static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + unsigned long flags; + u32 val; + + spin_lock_irqsave(&usbmisc->lock, flags); + val = readl(usbmisc->base + data->index * 4); + spin_unlock_irqrestore(&usbmisc->lock, flags); + /* + * Here use a power on reset value to judge + * if the controller experienced a power lost + */ + if (val == 0x30001000) + return 1; + else + return 0; +} + static const struct usbmisc_ops imx25_usbmisc_ops = { .init = usbmisc_imx25_init, .post = usbmisc_imx25_post, @@ -972,6 +991,7 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = { .init = usbmisc_imx6sx_init, .hsic_set_connect = usbmisc_imx6_hsic_set_connect, .hsic_set_clk = usbmisc_imx6_hsic_set_clk, + .power_lost_check = usbmisc_imx6sx_power_lost_check, }; static const struct usbmisc_ops imx7d_usbmisc_ops = { -- GitLab From 604ceaa9e9fc223c2cc8d6cf0fc02022a3d14a68 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 13 Oct 2022 23:14:41 +0800 Subject: [PATCH 0111/1480] usb: chipidea: usbmisc: add power lost check for imx7d imx7d can shutdown domain power supply if none of peripheral in this domain is registered as wakeup source, this patch add related codes to check if power is lost. Signed-off-by: Li Jun Link: https://lore.kernel.org/r/20221013151442.3262951-8-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 7bfbfc83cfe3c..cc17dcd97856c 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -939,6 +939,25 @@ static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) return 0; } +static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + unsigned long flags; + u32 val; + + spin_lock_irqsave(&usbmisc->lock, flags); + val = readl(usbmisc->base); + spin_unlock_irqrestore(&usbmisc->lock, flags); + /* + * Here use a power on reset value to judge + * if the controller experienced a power lost + */ + if (val == 0x30001000) + return 1; + else + return 0; +} + static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); @@ -998,6 +1017,7 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = { .init = usbmisc_imx7d_init, .set_wakeup = usbmisc_imx7d_set_wakeup, .charger_detection = imx7d_charger_detection, + .power_lost_check = usbmisc_imx7d_power_lost_check, }; static const struct usbmisc_ops imx7ulp_usbmisc_ops = { -- GitLab From 8127cac0f393abaddf5747bcc7e7ccf6668117fe Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 13 Oct 2022 23:14:42 +0800 Subject: [PATCH 0112/1480] usb: chipidea: usbmisc: add power lost check for imx7ulp imx7ulp can shutdown domain power supply if none of peripheral in this domain is registered as wakeup source, this patch add related power lost check API. Signed-off-by: Li Jun Link: https://lore.kernel.org/r/20221013151442.3262951-9-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index cc17dcd97856c..acdb13316cd0d 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -1025,6 +1025,7 @@ static const struct usbmisc_ops imx7ulp_usbmisc_ops = { .set_wakeup = usbmisc_imx7d_set_wakeup, .hsic_set_connect = usbmisc_imx6_hsic_set_connect, .hsic_set_clk = usbmisc_imx6_hsic_set_clk, + .power_lost_check = usbmisc_imx7d_power_lost_check, }; static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) -- GitLab From bf0563502ecdbb97efb65790b37dd50afbe2d9b2 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sat, 22 Oct 2022 01:03:42 +0530 Subject: [PATCH 0113/1480] staging: wlan-ng: remove commented debug printk messages printk messages are added for program flow tracing and are left commented. These commented log messages should be removed as they are no more useful for program execution. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y1L0FiKvrM9jjZG9@debian-BULLSEYE-live-builder-AMD64 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index e04fc666d218e..6bef419e8ad0c 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -881,55 +881,42 @@ static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc) wlandev->rx.mgmt++; switch (fstype) { case WLAN_FSTYPE_ASSOCREQ: - /* printk("assocreq"); */ wlandev->rx.assocreq++; break; case WLAN_FSTYPE_ASSOCRESP: - /* printk("assocresp"); */ wlandev->rx.assocresp++; break; case WLAN_FSTYPE_REASSOCREQ: - /* printk("reassocreq"); */ wlandev->rx.reassocreq++; break; case WLAN_FSTYPE_REASSOCRESP: - /* printk("reassocresp"); */ wlandev->rx.reassocresp++; break; case WLAN_FSTYPE_PROBEREQ: - /* printk("probereq"); */ wlandev->rx.probereq++; break; case WLAN_FSTYPE_PROBERESP: - /* printk("proberesp"); */ wlandev->rx.proberesp++; break; case WLAN_FSTYPE_BEACON: - /* printk("beacon"); */ wlandev->rx.beacon++; break; case WLAN_FSTYPE_ATIM: - /* printk("atim"); */ wlandev->rx.atim++; break; case WLAN_FSTYPE_DISASSOC: - /* printk("disassoc"); */ wlandev->rx.disassoc++; break; case WLAN_FSTYPE_AUTHEN: - /* printk("authen"); */ wlandev->rx.authen++; break; case WLAN_FSTYPE_DEAUTHEN: - /* printk("deauthen"); */ wlandev->rx.deauthen++; break; default: - /* printk("unknown"); */ wlandev->rx.mgmt_unknown++; break; } - /* printk("\n"); */ drop = 2; break; @@ -943,35 +930,27 @@ static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc) wlandev->rx.ctl++; switch (fstype) { case WLAN_FSTYPE_PSPOLL: - /* printk("pspoll"); */ wlandev->rx.pspoll++; break; case WLAN_FSTYPE_RTS: - /* printk("rts"); */ wlandev->rx.rts++; break; case WLAN_FSTYPE_CTS: - /* printk("cts"); */ wlandev->rx.cts++; break; case WLAN_FSTYPE_ACK: - /* printk("ack"); */ wlandev->rx.ack++; break; case WLAN_FSTYPE_CFEND: - /* printk("cfend"); */ wlandev->rx.cfend++; break; case WLAN_FSTYPE_CFENDCFACK: - /* printk("cfendcfack"); */ wlandev->rx.cfendcfack++; break; default: - /* printk("unknown"); */ wlandev->rx.ctl_unknown++; break; } - /* printk("\n"); */ drop = 2; break; @@ -1007,7 +986,6 @@ static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc) wlandev->rx.cfack_cfpoll++; break; default: - /* printk("unknown"); */ wlandev->rx.data_unknown++; break; } -- GitLab From a6f100aa64831f64496e26d55c6337cc7ceb8bfc Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Sun, 23 Oct 2022 16:41:51 +0700 Subject: [PATCH 0114/1480] Staging: rtl8192e: rtl819x_HTProc: fixed missing blank space Added a missing blank space as per the Linux kernel coding-style regulations. The issue was flagged by the checkpatch script as a warning. Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/e6635103e3cf2426220767955b99d2e2b62a7329.1666502177.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_HTProc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index ef3dca51cf99b..b763cf0ba3567 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -70,6 +70,7 @@ static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; void HTUpdateDefaultSetting(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + pHTInfo->bRegShortGI20MHz = 1; pHTInfo->bRegShortGI40MHz = 1; -- GitLab From 354989f7dc1e54abcb3c0e7b47444e03cb060504 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Sun, 23 Oct 2022 16:44:13 +0700 Subject: [PATCH 0115/1480] Staging: rtl8192e: rtl819x_HTProc: fixed alignment matching open parenthesis Aligned multiple statements to match open parenthesis as per Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/98c9e764a4447ab550e5615c48f6a98bf6656b0d.1666502177.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_HTProc.c | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index b763cf0ba3567..a701be8c29237 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -152,8 +152,8 @@ bool IsHTHalfNmodeAPs(struct rtllib_device *ieee) (net->ralink_cap_exist)) retValue = true; else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || (net->broadcom_cap_exist)) retValue = true; else if (net->bssht.bd_rt2rt_aggregation) @@ -540,7 +540,7 @@ void HTOnAssocRsp(struct rtllib_device *ieee) pPeerHTCap, sizeof(struct ht_capab_ele)); #endif HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), - (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); + (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); pHTInfo->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? true : false); @@ -566,9 +566,9 @@ void HTOnAssocRsp(struct rtllib_device *ieee) pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; if (ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) { + (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) { if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || - (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) + (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) pHTInfo->bCurrentAMPDUEnable = false; } @@ -617,7 +617,8 @@ void HTOnAssocRsp(struct rtllib_device *ieee) else pMcsFilter = MCS_FILTER_ALL; ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, - ieee->dot11HTOperationalRateSet, pMcsFilter); + ieee->dot11HTOperationalRateSet, + pMcsFilter); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; pHTInfo->current_op_mode = pPeerHTInfo->OptMode; @@ -644,13 +645,13 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; memset((void *)(&(pHTInfo->SelfHTCap)), 0, - sizeof(pHTInfo->SelfHTCap)); + sizeof(pHTInfo->SelfHTCap)); memset((void *)(&(pHTInfo->SelfHTInfo)), 0, - sizeof(pHTInfo->SelfHTInfo)); + sizeof(pHTInfo->SelfHTInfo)); memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, - sizeof(pHTInfo->PeerHTCapBuf)); + sizeof(pHTInfo->PeerHTCapBuf)); memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, - sizeof(pHTInfo->PeerHTInfoBuf)); + sizeof(pHTInfo->PeerHTInfoBuf)); pHTInfo->sw_bw_in_progress = false; @@ -803,8 +804,8 @@ void HTUseDefaultSetting(struct rtllib_device *ieee) HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, ieee->dot11HTOperationalRateSet); ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, - ieee->dot11HTOperationalRateSet, - MCS_FILTER_ALL); + ieee->dot11HTOperationalRateSet, + MCS_FILTER_ALL); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; } else { -- GitLab From 4a1fc310e739d63d2d28952e358b33adde0d87e4 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Sun, 23 Oct 2022 16:45:37 +0700 Subject: [PATCH 0116/1480] Staging: rtl8192e: rtl819x_HTProc: fixed unnecessary parentheses Fixed multiple unnecessary parentheses as per the Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/d2168b90726dda2f02279a3483b53b8d9b34cb30.1666502177.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_HTProc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index a701be8c29237..62aa8e893c34c 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -285,7 +285,7 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); - pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); + pCapELE = (struct ht_capab_ele *)&posHTCap[4]; *len = 30 + 2; } else { pCapELE = (struct ht_capab_ele *)posHTCap; @@ -644,13 +644,13 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) pHTInfo->current_mpdu_density = pHTInfo->MPDU_Density; pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - memset((void *)(&(pHTInfo->SelfHTCap)), 0, + memset((void *)(&pHTInfo->SelfHTCap), 0, sizeof(pHTInfo->SelfHTCap)); - memset((void *)(&(pHTInfo->SelfHTInfo)), 0, + memset((void *)(&pHTInfo->SelfHTInfo), 0, sizeof(pHTInfo->SelfHTInfo)); - memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, + memset((void *)(&pHTInfo->PeerHTCapBuf), 0, sizeof(pHTInfo->PeerHTCapBuf)); - memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, + memset((void *)(&pHTInfo->PeerHTInfoBuf), 0, sizeof(pHTInfo->PeerHTInfoBuf)); pHTInfo->sw_bw_in_progress = false; @@ -666,7 +666,7 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) pHTInfo->iot_ra_func = 0; { - u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); + u8 *RegHTSuppRateSets = &ieee->RegHTSuppRateSet[0]; RegHTSuppRateSets[0] = 0xFF; RegHTSuppRateSets[1] = 0xFF; -- GitLab From 7872d4236f74ad6df4d2c9189b66f95157e24a9b Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 26 Sep 2022 22:17:29 +0800 Subject: [PATCH 0117/1480] fpga: zynq: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replaced with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. It also sets the defer probe reason which can be checked later through debugfs. It's more simple in error path. Signed-off-by: Yang Yingliang Acked-by: Xu Yilun Link: https://lore.kernel.org/r/20220926141729.2292311-1-yangyingliang@huawei.com Signed-off-by: Xu Yilun --- drivers/fpga/zynq-fpga.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 426aa34c6a0dc..ae0da361e6c62 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -582,11 +582,9 @@ static int zynq_fpga_probe(struct platform_device *pdev) return priv->irq; priv->clk = devm_clk_get(dev, "ref_clk"); - if (IS_ERR(priv->clk)) { - if (PTR_ERR(priv->clk) != -EPROBE_DEFER) - dev_err(dev, "input clock not found\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "input clock not found\n"); err = clk_prepare_enable(priv->clk); if (err) { -- GitLab From 463dd43bc976d1dfaba5cd46b2a10addf8d3b4de Mon Sep 17 00:00:00 2001 From: Ivan Bornyakov Date: Tue, 25 Oct 2022 08:39:46 +0300 Subject: [PATCH 0118/1480] fpga: lattice-sysconfig-spi: add Lattice sysCONFIG FPGA manager Add support to the FPGA manager for programming Lattice ECP5 FPGA over slave SPI sysCONFIG interface. sysCONFIG interface core functionality is separate from both ECP5 and SPI specifics, so support for other FPGAs with different port types can be added in the future. Signed-off-by: Ivan Bornyakov Acked-by: Xu Yilun Link: https://lore.kernel.org/r/20221025053947.2737-2-i.bornyakov@metrotek.ru [yilun.xu@intel.com: remove redundant blank line after kmemdup] Signed-off-by: Xu Yilun --- drivers/fpga/Kconfig | 11 + drivers/fpga/Makefile | 2 + drivers/fpga/lattice-sysconfig-spi.c | 152 ++++++++++ drivers/fpga/lattice-sysconfig.c | 397 +++++++++++++++++++++++++++ drivers/fpga/lattice-sysconfig.h | 39 +++ 5 files changed, 601 insertions(+) create mode 100644 drivers/fpga/lattice-sysconfig-spi.c create mode 100644 drivers/fpga/lattice-sysconfig.c create mode 100644 drivers/fpga/lattice-sysconfig.h diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 6c416955da532..d1a8107fdcb33 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -263,4 +263,15 @@ config FPGA_MGR_MICROCHIP_SPI programming over slave SPI interface with .dat formatted bitstream image. +config FPGA_MGR_LATTICE_SYSCONFIG + tristate + +config FPGA_MGR_LATTICE_SYSCONFIG_SPI + tristate "Lattice sysCONFIG SPI FPGA manager" + depends on SPI + select FPGA_MGR_LATTICE_SYSCONFIG + help + FPGA manager driver support for Lattice FPGAs programming over slave + SPI sysCONFIG interface. + endif # FPGA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 42ae8b58abce7..72e554b4d2f76 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -20,6 +20,8 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA) += zynqmp-fpga.o obj-$(CONFIG_FPGA_MGR_VERSAL_FPGA) += versal-fpga.o obj-$(CONFIG_FPGA_MGR_MICROCHIP_SPI) += microchip-spi.o +obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG) += lattice-sysconfig.o +obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI) += lattice-sysconfig-spi.o obj-$(CONFIG_ALTERA_PR_IP_CORE) += altera-pr-ip-core.o obj-$(CONFIG_ALTERA_PR_IP_CORE_PLAT) += altera-pr-ip-core-plat.o diff --git a/drivers/fpga/lattice-sysconfig-spi.c b/drivers/fpga/lattice-sysconfig-spi.c new file mode 100644 index 0000000000000..2702b26b7f55e --- /dev/null +++ b/drivers/fpga/lattice-sysconfig-spi.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Lattice FPGA programming over slave SPI sysCONFIG interface. + */ + +#include + +#include "lattice-sysconfig.h" + +static const u32 ecp5_spi_max_speed_hz = 60000000; + +static int sysconfig_spi_cmd_transfer(struct sysconfig_priv *priv, + const void *tx_buf, size_t tx_len, + void *rx_buf, size_t rx_len) +{ + struct spi_device *spi = to_spi_device(priv->dev); + + return spi_write_then_read(spi, tx_buf, tx_len, rx_buf, rx_len); +} + +static int sysconfig_spi_bitstream_burst_init(struct sysconfig_priv *priv) +{ + const u8 lsc_bitstream_burst[] = SYSCONFIG_LSC_BITSTREAM_BURST; + struct spi_device *spi = to_spi_device(priv->dev); + struct spi_transfer xfer = {}; + struct spi_message msg; + size_t buf_len; + void *buf; + int ret; + + buf_len = sizeof(lsc_bitstream_burst); + + buf = kmemdup(lsc_bitstream_burst, buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + xfer.len = buf_len; + xfer.tx_buf = buf; + xfer.cs_change = 1; + + spi_message_init_with_transfers(&msg, &xfer, 1); + + /* + * Lock SPI bus for exclusive usage until FPGA programming is done. + * SPI bus will be released in sysconfig_spi_bitstream_burst_complete(). + */ + spi_bus_lock(spi->controller); + + ret = spi_sync_locked(spi, &msg); + if (ret) + spi_bus_unlock(spi->controller); + + kfree(buf); + + return ret; +} + +static int sysconfig_spi_bitstream_burst_write(struct sysconfig_priv *priv, + const char *buf, size_t len) +{ + struct spi_device *spi = to_spi_device(priv->dev); + struct spi_transfer xfer = { + .tx_buf = buf, + .len = len, + .cs_change = 1, + }; + struct spi_message msg; + + spi_message_init_with_transfers(&msg, &xfer, 1); + + return spi_sync_locked(spi, &msg); +} + +static int sysconfig_spi_bitstream_burst_complete(struct sysconfig_priv *priv) +{ + struct spi_device *spi = to_spi_device(priv->dev); + + /* Bitstream burst write is done, release SPI bus */ + spi_bus_unlock(spi->controller); + + /* Toggle CS to finish bitstream write */ + return spi_write(spi, NULL, 0); +} + +static int sysconfig_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *dev_id; + struct device *dev = &spi->dev; + struct sysconfig_priv *priv; + const u32 *spi_max_speed; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spi_max_speed = device_get_match_data(dev); + if (!spi_max_speed) { + dev_id = spi_get_device_id(spi); + if (!dev_id) + return -ENODEV; + + spi_max_speed = (const u32 *)dev_id->driver_data; + } + + if (!spi_max_speed) + return -EINVAL; + + if (spi->max_speed_hz > *spi_max_speed) { + dev_err(dev, "SPI speed %u is too high, maximum speed is %u\n", + spi->max_speed_hz, *spi_max_speed); + return -EINVAL; + } + + priv->dev = dev; + priv->command_transfer = sysconfig_spi_cmd_transfer; + priv->bitstream_burst_write_init = sysconfig_spi_bitstream_burst_init; + priv->bitstream_burst_write = sysconfig_spi_bitstream_burst_write; + priv->bitstream_burst_write_complete = sysconfig_spi_bitstream_burst_complete; + + return sysconfig_probe(priv); +} + +static const struct spi_device_id sysconfig_spi_ids[] = { + { + .name = "sysconfig-ecp5", + .driver_data = (kernel_ulong_t)&ecp5_spi_max_speed_hz, + }, {}, +}; +MODULE_DEVICE_TABLE(spi, sysconfig_spi_ids); + +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id sysconfig_of_ids[] = { + { + .compatible = "lattice,sysconfig-ecp5", + .data = &ecp5_spi_max_speed_hz, + }, {}, +}; +MODULE_DEVICE_TABLE(of, sysconfig_of_ids); +#endif /* IS_ENABLED(CONFIG_OF) */ + +static struct spi_driver lattice_sysconfig_driver = { + .probe = sysconfig_spi_probe, + .id_table = sysconfig_spi_ids, + .driver = { + .name = "lattice_sysconfig_spi_fpga_mgr", + .of_match_table = of_match_ptr(sysconfig_of_ids), + }, +}; +module_spi_driver(lattice_sysconfig_driver); + +MODULE_DESCRIPTION("Lattice sysCONFIG Slave SPI FPGA Manager"); +MODULE_LICENSE("GPL"); diff --git a/drivers/fpga/lattice-sysconfig.c b/drivers/fpga/lattice-sysconfig.c new file mode 100644 index 0000000000000..ba51a60f672fe --- /dev/null +++ b/drivers/fpga/lattice-sysconfig.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Lattice FPGA sysCONFIG interface functions independent of port type. + */ + +#include +#include +#include +#include + +#include "lattice-sysconfig.h" + +static int sysconfig_cmd_write(struct sysconfig_priv *priv, const void *buf, + size_t buf_len) +{ + return priv->command_transfer(priv, buf, buf_len, NULL, 0); +} + +static int sysconfig_cmd_read(struct sysconfig_priv *priv, const void *tx_buf, + size_t tx_len, void *rx_buf, size_t rx_len) +{ + return priv->command_transfer(priv, tx_buf, tx_len, rx_buf, rx_len); +} + +static int sysconfig_read_busy(struct sysconfig_priv *priv) +{ + const u8 lsc_check_busy[] = SYSCONFIG_LSC_CHECK_BUSY; + u8 busy; + int ret; + + ret = sysconfig_cmd_read(priv, lsc_check_busy, sizeof(lsc_check_busy), + &busy, sizeof(busy)); + + return ret ? : busy; +} + +static int sysconfig_poll_busy(struct sysconfig_priv *priv) +{ + int ret, busy; + + ret = read_poll_timeout(sysconfig_read_busy, busy, busy <= 0, + SYSCONFIG_POLL_INTERVAL_US, + SYSCONFIG_POLL_BUSY_TIMEOUT_US, false, priv); + + return ret ? : busy; +} + +static int sysconfig_read_status(struct sysconfig_priv *priv, u32 *status) +{ + const u8 lsc_read_status[] = SYSCONFIG_LSC_READ_STATUS; + __be32 device_status; + int ret; + + ret = sysconfig_cmd_read(priv, lsc_read_status, sizeof(lsc_read_status), + &device_status, sizeof(device_status)); + if (ret) + return ret; + + *status = be32_to_cpu(device_status); + + return 0; +} + +static int sysconfig_poll_status(struct sysconfig_priv *priv, u32 *status) +{ + int ret = sysconfig_poll_busy(priv); + + if (ret) + return ret; + + return sysconfig_read_status(priv, status); +} + +static int sysconfig_poll_gpio(struct gpio_desc *gpio, bool is_active) +{ + int ret, val; + + ret = read_poll_timeout(gpiod_get_value, val, + val < 0 || !!val == is_active, + SYSCONFIG_POLL_INTERVAL_US, + SYSCONFIG_POLL_GPIO_TIMEOUT_US, false, gpio); + + if (val < 0) + return val; + + return ret; +} + +static int sysconfig_gpio_refresh(struct sysconfig_priv *priv) +{ + struct gpio_desc *program = priv->program; + struct gpio_desc *init = priv->init; + struct gpio_desc *done = priv->done; + int ret; + + /* Enter init mode */ + gpiod_set_value(program, 1); + + ret = sysconfig_poll_gpio(init, true); + if (!ret) + ret = sysconfig_poll_gpio(done, false); + + if (ret) + return ret; + + /* Enter program mode */ + gpiod_set_value(program, 0); + + return sysconfig_poll_gpio(init, false); +} + +static int sysconfig_lsc_refresh(struct sysconfig_priv *priv) +{ + static const u8 lsc_refresh[] = SYSCONFIG_LSC_REFRESH; + int ret; + + ret = sysconfig_cmd_write(priv, lsc_refresh, sizeof(lsc_refresh)); + if (ret) + return ret; + + usleep_range(4000, 8000); + + return 0; +} + +static int sysconfig_refresh(struct sysconfig_priv *priv) +{ + struct gpio_desc *program = priv->program; + struct gpio_desc *init = priv->init; + struct gpio_desc *done = priv->done; + + if (program && init && done) + return sysconfig_gpio_refresh(priv); + + return sysconfig_lsc_refresh(priv); +} + +static int sysconfig_isc_enable(struct sysconfig_priv *priv) +{ + u8 isc_enable[] = SYSCONFIG_ISC_ENABLE; + u32 status; + int ret; + + ret = sysconfig_cmd_write(priv, isc_enable, sizeof(isc_enable)); + if (ret) + return ret; + + ret = sysconfig_poll_status(priv, &status); + if (ret) + return ret; + + if (status & SYSCONFIG_STATUS_FAIL) + return -EFAULT; + + return 0; +} + +static int sysconfig_isc_erase(struct sysconfig_priv *priv) +{ + u8 isc_erase[] = SYSCONFIG_ISC_ERASE; + u32 status; + int ret; + + ret = sysconfig_cmd_write(priv, isc_erase, sizeof(isc_erase)); + if (ret) + return ret; + + ret = sysconfig_poll_status(priv, &status); + if (ret) + return ret; + + if (status & SYSCONFIG_STATUS_FAIL) + return -EFAULT; + + return 0; +} + +static int sysconfig_isc_init(struct sysconfig_priv *priv) +{ + int ret = sysconfig_isc_enable(priv); + + if (ret) + return ret; + + return sysconfig_isc_erase(priv); +} + +static int sysconfig_lsc_init_addr(struct sysconfig_priv *priv) +{ + const u8 lsc_init_addr[] = SYSCONFIG_LSC_INIT_ADDR; + + return sysconfig_cmd_write(priv, lsc_init_addr, sizeof(lsc_init_addr)); +} + +static int sysconfig_burst_write_init(struct sysconfig_priv *priv) +{ + return priv->bitstream_burst_write_init(priv); +} + +static int sysconfig_burst_write_complete(struct sysconfig_priv *priv) +{ + return priv->bitstream_burst_write_complete(priv); +} + +static int sysconfig_bitstream_burst_write(struct sysconfig_priv *priv, + const char *buf, size_t count) +{ + int ret = priv->bitstream_burst_write(priv, buf, count); + + if (ret) + sysconfig_burst_write_complete(priv); + + return ret; +} + +static int sysconfig_isc_disable(struct sysconfig_priv *priv) +{ + const u8 isc_disable[] = SYSCONFIG_ISC_DISABLE; + + return sysconfig_cmd_write(priv, isc_disable, sizeof(isc_disable)); +} + +static void sysconfig_cleanup(struct sysconfig_priv *priv) +{ + sysconfig_isc_erase(priv); + sysconfig_refresh(priv); +} + +static int sysconfig_isc_finish(struct sysconfig_priv *priv) +{ + struct gpio_desc *done_gpio = priv->done; + u32 status; + int ret; + + if (done_gpio) { + ret = sysconfig_isc_disable(priv); + if (ret) + return ret; + + return sysconfig_poll_gpio(done_gpio, true); + } + + ret = sysconfig_poll_status(priv, &status); + if (ret) + return ret; + + if ((status & SYSCONFIG_STATUS_DONE) && + !(status & SYSCONFIG_STATUS_BUSY) && + !(status & SYSCONFIG_STATUS_ERR)) + return sysconfig_isc_disable(priv); + + return -EFAULT; +} + +static enum fpga_mgr_states sysconfig_ops_state(struct fpga_manager *mgr) +{ + struct sysconfig_priv *priv = mgr->priv; + struct gpio_desc *done = priv->done; + u32 status; + int ret; + + if (done && (gpiod_get_value(done) > 0)) + return FPGA_MGR_STATE_OPERATING; + + ret = sysconfig_read_status(priv, &status); + if (!ret && (status & SYSCONFIG_STATUS_DONE)) + return FPGA_MGR_STATE_OPERATING; + + return FPGA_MGR_STATE_UNKNOWN; +} + +static int sysconfig_ops_write_init(struct fpga_manager *mgr, + struct fpga_image_info *info, + const char *buf, size_t count) +{ + struct sysconfig_priv *priv = mgr->priv; + struct device *dev = &mgr->dev; + int ret; + + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { + dev_err(dev, "Partial reconfiguration is not supported\n"); + return -EOPNOTSUPP; + } + + /* Enter program mode */ + ret = sysconfig_refresh(priv); + if (ret) { + dev_err(dev, "Failed to go to program mode\n"); + return ret; + } + + /* Enter ISC mode */ + ret = sysconfig_isc_init(priv); + if (ret) { + dev_err(dev, "Failed to go to ISC mode\n"); + return ret; + } + + /* Initialize the Address Shift Register */ + ret = sysconfig_lsc_init_addr(priv); + if (ret) { + dev_err(dev, + "Failed to initialize the Address Shift Register\n"); + return ret; + } + + /* Prepare for bitstream burst write */ + ret = sysconfig_burst_write_init(priv); + if (ret) + dev_err(dev, "Failed to prepare for bitstream burst write\n"); + + return ret; +} + +static int sysconfig_ops_write(struct fpga_manager *mgr, const char *buf, + size_t count) +{ + return sysconfig_bitstream_burst_write(mgr->priv, buf, count); +} + +static int sysconfig_ops_write_complete(struct fpga_manager *mgr, + struct fpga_image_info *info) +{ + struct sysconfig_priv *priv = mgr->priv; + struct device *dev = &mgr->dev; + int ret; + + ret = sysconfig_burst_write_complete(priv); + if (!ret) + ret = sysconfig_poll_busy(priv); + + if (ret) { + dev_err(dev, "Error while waiting bitstream write to finish\n"); + goto fail; + } + + ret = sysconfig_isc_finish(priv); + +fail: + if (ret) + sysconfig_cleanup(priv); + + return ret; +} + +static const struct fpga_manager_ops sysconfig_fpga_mgr_ops = { + .state = sysconfig_ops_state, + .write_init = sysconfig_ops_write_init, + .write = sysconfig_ops_write, + .write_complete = sysconfig_ops_write_complete, +}; + +int sysconfig_probe(struct sysconfig_priv *priv) +{ + struct gpio_desc *program, *init, *done; + struct device *dev = priv->dev; + struct fpga_manager *mgr; + + if (!dev) + return -ENODEV; + + if (!priv->command_transfer || + !priv->bitstream_burst_write_init || + !priv->bitstream_burst_write || + !priv->bitstream_burst_write_complete) { + dev_err(dev, "Essential callback is missing\n"); + return -EINVAL; + } + + program = devm_gpiod_get_optional(dev, "program", GPIOD_OUT_LOW); + if (IS_ERR(program)) + return dev_err_probe(dev, PTR_ERR(program), + "Failed to get PROGRAM GPIO\n"); + + init = devm_gpiod_get_optional(dev, "init", GPIOD_IN); + if (IS_ERR(init)) + return dev_err_probe(dev, PTR_ERR(init), + "Failed to get INIT GPIO\n"); + + done = devm_gpiod_get_optional(dev, "done", GPIOD_IN); + if (IS_ERR(done)) + return dev_err_probe(dev, PTR_ERR(done), + "Failed to get DONE GPIO\n"); + + priv->program = program; + priv->init = init; + priv->done = done; + + mgr = devm_fpga_mgr_register(dev, "Lattice sysCONFIG FPGA Manager", + &sysconfig_fpga_mgr_ops, priv); + + return PTR_ERR_OR_ZERO(mgr); +} +EXPORT_SYMBOL(sysconfig_probe); + +MODULE_DESCRIPTION("Lattice sysCONFIG FPGA Manager Core"); +MODULE_LICENSE("GPL"); diff --git a/drivers/fpga/lattice-sysconfig.h b/drivers/fpga/lattice-sysconfig.h new file mode 100644 index 0000000000000..df47d9a524f63 --- /dev/null +++ b/drivers/fpga/lattice-sysconfig.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LATTICE_SYSCONFIG_H +#define __LATTICE_SYSCONFIG_H + +#define SYSCONFIG_ISC_ENABLE {0xC6, 0x00, 0x00, 0x00} +#define SYSCONFIG_ISC_DISABLE {0x26, 0x00, 0x00, 0x00} +#define SYSCONFIG_ISC_ERASE {0x0E, 0x01, 0x00, 0x00} +#define SYSCONFIG_LSC_READ_STATUS {0x3C, 0x00, 0x00, 0x00} +#define SYSCONFIG_LSC_CHECK_BUSY {0xF0, 0x00, 0x00, 0x00} +#define SYSCONFIG_LSC_REFRESH {0x79, 0x00, 0x00, 0x00} +#define SYSCONFIG_LSC_INIT_ADDR {0x46, 0x00, 0x00, 0x00} +#define SYSCONFIG_LSC_BITSTREAM_BURST {0x7a, 0x00, 0x00, 0x00} + +#define SYSCONFIG_STATUS_DONE BIT(8) +#define SYSCONFIG_STATUS_BUSY BIT(12) +#define SYSCONFIG_STATUS_FAIL BIT(13) +#define SYSCONFIG_STATUS_ERR GENMASK(25, 23) + +#define SYSCONFIG_POLL_INTERVAL_US 30 +#define SYSCONFIG_POLL_BUSY_TIMEOUT_US 1000000 +#define SYSCONFIG_POLL_GPIO_TIMEOUT_US 100000 + +struct sysconfig_priv { + struct gpio_desc *program; + struct gpio_desc *init; + struct gpio_desc *done; + struct device *dev; + int (*command_transfer)(struct sysconfig_priv *priv, const void *tx_buf, + size_t tx_len, void *rx_buf, size_t rx_len); + int (*bitstream_burst_write_init)(struct sysconfig_priv *priv); + int (*bitstream_burst_write)(struct sysconfig_priv *priv, + const char *tx_buf, size_t tx_len); + int (*bitstream_burst_write_complete)(struct sysconfig_priv *priv); +}; + +int sysconfig_probe(struct sysconfig_priv *priv); + +#endif /* __LATTICE_SYSCONFIG_H */ -- GitLab From ee31d5038c06b56ea515f4fe490274628c0f80e1 Mon Sep 17 00:00:00 2001 From: Ivan Bornyakov Date: Tue, 25 Oct 2022 08:39:47 +0300 Subject: [PATCH 0119/1480] dt-bindings: fpga: document Lattice sysCONFIG FPGA manager Add Device Tree Binding doc for configuring Lattice ECP5 FPGA over Slave SPI sysCONFIG interface. Signed-off-by: Ivan Bornyakov Reviewed-by: Krzysztof Kozlowski Acked-by: Xu Yilun Link: https://lore.kernel.org/r/20221025053947.2737-3-i.bornyakov@metrotek.ru Signed-off-by: Xu Yilun --- .../bindings/fpga/lattice,sysconfig.yaml | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Documentation/devicetree/bindings/fpga/lattice,sysconfig.yaml diff --git a/Documentation/devicetree/bindings/fpga/lattice,sysconfig.yaml b/Documentation/devicetree/bindings/fpga/lattice,sysconfig.yaml new file mode 100644 index 0000000000000..4fb05eb84e2af --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/lattice,sysconfig.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/fpga/lattice,sysconfig.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lattice Slave SPI sysCONFIG FPGA manager + +maintainers: + - Ivan Bornyakov + +description: | + Lattice sysCONFIG port, which is used for FPGA configuration, among others, + have Slave Serial Peripheral Interface. Only full reconfiguration is + supported. + + Programming of ECP5 is done by writing uncompressed bitstream image in .bit + format into FPGA's SRAM configuration memory. + +properties: + compatible: + enum: + - lattice,sysconfig-ecp5 + + reg: + maxItems: 1 + + program-gpios: + description: + A GPIO line connected to PROGRAMN (active low) pin of the device. + Initiates configuration sequence. + maxItems: 1 + + init-gpios: + description: + A GPIO line connected to INITN (active low) pin of the device. + Indicates that the FPGA is ready to be configured. + maxItems: 1 + + done-gpios: + description: + A GPIO line connected to DONE (active high) pin of the device. + Indicates that the configuration sequence is complete. + maxItems: 1 + +required: + - compatible + - reg + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml + + - if: + properties: + compatible: + contains: + const: lattice,sysconfig-ecp5 + then: + properties: + spi-max-frequency: + maximum: 60000000 + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + fpga-mgr@0 { + compatible = "lattice,sysconfig-ecp5"; + reg = <0>; + spi-max-frequency = <20000000>; + program-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + init-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>; + done-gpios = <&gpio3 2 GPIO_ACTIVE_HIGH>; + }; + }; -- GitLab From 848dba781f1951636c966c9f3a6a41a5b2f8b572 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 24 Oct 2022 14:39:33 +0200 Subject: [PATCH 0120/1480] container_of: remove container_of_safe() It came in from a staging driver that has been long removed from the tree, and there are no in-kernel users of the macro, and it's very dubious if anyone should ever use this thing, so just remove it entirely. Reviewed-by: Sakari Ailus Acked-by: Rafael J. Wysocki Acked-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221024123933.3331116-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/container_of.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/include/linux/container_of.h b/include/linux/container_of.h index 2f4944b791b81..a6f242137b116 100644 --- a/include/linux/container_of.h +++ b/include/linux/container_of.h @@ -21,20 +21,4 @@ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); }) -/** - * container_of_safe - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged. - */ -#define container_of_safe(ptr, type, member) ({ \ - void *__mptr = (void *)(ptr); \ - static_assert(__same_type(*(ptr), ((type *)0)->member) || \ - __same_type(*(ptr), void), \ - "pointer type mismatch in container_of_safe()"); \ - IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) : \ - ((type *)(__mptr - offsetof(type, member))); }) - #endif /* _LINUX_CONTAINER_OF_H */ -- GitLab From 7376e561fd2e017e9a53f975209777234b8b434e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 24 Oct 2022 14:16:27 +0300 Subject: [PATCH 0121/1480] linux/container_of.h: Warn about loss of constness container_of() casts the original type to another which leads to the loss of the const qualifier if it is not specified in the caller-provided type. This easily leads to container_of() returning a non-const pointer to a const struct which the C compiler does not warn about. Acked-by: Andy Shevchenko Signed-off-by: Sakari Ailus Link: https://lore.kernel.org/r/20221024111627.75183-1-sakari.ailus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/container_of.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/container_of.h b/include/linux/container_of.h index a6f242137b116..2008e9f4058c6 100644 --- a/include/linux/container_of.h +++ b/include/linux/container_of.h @@ -13,6 +13,7 @@ * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * + * WARNING: any const qualifier of @ptr is lost. */ #define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ -- GitLab From 2ae18cc2269fc2d05d36bf44a8daa4404fa11dde Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 24 Oct 2022 10:48:46 +0300 Subject: [PATCH 0122/1480] thunderbolt: ACPI: Use the helper fwnode_find_reference() Replacing the direct fwnode_property_get_reference_args() call will this wrapper function. No functional changes intended. Signed-off-by: Heikki Krogerus Signed-off-by: Mika Westerberg --- drivers/thunderbolt/acpi.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/acpi.c b/drivers/thunderbolt/acpi.c index 7a8adf5ad5a09..317e4f5fdb979 100644 --- a/drivers/thunderbolt/acpi.c +++ b/drivers/thunderbolt/acpi.c @@ -15,24 +15,20 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, void **return_value) { struct acpi_device *adev = acpi_fetch_acpi_dev(handle); - struct fwnode_reference_args args; struct fwnode_handle *fwnode; struct tb_nhi *nhi = data; struct pci_dev *pdev; struct device *dev; - int ret; if (!adev) return AE_OK; - fwnode = acpi_fwnode_handle(adev); - ret = fwnode_property_get_reference_args(fwnode, "usb4-host-interface", - NULL, 0, 0, &args); - if (ret) + fwnode = fwnode_find_reference(acpi_fwnode_handle(adev), "usb4-host-interface", 0); + if (IS_ERR(fwnode)) return AE_OK; /* It needs to reference this NHI */ - if (dev_fwnode(&nhi->pdev->dev) != args.fwnode) + if (dev_fwnode(&nhi->pdev->dev) != fwnode) goto out_put; /* @@ -100,7 +96,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, } out_put: - fwnode_handle_put(args.fwnode); + fwnode_handle_put(fwnode); return AE_OK; } -- GitLab From 1662cea4623f75d8251adf07370bbaa958f0355d Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 25 Oct 2022 15:15:49 +0800 Subject: [PATCH 0123/1480] kset: fix memory leak when kset_register() returns error Inject fault while loading module, kset_register() may fail. If it fails, the kset.kobj.name allocated by kobject_set_name() which must be called before a call to kset_register() may be leaked, since refcount of kobj was set in kset_init(). To mitigate this, we free the name in kset_register() when an error is encountered, i.e. when kset_register() returns an error. A kset may be embedded in a larger structure which may be dynamically allocated in callers, it needs to be freed in ktype.release() or error path in callers, in this case, we can not call kset_put() in kset_register(), or it will cause double free, so just call kfree_const() to free the name and set it to NULL to avoid accessing bad pointer in callers. With this fix, the callers don't need care about freeing the name and may call kset_put() if kset_register() fails. Suggested-by: Luben Tuikov Signed-off-by: Yang Yingliang Reviewed-by: Link: https://lore.kernel.org/r/20221025071549.1280528-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/kobject.c b/lib/kobject.c index 0380ec889a6af..ba1017cd67d16 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -834,6 +834,9 @@ EXPORT_SYMBOL_GPL(kobj_sysfs_ops); /** * kset_register() - Initialize and add a kset. * @k: kset. + * + * NOTE: On error, the kset.kobj.name allocated by() kobj_set_name() + * is freed, it can not be used any more. */ int kset_register(struct kset *k) { @@ -844,8 +847,12 @@ int kset_register(struct kset *k) kset_init(k); err = kobject_add_internal(&k->kobj); - if (err) + if (err) { + kfree_const(k->kobj.name); + /* Set it to NULL to avoid accessing bad pointer in callers. */ + k->kobj.name = NULL; return err; + } kobject_uevent(&k->kobj, KOBJ_ADD); return 0; } -- GitLab From a12960f970d3d47d1aefd4293738b878a6e7d024 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:01 +0200 Subject: [PATCH 0124/1480] staging: r8188eu: restructure mlme subfunction handling Move some code around in rtw_mlme_ext.c to make it simpler. mlme_sta_tbl is used only by mgt_dispatcher. Move the table inside the function. Move mgt_dispatcher behind the handler functions. We can then make the handler functions static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 116 ++++++++++---------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index d146b94307b80..3435610ca4116 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -12,24 +12,6 @@ #include "../include/rtl8188e_xmit.h" #include "../include/rtl8188e_dm.h" -/* response function for each management frame subtype, do not reorder */ -static mlme_handler mlme_sta_tbl[] = { - OnAssocReq, - OnAssocRsp, - OnAssocReq, - OnAssocRsp, - OnProbeReq, - OnProbeRsp, - NULL, - NULL, - OnBeacon, - NULL, - OnDisassoc, - OnAuthClient, - OnDeAuth, - OnAction, -}; - static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; /************************************************** @@ -393,47 +375,6 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) } } -void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) -{ - int index; - mlme_handler fct; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2); - - if (!ieee80211_is_mgmt(hdr->frame_control)) - return; - - /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ - if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN) && - !is_broadcast_ether_addr(hdr->addr1)) - return; - - index = (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) >> 4; - if (index >= ARRAY_SIZE(mlme_sta_tbl)) - return; - fct = mlme_sta_tbl[index]; - - if (psta) { - if (ieee80211_has_retry(hdr->frame_control)) { - if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) - /* drop the duplicate management frame */ - return; - } - psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num; - } - - if (ieee80211_is_auth(hdr->frame_control)) { - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) - fct = OnAuth; - else - fct = OnAuthClient; - } - - if (fct) - fct(padapter, precv_frame); -} - static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da) { bool response = true; @@ -4008,6 +3949,63 @@ struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) return pmgntframe; } +void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) +{ + mlme_handler mlme_sta_tbl[] = { + OnAssocReq, + OnAssocRsp, + OnAssocReq, + OnAssocRsp, + OnProbeReq, + OnProbeRsp, + NULL, + NULL, + OnBeacon, + NULL, + OnDisassoc, + OnAuthClient, + OnDeAuth, + OnAction, + }; + int index; + mlme_handler fct; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2); + + if (!ieee80211_is_mgmt(hdr->frame_control)) + return; + + /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ + if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN) && + !is_broadcast_ether_addr(hdr->addr1)) + return; + + index = (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) >> 4; + if (index >= ARRAY_SIZE(mlme_sta_tbl)) + return; + fct = mlme_sta_tbl[index]; + + if (psta) { + if (ieee80211_has_retry(hdr->frame_control)) { + if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) + /* drop the duplicate management frame */ + return; + } + psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num; + } + + if (ieee80211_is_auth(hdr->frame_control)) { + if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) + fct = OnAuth; + else + fct = OnAuthClient; + } + + if (fct) + fct(padapter, precv_frame); +} + /**************************************************************************** Following are some TX functions for WiFi MLME -- GitLab From b8d4f50557d52fff6356e8a83d50283232eedb98 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:02 +0200 Subject: [PATCH 0125/1480] staging: r8188eu: make OnAssocReq static OnAssocReq is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 3435610ca4116..576f56ad43838 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -911,7 +911,7 @@ static void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen) } } -unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) { u16 capab_info; struct rtw_ieee802_11_elems elems; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 66aa8b497aa1d..41e31cec9abe4 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnAssocReq(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnProbeReq(struct adapter *padapter, -- GitLab From 411c3890cb0d385bcd8ddef90abac82a32274153 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:03 +0200 Subject: [PATCH 0126/1480] staging: r8188eu: make OnAssocRsp static OnAssocRsp is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 576f56ad43838..a3cfab2627d54 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1319,7 +1319,7 @@ OnAssocReqFail: return _FAIL; } -unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; uint i; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 41e31cec9abe4..c2b1aa2f378bf 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnAssocRsp(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnProbeRsp(struct adapter *padapter, -- GitLab From 94941c42c24813da86128f47bec0949184798b62 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:04 +0200 Subject: [PATCH 0127/1480] staging: r8188eu: make OnProbeReq static OnProbeReq is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index a3cfab2627d54..5e1e2970ccd9b 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -447,7 +447,7 @@ Following are the callback functions for each subtype of the management frames *****************************************************************************/ -unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int ielen; unsigned char *p; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index c2b1aa2f378bf..b24aae8108b60 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnProbeReq(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnBeacon(struct adapter *padapter, -- GitLab From bd0bd67c6bd8e2e5f1a3741f3d323e58ea3fc7ff Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:05 +0200 Subject: [PATCH 0128/1480] staging: r8188eu: make OnProbeRsp static OnProbeRsp is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 5e1e2970ccd9b..4ccc6c6e45e6c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -515,7 +515,7 @@ _issue_probersp: return _SUCCESS; } -unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct wifidirect_info *pwdinfo = &padapter->wdinfo; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index b24aae8108b60..52991ec7b3e84 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnProbeRsp(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnDisassoc(struct adapter *padapter, -- GitLab From 1aad70df18457dfbd4244dbe620f6f12429e32d5 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:06 +0200 Subject: [PATCH 0129/1480] staging: r8188eu: make OnBeacon static OnBeacon is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 4ccc6c6e45e6c..1a279c812f5ff 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -561,7 +561,7 @@ static unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *prec return _SUCCESS; } -unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) { int cam_idx; struct sta_info *psta; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 52991ec7b3e84..b4868598eba85 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnBeacon(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnAuth(struct adapter *padapter, -- GitLab From 8ef3cd4f527c76832fefa2bb9960b5afb5f0a1d0 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:07 +0200 Subject: [PATCH 0130/1480] staging: r8188eu: make OnDisassoc static OnDisassoc is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 1a279c812f5ff..309376aba41fe 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1458,7 +1458,7 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) return _SUCCESS; } -unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) { u16 reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index b4868598eba85..c1bc554202a03 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnDisassoc(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnAuthClient(struct adapter *padapter, -- GitLab From de20e195c221c808f7d9e2babe6f4cd9e7c92818 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:08 +0200 Subject: [PATCH 0131/1480] staging: r8188eu: make OnAuthClient static OnAuthClient is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 309376aba41fe..a63146ccc6b42 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -800,7 +800,7 @@ auth_fail: return _FAIL; } -unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int seq, len, status, offset; unsigned char *p; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index c1bc554202a03..866d358f5f100 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -538,8 +538,6 @@ void start_create_ibss(struct adapter *padapter); unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame); -unsigned int OnAuthClient(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int OnAction(struct adapter *padapter, -- GitLab From 51877bf3ab4ccd0279fedbf97736791234ed0cfe Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:09 +0200 Subject: [PATCH 0132/1480] staging: r8188eu: make OnDeAuth static OnDeAuth is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index a63146ccc6b42..df817d7594a24 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1396,7 +1396,7 @@ report_assoc_result: return _SUCCESS; } -unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; unsigned short reason; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 866d358f5f100..14df835744783 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -538,8 +538,6 @@ void start_create_ibss(struct adapter *padapter); unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame); -unsigned int OnDeAuth(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame); -- GitLab From 37552ad1fa2ed3924364e54f99f31ee56d902bcb Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:10 +0200 Subject: [PATCH 0133/1480] staging: r8188eu: make OnAction static OnAction is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-11-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index df817d7594a24..0eb7f586d755c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3910,7 +3910,7 @@ unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fra return _SUCCESS; } -unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 14df835744783..f192733a5c539 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -538,8 +538,6 @@ void start_create_ibss(struct adapter *padapter); unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame); -unsigned int OnAction(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame); -- GitLab From 19adbd9a2f26a64be96702f488ebed77b5334f79 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:11 +0200 Subject: [PATCH 0134/1480] staging: r8188eu: make OnAuth static OnAuth is used only in rtw_mlme_ext.c. Make this function static. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-12-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 0eb7f586d755c..be34c3b21bd7c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -651,7 +651,7 @@ _END_ONBEACON_: return _SUCCESS; } -unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) +static unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int auth_mode, ie_len; u16 seq; diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index f192733a5c539..f77e6dc81831f 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,9 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnAuth(struct adapter *padapter, - struct recv_frame *precv_frame); - unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame); unsigned int on_action_public(struct adapter *padapter, -- GitLab From 05aa6bf9c2546379f8ba57e2ffe8f88082d50a52 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:12 +0200 Subject: [PATCH 0135/1480] staging: r8188eu: change mlme handlers to void The mlme handlers that are called from mgt_dispatcher return an error code. mgt_dispatcher doesn't check this error code, we can remove it and change the handler functions to void. For now, make only the minimum changes to the handlers for removing the error codes. If handlers can be simplified, that'll be done it separate patches. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-13-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 93 ++++++++----------- .../staging/r8188eu/include/rtw_mlme_ext.h | 2 +- 2 files changed, 41 insertions(+), 54 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index be34c3b21bd7c..d89f494d12af8 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -447,7 +447,7 @@ Following are the callback functions for each subtype of the management frames *****************************************************************************/ -static unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int ielen; unsigned char *p; @@ -481,17 +481,17 @@ static unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *prec report_survey_event(padapter, precv_frame); p2p_listen_state_process(padapter, get_sa(pframe)); - return _SUCCESS; + return; } } } if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - return _SUCCESS; + return; if (!check_fwstate(pmlmepriv, _FW_LINKED) && !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) - return _SUCCESS; + return; p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); @@ -503,7 +503,7 @@ static unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *prec if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) - return _SUCCESS; + return; _issue_probersp: @@ -512,10 +512,9 @@ _issue_probersp: check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); } - return _SUCCESS; } -static unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct wifidirect_info *pwdinfo = &padapter->wdinfo; @@ -537,7 +536,7 @@ static unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *prec } } } - return _SUCCESS; + return; } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { if (pwdinfo->nego_req_info.benable) { if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) { @@ -555,13 +554,11 @@ static unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *prec } if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { report_survey_event(padapter, precv_frame); - return _SUCCESS; + return; } - - return _SUCCESS; } -static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) { int cam_idx; struct sta_info *psta; @@ -576,7 +573,7 @@ static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { report_survey_event(padapter, precv_frame); - return _SUCCESS; + return; } if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { @@ -600,7 +597,7 @@ static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_ /* start auth */ start_clnt_auth(padapter); - return _SUCCESS; + return; } if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { @@ -610,7 +607,7 @@ static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_ if (!ret) { receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); - return _SUCCESS; + return; } /* update WMM, ERP in the beacon */ /* todo: the timer is used instead of the number of the beacon received */ @@ -629,12 +626,12 @@ static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_ /* allocate a new CAM entry for IBSS station */ cam_idx = allocate_fw_sta_entry(padapter); if (cam_idx == NUM_STA) - goto _END_ONBEACON_; + return; /* get supported rate */ if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) { pmlmeinfo->FW_sta_info[cam_idx].status = 0; - goto _END_ONBEACON_; + return; } /* update TSF Value */ @@ -645,13 +642,9 @@ static unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_ } } } - -_END_ONBEACON_: - - return _SUCCESS; } -static unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int auth_mode, ie_len; u16 seq; @@ -668,7 +661,7 @@ static unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_fr uint len = precv_frame->len; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) - return _FAIL; + return; sa = GetAddr2Ptr(pframe); @@ -784,7 +777,7 @@ static unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_fr if (pstat->state & WIFI_FW_AUTH_SUCCESS) pstat->auth_seq = 0; - return _SUCCESS; + return; auth_fail: @@ -797,10 +790,9 @@ auth_fail: memcpy(pstat->hwaddr, sa, 6); issue_auth(padapter, pstat, (unsigned short)status); - return _FAIL; } -static unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) { unsigned int seq, len, status, offset; unsigned char *p; @@ -812,10 +804,10 @@ static unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *pr /* check A1 matches or not */ if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) - return _SUCCESS; + return; if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) - return _SUCCESS; + return; offset = (GetPrivacy(pframe)) ? 4 : 0; @@ -848,7 +840,7 @@ static unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *pr issue_auth(padapter, NULL, 0); set_link_timer(pmlmeext, REAUTH_TO); - return _SUCCESS; + return; } else { /* open system */ go2asoc = 1; @@ -865,10 +857,10 @@ static unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *pr if (go2asoc) { start_clnt_assoc(padapter); - return _SUCCESS; + return; } authclnt_fail: - return _FAIL; + return; } static void UpdateBrateTbl(u8 *mbrate) @@ -911,7 +903,7 @@ static void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen) } } -static unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) { u16 capab_info; struct rtw_ieee802_11_elems elems; @@ -937,7 +929,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *prec u32 p2pielen = 0; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) - return _FAIL; + return; frame_type = GetFrameSubType(pframe); if (frame_type == WIFI_ASSOCREQ) @@ -946,7 +938,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *prec ie_offset = _REASOCREQ_IE_OFFSET_; if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) - return _FAIL; + return; pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); if (pstat == (struct sta_info *)NULL) { @@ -1300,13 +1292,13 @@ static unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *prec report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); } - return _SUCCESS; + return; asoc_class2_error: issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); - return _FAIL; + return; OnAssocReqFail: @@ -1316,10 +1308,10 @@ OnAssocReqFail: else issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); - return _FAIL; + return; } -static unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; uint i; @@ -1333,13 +1325,13 @@ static unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *prec /* check A1 matches or not */ if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) - return _SUCCESS; + return; if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) - return _SUCCESS; + return; if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - return _SUCCESS; + return; _cancel_timer_ex(&pmlmeext->link_timer); @@ -1392,11 +1384,9 @@ static unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *prec report_assoc_result: report_join_res(padapter, res); - - return _SUCCESS; } -static unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; unsigned short reason; @@ -1406,7 +1396,7 @@ static unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_ struct wifidirect_info *pwdinfo = &padapter->wdinfo; if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) - return _SUCCESS; + return; if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); @@ -1422,7 +1412,7 @@ static unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_ psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (!psta) - return _SUCCESS; + return; spin_lock_bh(&pstapriv->asoc_list_lock); if (!list_empty(&psta->asoc_list)) { @@ -1455,10 +1445,9 @@ static unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } - return _SUCCESS; } -static unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) { u16 reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1469,7 +1458,7 @@ static unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *prec /* check A3 */ if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) - return _SUCCESS; + return; if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); @@ -1497,12 +1486,11 @@ static unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *prec associated_clients_update(padapter, updated); } - return _SUCCESS; + return; } else { receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); } pmlmepriv->LinkDetectInfo.bBusyTraffic = false; - return _SUCCESS; } unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) @@ -3910,7 +3898,7 @@ unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fra return _SUCCESS; } -static unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; @@ -3925,7 +3913,6 @@ static unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_ OnAction_p2p(padapter, precv_frame); break; } - return _SUCCESS; } struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index f77e6dc81831f..c8beaa927cba1 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -184,7 +184,7 @@ enum SCAN_STATE { SCAN_STATE_MAX, }; -typedef unsigned int (*mlme_handler)(struct adapter *adapt, struct recv_frame *frame); +typedef void (*mlme_handler)(struct adapter *adapt, struct recv_frame *frame); struct ss_res { int state; -- GitLab From 2d64ae536ef0c78924fdd99e0bb3018d7b6b3178 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:13 +0200 Subject: [PATCH 0136/1480] staging: r8188eu: remove unnecessary label Remove a label on OnAuthClient that just calls return. We can return directly instead of jumping to this label. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-14-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index d89f494d12af8..e2e7c35019f2e 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -823,7 +823,7 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram } set_link_timer(pmlmeext, 1); - goto authclnt_fail; + return; } if (seq == 2) { @@ -833,7 +833,7 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); if (!p) - goto authclnt_fail; + return; memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); pmlmeinfo->auth_seq = 3; @@ -849,18 +849,16 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) go2asoc = 1; else - goto authclnt_fail; + return; } else { /* this is also illegal */ - goto authclnt_fail; + return; } if (go2asoc) { start_clnt_assoc(padapter); return; } -authclnt_fail: - return; } static void UpdateBrateTbl(u8 *mbrate) -- GitLab From 3cf90ead512362a1b2b4b9a0d48ec47ca26744c2 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:14 +0200 Subject: [PATCH 0137/1480] staging: r8188eu: remove unnecessary else branch Remove an else branch in OnAuthClient that is not needed. If we go into the else branch, go2asoc is 0. We can simply continue and the last if condition will be false. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-15-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index e2e7c35019f2e..6ac3e41af992f 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -850,9 +850,6 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram go2asoc = 1; else return; - } else { - /* this is also illegal */ - return; } if (go2asoc) { -- GitLab From cb2cff04d040eb02555c3c51a045fa31f4cc0e79 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:15 +0200 Subject: [PATCH 0138/1480] staging: r8188eu: remove unnecessary return Remove a return statement at the end of a function. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-16-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 6ac3e41af992f..a93133a9ca567 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -852,10 +852,8 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram return; } - if (go2asoc) { + if (go2asoc) start_clnt_assoc(padapter); - return; - } } static void UpdateBrateTbl(u8 *mbrate) -- GitLab From d667d36d689eb3b0cd1bd0d09b36cbad9625f10b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:16 +0200 Subject: [PATCH 0139/1480] staging: r8188eu: remove an else branch If we go into this else branch, go2asoc is 0. We can continue to the end of the function. The final if condition will be false. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-17-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index a93133a9ca567..ba95d2391319b 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -848,8 +848,6 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram } else if (seq == 4) { if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) go2asoc = 1; - else - return; } if (go2asoc) -- GitLab From 8d5c6a1df1204280354bfb59316fd056e978a864 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 24 Oct 2022 10:14:17 +0200 Subject: [PATCH 0140/1480] staging: r8188eu: go2asoc is not needed Remove the go2asoc variable in OnAuthClient and call start_clnt_assoc directly. This makes the code a tiny bit shorter. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221024081417.66441-18-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index ba95d2391319b..254832a0177e7 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -796,7 +796,6 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram { unsigned int seq, len, status, offset; unsigned char *p; - unsigned int go2asoc = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->rx_data; @@ -843,15 +842,12 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram return; } else { /* open system */ - go2asoc = 1; + start_clnt_assoc(padapter); } } else if (seq == 4) { if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) - go2asoc = 1; + start_clnt_assoc(padapter); } - - if (go2asoc) - start_clnt_assoc(padapter); } static void UpdateBrateTbl(u8 *mbrate) -- GitLab From ec6d91016437fe8e5fdcb8cc60c14887e588998f Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 23 Oct 2022 19:08:04 +0200 Subject: [PATCH 0141/1480] staging: r8188eu: use standard multicast addr check Use is_multicast_ether_addr to check for a multicast address instead of reimplementing this check in the driver. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221023170808.46233-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_sta_mgt.c | 2 +- drivers/staging/r8188eu/include/wifi.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c index bbde5c03f9ae0..51324e708697f 100644 --- a/drivers/staging/r8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/r8188eu/core/rtw_sta_mgt.c @@ -404,7 +404,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) if (!hwaddr) return NULL; - if (IS_MCAST(hwaddr)) + if (is_multicast_ether_addr(hwaddr)) addr = bc_addr; else addr = hwaddr; diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index 381385a7e1189..fdb7c1bf3573c 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -236,11 +236,6 @@ enum WIFI_REG_DOMAIN { #define GetAddr4Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 24)) -static inline bool IS_MCAST(unsigned char *da) -{ - return (*da) & 0x01; -} - static inline unsigned char *get_da(unsigned char *pframe) { unsigned char *da; -- GitLab From 2ce164e9b363ee845287b7e693a1f9e7429ecc08 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 23 Oct 2022 19:08:05 +0200 Subject: [PATCH 0142/1480] staging: r8188eu: don't set pcmd_obj components to 0 pcmd_obj was allocated with kzalloc, its memory is filled with 0s. There's no need to set rsp and rspsz to NULL or 0 again. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221023170808.46233-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 254832a0177e7..6c71fbfec32d1 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -6725,9 +6725,6 @@ void report_join_res(struct adapter *padapter, int res) pcmd_obj->cmdsz = cmdsz; pcmd_obj->parmbuf = pevtcmd; - pcmd_obj->rsp = NULL; - pcmd_obj->rspsz = 0; - pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); pc2h_evt_hdr->len = sizeof(struct joinbss_event); pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); -- GitLab From 9e9e26190ee651ba868281ae16eab5dc1bcecf0e Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 23 Oct 2022 19:08:06 +0200 Subject: [PATCH 0143/1480] staging: r8188eu: NetworkTypeInUse is not in use NetworkTypeInUse from struct wlan_bssid_ex is not used. Remove NetworkTypeInUse itself, the code to set it and the enum for its possible values. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221023170808.46233-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme.c | 16 ---------------- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- drivers/staging/r8188eu/include/wlan_bssdef.h | 9 --------- 3 files changed, 28 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c index 1f69e5c57d5d5..a47ae33454b3d 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme.c +++ b/drivers/staging/r8188eu/core/rtw_mlme.c @@ -1819,22 +1819,6 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter) pdev_network->Rssi = 0; - switch (pregistrypriv->wireless_mode) { - case WIRELESS_11B: - pdev_network->NetworkTypeInUse = (Ndis802_11DS); - break; - case WIRELESS_11G: - case WIRELESS_11BG: - case WIRELESS_11_24N: - case WIRELESS_11G_24N: - case WIRELESS_11BG_24N: - pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); - break; - default: - /* TODO */ - break; - } - pdev_network->Configuration.DSConfig = (pregistrypriv->channel); if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 6c71fbfec32d1..fc37d17f8c7e9 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -6160,9 +6160,6 @@ u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, st memcpy(bssid->SupportedRates + i, (p + 2), len); } - /* todo: */ - bssid->NetworkTypeInUse = Ndis802_11OFDM24; - if (bssid->IELength < 12) return _FAIL; diff --git a/drivers/staging/r8188eu/include/wlan_bssdef.h b/drivers/staging/r8188eu/include/wlan_bssdef.h index 81bda91a4136b..831c465df5001 100644 --- a/drivers/staging/r8188eu/include/wlan_bssdef.h +++ b/drivers/staging/r8188eu/include/wlan_bssdef.h @@ -17,14 +17,6 @@ struct ndis_802_11_ssid { u8 Ssid[32]; }; -enum NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax /* dummy upper bound */ -}; - struct ndis_802_11_config_fh { u32 Length; /* Length of structure */ u32 HopPattern; /* As defined by 802.11, MSB set */ @@ -233,7 +225,6 @@ struct wlan_bssid_ex { struct ndis_802_11_ssid Ssid; u32 Privacy; NDIS_802_11_RSSI Rssi;/* in dBM,raw data ,get from PHY) */ - enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; struct ndis_802_11_config Configuration; enum ndis_802_11_network_infra InfrastructureMode; unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; -- GitLab From e329c18341b72c8386a1a25f8176ec541e66bf2b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 23 Oct 2022 19:08:07 +0200 Subject: [PATCH 0144/1480] staging: r8188eu: remove wait_ack param from _issue_probereq_p2p The only caller of _issue_probereq_p2p sets wait_ack = false. Remove the wait_ack parameter and the code that would run only if wait_ack == true. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221023170808.46233-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index fc37d17f8c7e9..ffb708f242e6c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3207,7 +3207,7 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da) dump_mgntframe(padapter, pmgntframe); } -static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack) +static int _issue_probereq_p2p(struct adapter *padapter, u8 *da) { int ret = _FAIL; struct xmit_frame *pmgntframe; @@ -3480,12 +3480,8 @@ static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack) pattrib->last_txcmdsz = pattrib->pktlen; - if (wait_ack) { - ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); - } else { - dump_mgntframe(padapter, pmgntframe); - ret = _SUCCESS; - } + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; exit: return ret; @@ -3493,7 +3489,7 @@ exit: inline void issue_probereq_p2p(struct adapter *adapter, u8 *da) { - _issue_probereq_p2p(adapter, da, false); + _issue_probereq_p2p(adapter, da); } static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) -- GitLab From 5229004f800219e849969eaa8197dff3b55f4b02 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 23 Oct 2022 19:08:08 +0200 Subject: [PATCH 0145/1480] staging: r8188eu: bCardDisableWOHSM is write-only bCardDisableWOHSM in struct adapter is only written but never read. It can be removed. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221023170808.46233-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/drv_types.h | 1 - drivers/staging/r8188eu/os_dep/os_intfs.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/drivers/staging/r8188eu/include/drv_types.h b/drivers/staging/r8188eu/include/drv_types.h index 1bd0c8f3a3588..8fef5759c36ae 100644 --- a/drivers/staging/r8188eu/include/drv_types.h +++ b/drivers/staging/r8188eu/include/drv_types.h @@ -167,7 +167,6 @@ struct adapter { s32 bDriverStopped; s32 bSurpriseRemoved; - s32 bCardDisableWOHSM; u8 hw_init_completed; s8 signal_strength; diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 38e324754c8fa..970f380bac961 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -620,7 +620,6 @@ static int _netdev_open(struct net_device *pnetdev) if (!padapter->bup) { padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; - padapter->bCardDisableWOHSM = false; status = rtw_hal_init(padapter); if (status == _FAIL) @@ -686,7 +685,6 @@ static int ips_netdrv_open(struct adapter *padapter) padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; - padapter->bCardDisableWOHSM = false; status = rtw_hal_init(padapter); if (status == _FAIL) @@ -718,13 +716,11 @@ int rtw_ips_pwr_up(struct adapter *padapter) void rtw_ips_pwr_down(struct adapter *padapter) { - padapter->bCardDisableWOHSM = true; padapter->net_closed = true; rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); - padapter->bCardDisableWOHSM = false; } static void rtw_fifo_cleanup(struct adapter *adapter) -- GitLab From db213ea614e0b65d4be9c1cb78d14465a2c5b146 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Mon, 24 Oct 2022 19:26:07 +0700 Subject: [PATCH 0146/1480] Staging: rtl8192e: rtllib_tx: fixed multiple blank lines Multiple blank lines are condensed into a single blank line as per the Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/a3e044ff9e5b198af15ebc8b91fd048743881340.1666612946.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index e307020580a05..abb5b57d142be 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -191,7 +191,6 @@ int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, return 0; } - void rtllib_txb_free(struct rtllib_txb *txb) { if (unlikely(!txb)) @@ -475,7 +474,6 @@ NO_PROTECTION: tcb_desc->bRTSBW = false; } - static void rtllib_txrate_selectmode(struct rtllib_device *ieee, struct cb_desc *tcb_desc) { @@ -582,7 +580,6 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) goto success; } - if (likely(ieee->raw_tx == 0)) { if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { netdev_warn(ieee->dev, "skb too small (%d).\n", @@ -895,7 +892,6 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) tcb_desc->bTxDisableRateFallBack = 1; } - tcb_desc->RATRIndex = 7; tcb_desc->bTxUseDriverAssingedRate = 1; } else { @@ -920,7 +916,6 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) tcb_desc->bTxDisableRateFallBack = 1; } - tcb_desc->RATRIndex = 7; tcb_desc->bTxUseDriverAssingedRate = 1; tcb_desc->bdhcp = 1; -- GitLab From 2de698578ff331f98021d53e626e46acc4a91b46 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Mon, 24 Oct 2022 19:26:59 +0700 Subject: [PATCH 0147/1480] Staging: rtl8192e: rtllib_tx: fixed alignment matching open parenthesis Aligned multiple statements to match the open parenthesis on the line before it as per the Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/b9a984cf481018a8ef61e4a579cb307eaf1bdc56.1666612946.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index abb5b57d142be..38dfdcf99fecc 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -290,7 +290,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, return; if (pHTInfo->bCurrentAMPDUEnable) { if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, - skb->priority, TX_DIR, true)) { + skb->priority, TX_DIR, true)) { netdev_info(ieee->dev, "%s: can't get TS\n", __func__); return; } @@ -306,7 +306,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, goto FORCED_AGG_SETTING; } else if (!pTxTs->bUsingBa) { if (SN_LESS(pTxTs->TxAdmittedBARecord.ba_start_seq_ctrl.field.seq_num, - (pTxTs->TxCurSeq+1)%4096)) + (pTxTs->TxCurSeq+1)%4096)) pTxTs->bUsingBa = true; else goto FORCED_AGG_SETTING; @@ -442,7 +442,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, u8 HTOpMode = pHTInfo->current_op_mode; if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || - HTOpMode == 3)) || + HTOpMode == 3)) || (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; @@ -501,7 +501,7 @@ static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, struct tx_ts_record *pTS = NULL; if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, - skb->priority, TX_DIR, true)) + skb->priority, TX_DIR, true)) return 0; seqnum = pTS->TxCurSeq; pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096; @@ -618,7 +618,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); if (((((u8 *)udp)[1] == 68) && - (((u8 *)udp)[3] == 67)) || + (((u8 *)udp)[3] == 67)) || ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) { bdhcp = true; @@ -712,11 +712,11 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* in case we are a client verify acm is not set for this ac */ while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { netdev_info(ieee->dev, "skb->priority = %x\n", - skb->priority); + skb->priority); if (wme_downgrade_ac(skb)) break; netdev_info(ieee->dev, "converted skb->priority = %x\n", - skb->priority); + skb->priority); } qos_ctl |= skb->priority; @@ -813,7 +813,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if ((qos_activated) && (!bIsMulticast)) { frag_hdr->seq_ctl = cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, - header.addr1)); + header.addr1)); frag_hdr->seq_ctl = cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i); } else { -- GitLab From 5b773c5504205398ce7ebcf42c5092a7759b556a Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Mon, 24 Oct 2022 19:27:59 +0700 Subject: [PATCH 0148/1480] Staging: rtl8192e: rtllib_tx: added spaces around operators Added multiple spaces around operators which needs it as per the Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/b8bf422436ff4b2d9b530c61ebf814582ab8836a.1666612946.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 38dfdcf99fecc..fa998cd769176 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -306,7 +306,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, goto FORCED_AGG_SETTING; } else if (!pTxTs->bUsingBa) { if (SN_LESS(pTxTs->TxAdmittedBARecord.ba_start_seq_ctrl.field.seq_num, - (pTxTs->TxCurSeq+1)%4096)) + (pTxTs->TxCurSeq + 1) % 4096)) pTxTs->bUsingBa = true; else goto FORCED_AGG_SETTING; @@ -403,7 +403,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, if (tcb_desc->bBroadcast || tcb_desc->bMulticast) return; - if (is_broadcast_ether_addr(skb->data+16)) + if (is_broadcast_ether_addr(skb->data + 16)) return; if (ieee->mode < IEEE_N_24G) { @@ -504,7 +504,7 @@ static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, skb->priority, TX_DIR, true)) return 0; seqnum = pTS->TxCurSeq; - pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096; + pTS->TxCurSeq = (pTS->TxCurSeq + 1) % 4096; return seqnum; } return 0; @@ -611,7 +611,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (skb->len > 282) { if (ether_type == ETH_P_IP) { const struct iphdr *ip = (struct iphdr *) - ((u8 *)skb->data+14); + ((u8 *)skb->data + 14); if (ip->protocol == IPPROTO_UDP) { struct udphdr *udp; @@ -815,10 +815,10 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, header.addr1)); frag_hdr->seq_ctl = - cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i); + cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl) << 4 | i); } else { frag_hdr->seq_ctl = - cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); } /* Put a SNAP header on the first fragment */ if (i == 0) { -- GitLab From 73fb5660fc300ecd9a611e1997c68bc81c8098db Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Mon, 24 Oct 2022 19:29:14 +0700 Subject: [PATCH 0149/1480] Staging: rtl8192e: rtllib_tx: fixed lines ending with an open parenthesis Fixed several lines that end with an open parenthesis to not end with it anymore, as per the Linux kernel coding-style regulations. The issues were flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/a8e67d281b4e9ab1254e0b58294f566994ac7d9d.1666612946.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index fa998cd769176..4647efb0f868b 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -802,8 +802,8 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) * MOREFRAGS bit to the frame control */ if (i != nr_frags - 1) { - frag_hdr->frame_ctl = cpu_to_le16( - fc | RTLLIB_FCTL_MOREFRAGS); + frag_hdr->frame_ctl = cpu_to_le16(fc | + RTLLIB_FCTL_MOREFRAGS); bytes = bytes_per_frag; } else { @@ -822,9 +822,9 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } /* Put a SNAP header on the first fragment */ if (i == 0) { - rtllib_put_snap( - skb_put(skb_frag, SNAP_SIZE + - sizeof(u16)), ether_type); + rtllib_put_snap(skb_put(skb_frag, + SNAP_SIZE + + sizeof(u16)), ether_type); bytes -= SNAP_SIZE + sizeof(u16); } -- GitLab From 438b4ade12582c358a6e6ab762408923f1af2d44 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Mon, 24 Oct 2022 19:30:28 +0700 Subject: [PATCH 0150/1480] Staging: rtl8192e: rtllib_tx: removed unnecessary blank line before a close brace Removed a blank line before a closing brace as it is not necessary as per the Linux coding-style regulations. The issue was flagged by the checkpatch script. Signed-off-by: Aaron Lawrence Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/234a3e8d21080ae2a1f75127a5c1a0ed131db924.1666612946.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 4647efb0f868b..101f441291451 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -954,7 +954,6 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); stats->tx_errors++; return 1; - } netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev) -- GitLab From 6e006508f6e20a0f09dd9e64bc23c0592d92cc2d Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Mon, 24 Oct 2022 14:47:25 -0700 Subject: [PATCH 0151/1480] staging: rtl8723bs: Fix indentation in conditional statements Remove/add tabs in block statements in rtl8723bs/core to fix checkpatch warnings for suspect code indent for conditionals. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/Y1cH7br3mMcT4Dm5@marshmallow Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_mlme.c | 30 +++++++++---------- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 2 +- drivers/staging/rtl8723bs/core/rtw_recv.c | 6 ++-- drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 2 +- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index 6498fd17e1d3e..c6fd6cf741ef6 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -389,7 +389,7 @@ int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst, u8 fea __le16 tmps, tmpd; if (rtw_bug_check(dst, src, &s_cap, &d_cap) == false) - return false; + return false; memcpy((u8 *)&tmps, rtw_get_capability_from_ie(src->ies), 2); memcpy((u8 *)&tmpd, rtw_get_capability_from_ie(dst->ies), 2); @@ -669,7 +669,7 @@ int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwor uint ie_len = 0; if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) - bselected = false; + bselected = false; if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_)); @@ -795,7 +795,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) pmlmepriv->to_join = false; s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); if (s_ret == _SUCCESS) { - _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else if (s_ret == 2) {/* there is no need to wait for join */ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); rtw_indicate_connect(adapter); @@ -2010,8 +2010,8 @@ int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_ if (in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50 && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) { /* WMM element ID and OUI */ for (j = i; j < i + 9; j++) { - out_ie[ielength] = in_ie[j]; - ielength++; + out_ie[ielength] = in_ie[j]; + ielength++; } out_ie[initial_out_len + 1] = 0x07; out_ie[initial_out_len + 6] = 0x00; @@ -2064,15 +2064,13 @@ static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie if (ie[13] <= 20) { /* The RSN IE didn't include the PMK ID, append the PMK information */ - ie[ie_len] = 1; - ie_len++; - ie[ie_len] = 0; /* PMKID count = 0x0100 */ - ie_len++; - memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); - - ie_len += 16; - ie[13] += 18;/* PMKID length = 2+16 */ - + ie[ie_len] = 1; + ie_len++; + ie[ie_len] = 0; /* PMKID count = 0x0100 */ + ie_len++; + memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); + ie_len += 16; + ie[13] += 18;/* PMKID length = 2+16 */ } return ie_len; } @@ -2091,9 +2089,9 @@ signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, u memcpy(out_ie, in_ie, 12); ielength = 12; if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK)) - authmode = WLAN_EID_VENDOR_SPECIFIC; + authmode = WLAN_EID_VENDOR_SPECIFIC; if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) - authmode = WLAN_EID_RSN; + authmode = WLAN_EID_RSN; if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 8e74b4f47b947..1148c9829890c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -5447,7 +5447,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) u8 val8; if (is_client_associated_to_ap(padapter)) - issue_deauth_ex(padapter, pnetwork->mac_address, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); + issue_deauth_ex(padapter, pnetwork->mac_address, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) { /* Stop BCN */ diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index 2825375bff942..7c7b6495965f5 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -161,7 +161,7 @@ int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_ if (padapter) { if (pfree_recv_queue == &precvpriv->free_recv_queue) - precvpriv->free_recvframe_cnt++; + precvpriv->free_recvframe_cnt++; } spin_unlock_bh(&pfree_recv_queue->lock); return _SUCCESS; @@ -691,8 +691,8 @@ static signed int sta2sta_data_frame(struct adapter *adapter, union recv_frame * if (bmcast) { /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ if (!IS_MCAST(pattrib->bssid)) { - ret = _FAIL; - goto exit; + ret = _FAIL; + goto exit; } } else { /* not mc-frame */ /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c index beb11d89db186..c7de81f21bec0 100644 --- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c @@ -551,7 +551,7 @@ u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr) else if (pacl_list->mode == 2)/* deny unless in accept list */ res = match; else - res = true; + res = true; return res; } -- GitLab From 5f803b22bd2befdb43dfbee69d90932edd3cc1d0 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Tue, 25 Oct 2022 17:44:02 +0700 Subject: [PATCH 0152/1480] staging: rtl8192e: rtllib_crypt_wep: multiple blank lines removal Removal of multiple unnecessary blank lines in accordance with the Linux kernel coding-style regulations. Said issues ware detected on this file by the checkpatch script. Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/20221025104402.xvbfobi7sdnwlqs2@plymouth Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_wep.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c index 7790271a6a40d..062285e4d9398 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c @@ -27,7 +27,6 @@ struct prism2_wep_data { struct arc4_ctx tx_ctx_arc4; }; - static void *prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; @@ -46,7 +45,6 @@ static void *prism2_wep_init(int keyidx) return priv; } - static void prism2_wep_deinit(void *priv) { kfree_sensitive(priv); @@ -120,7 +118,6 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return 0; } - /* Perform WEP decryption on given struct buffer. Buffer includes whole WEP * part of the frame: IV (4 bytes), encrypted payload (including SNAP header), * ICV (4 bytes). len includes both IV and ICV. @@ -180,7 +177,6 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return 0; } - static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) { struct prism2_wep_data *wep = priv; @@ -194,7 +190,6 @@ static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) return 0; } - static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) { struct prism2_wep_data *wep = priv; @@ -207,7 +202,6 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) return wep->key_len; } - static void prism2_wep_print_stats(struct seq_file *m, void *priv) { struct prism2_wep_data *wep = priv; @@ -231,13 +225,11 @@ static struct lib80211_crypto_ops rtllib_crypt_wep = { .owner = THIS_MODULE, }; - static int __init rtllib_crypto_wep_init(void) { return lib80211_register_crypto_ops(&rtllib_crypt_wep); } - static void __exit rtllib_crypto_wep_exit(void) { lib80211_unregister_crypto_ops(&rtllib_crypt_wep); -- GitLab From 8cd75652300f957066b86e4ede5525c756fe7a42 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Tue, 25 Oct 2022 17:27:22 +0200 Subject: [PATCH 0153/1480] staging: r8188eu: remove unused macros from wifi.h There are some unused macros in wifi.h. Remove them. Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221025152722.14926-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/wifi.h | 27 -------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index fdb7c1bf3573c..6b50089cea294 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -140,7 +140,6 @@ enum WIFI_REG_DOMAIN { #define _PWRMGT_ BIT(12) #define _MORE_DATA_ BIT(13) #define _PRIVACY_ BIT(14) -#define _ORDER_ BIT(15) #define SetToDs(pbuf) \ *(__le16 *)(pbuf) |= cpu_to_le16(_TO_DS_) @@ -187,17 +186,6 @@ enum WIFI_REG_DOMAIN { *(__le16 *)(pbuf) |= cpu_to_le16(type); \ } while (0) -#define GetTupleCache(pbuf) \ - (cpu_to_le16(*(unsigned short *)((size_t)(pbuf) + 22))) - -#define SetFragNum(pbuf, num) \ - do { \ - *(unsigned short *)((size_t)(pbuf) + 22) = \ - ((*(unsigned short *)((size_t)(pbuf) + 22)) & \ - le16_to_cpu(~(0x000f))) | \ - cpu_to_le16(0x0f & (num)); \ - } while (0) - #define SetSeqNum(pbuf, num) \ do { \ *(__le16 *)((size_t)(pbuf) + 22) = \ @@ -221,13 +209,6 @@ enum WIFI_REG_DOMAIN { #define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) -#define SetAMsdu(pbuf, amsdu) \ - *(__le16 *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7) - -#define GetTid(pbuf) (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + \ - (((GetToDs(pbuf)<<1) | GetFrDs(pbuf)) == 3 ? \ - 30 : 24))) & 0x000f) - #define GetAddr1Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 4)) #define GetAddr2Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 10)) @@ -410,14 +391,6 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) Below is the definition for 802.11n ------------------------------------------------------------------------------*/ -#define SetOrderBit(pbuf) \ - do { \ - *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ - } while (0) - -#define GetOrderBit(pbuf) \ - (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) - /** * struct rtw_ieee80211_bar - HT Block Ack Request * -- GitLab From 25c2e5911705c69d7b01c35ea0b32cbe6ada67cd Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Mon, 15 Aug 2022 16:22:38 +0300 Subject: [PATCH 0154/1480] perf tools riscv: Add support for get_cpuid_str function The get_cpuid_str function returns the string that contains values of MVENDORID, MARCHID and MIMPID in hex format separated by coma. The values themselves are taken from first cpu entry in "/proc/cpuid" that contains "mvendorid", "marchid" and "mimpid". Signed-off-by: Nikita Shubin Tested-by: Kautuk Consul Acked-by: Palmer Dabbelt Cc: Albert Ou Cc: Alexander Shishkin Cc: Anup Patel Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Peter Zijlstra Cc: linux-riscv@lists.infradead.org Cc: linux@yadro.com Link: https://lore.kernel.org/r/20220815132251.25702-2-nikita.shubin@maquefel.me Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/riscv/util/Build | 1 + tools/perf/arch/riscv/util/header.c | 104 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 tools/perf/arch/riscv/util/header.c diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build index 7d3050134ae0f..603dbb5ae4dc9 100644 --- a/tools/perf/arch/riscv/util/Build +++ b/tools/perf/arch/riscv/util/Build @@ -1,4 +1,5 @@ perf-y += perf_regs.o +perf-y += header.o perf-$(CONFIG_DWARF) += dwarf-regs.o perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c new file mode 100644 index 0000000000000..4a41856938a88 --- /dev/null +++ b/tools/perf/arch/riscv/util/header.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Implementation of get_cpuid(). + * + * Author: Nikita Shubin + */ + +#include +#include +#include +#include +#include "../../util/debug.h" +#include "../../util/header.h" + +#define CPUINFO_MVEN "mvendorid" +#define CPUINFO_MARCH "marchid" +#define CPUINFO_MIMP "mimpid" +#define CPUINFO "/proc/cpuinfo" + +static char *_get_field(const char *line) +{ + char *line2, *nl; + + line2 = strrchr(line, ' '); + if (!line2) + return NULL; + + line2++; + nl = strrchr(line, '\n'); + if (!nl) + return NULL; + + return strndup(line2, nl - line2); +} + +static char *_get_cpuid(void) +{ + char *line = NULL; + char *mvendorid = NULL; + char *marchid = NULL; + char *mimpid = NULL; + char *cpuid = NULL; + int read; + unsigned long line_sz; + FILE *cpuinfo; + + cpuinfo = fopen(CPUINFO, "r"); + if (cpuinfo == NULL) + return cpuid; + + while ((read = getline(&line, &line_sz, cpuinfo)) != -1) { + if (!strncmp(line, CPUINFO_MVEN, strlen(CPUINFO_MVEN))) { + mvendorid = _get_field(line); + if (!mvendorid) + goto free; + } else if (!strncmp(line, CPUINFO_MARCH, strlen(CPUINFO_MARCH))) { + marchid = _get_field(line); + if (!marchid) + goto free; + } else if (!strncmp(line, CPUINFO_MIMP, strlen(CPUINFO_MIMP))) { + mimpid = _get_field(line); + if (!mimpid) + goto free; + + break; + } + } + + if (!mvendorid || !marchid || !mimpid) + goto free; + + if (asprintf(&cpuid, "%s-%s-%s", mvendorid, marchid, mimpid) < 0) + cpuid = NULL; + +free: + fclose(cpuinfo); + free(mvendorid); + free(marchid); + free(mimpid); + + return cpuid; +} + +int get_cpuid(char *buffer, size_t sz) +{ + char *cpuid = _get_cpuid(); + int ret = 0; + + if (sz < strlen(cpuid)) { + ret = -EINVAL; + goto free; + } + + scnprintf(buffer, sz, "%s", cpuid); +free: + free(cpuid); + return ret; +} + +char * +get_cpuid_str(struct perf_pmu *pmu __maybe_unused) +{ + return _get_cpuid(); +} -- GitLab From 8f0dcb4e7364af3e5b156e6a3fdac0860733eb86 Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Mon, 15 Aug 2022 16:22:39 +0300 Subject: [PATCH 0155/1480] perf arch events: riscv sbi firmware std event files Firmware events are defined by "RISC-V Supervisor Binary Interface Specification", which means they should be always available as long as firmware supports >= 0.3.0 SBI. Expose them to arch std events, so they can be reused by particular PMU bindings. Signed-off-by: Nikita Shubin Tested-by: Kautuk Consul Acked-by: Palmer Dabbelt Cc: Albert Ou Cc: Alexander Shishkin Cc: Anup Patel Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Peter Zijlstra Cc: linux-riscv@lists.infradead.org Cc: linux@yadro.com Link: https://lore.kernel.org/r/20220815132251.25702-3-nikita.shubin@maquefel.me Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/riscv/riscv-sbi-firmware.json | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tools/perf/pmu-events/arch/riscv/riscv-sbi-firmware.json diff --git a/tools/perf/pmu-events/arch/riscv/riscv-sbi-firmware.json b/tools/perf/pmu-events/arch/riscv/riscv-sbi-firmware.json new file mode 100644 index 0000000000000..a9939823b14b5 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/riscv-sbi-firmware.json @@ -0,0 +1,134 @@ +[ + { + "PublicDescription": "Misaligned load trap", + "ConfigCode": "0x8000000000000000", + "EventName": "FW_MISALIGNED_LOAD", + "BriefDescription": "Misaligned load trap event" + }, + { + "PublicDescription": "Misaligned store trap", + "ConfigCode": "0x8000000000000001", + "EventName": "FW_MISALIGNED_STORE", + "BriefDescription": "Misaligned store trap event" + }, + { + "PublicDescription": "Load access trap", + "ConfigCode": "0x8000000000000002", + "EventName": "FW_ACCESS_LOAD", + "BriefDescription": "Load access trap event" + }, + { + "PublicDescription": "Store access trap", + "ConfigCode": "0x8000000000000003", + "EventName": "FW_ACCESS_STORE", + "BriefDescription": "Store access trap event" + }, + { + "PublicDescription": "Illegal instruction trap", + "ConfigCode": "0x8000000000000004", + "EventName": "FW_ILLEGAL_INSN", + "BriefDescription": "Illegal instruction trap event" + }, + { + "PublicDescription": "Set timer event", + "ConfigCode": "0x8000000000000005", + "EventName": "FW_SET_TIMER", + "BriefDescription": "Set timer event" + }, + { + "PublicDescription": "Sent IPI to other HART event", + "ConfigCode": "0x8000000000000006", + "EventName": "FW_IPI_SENT", + "BriefDescription": "Sent IPI to other HART event" + }, + { + "PublicDescription": "Received IPI from other HART event", + "ConfigCode": "0x8000000000000007", + "EventName": "FW_IPI_RECEIVED", + "BriefDescription": "Received IPI from other HART event" + }, + { + "PublicDescription": "Sent FENCE.I request to other HART event", + "ConfigCode": "0x8000000000000008", + "EventName": "FW_FENCE_I_SENT", + "BriefDescription": "Sent FENCE.I request to other HART event" + }, + { + "PublicDescription": "Received FENCE.I request from other HART event", + "ConfigCode": "0x8000000000000009", + "EventName": "FW_FENCE_I_RECEIVED", + "BriefDescription": "Received FENCE.I request from other HART event" + }, + { + "PublicDescription": "Sent SFENCE.VMA request to other HART event", + "ConfigCode": "0x800000000000000a", + "EventName": "FW_SFENCE_VMA_SENT", + "BriefDescription": "Sent SFENCE.VMA request to other HART event" + }, + { + "PublicDescription": "Received SFENCE.VMA request from other HART event", + "ConfigCode": "0x800000000000000b", + "EventName": "FW_SFENCE_VMA_RECEIVED", + "BriefDescription": "Received SFENCE.VMA request from other HART event" + }, + { + "PublicDescription": "Sent SFENCE.VMA with ASID request to other HART event", + "ConfigCode": "0x800000000000000c", + "EventName": "FW_SFENCE_VMA_RECEIVED", + "BriefDescription": "Sent SFENCE.VMA with ASID request to other HART event" + }, + { + "PublicDescription": "Received SFENCE.VMA with ASID request from other HART event", + "ConfigCode": "0x800000000000000d", + "EventName": "FW_SFENCE_VMA_ASID_RECEIVED", + "BriefDescription": "Received SFENCE.VMA with ASID request from other HART event" + }, + { + "PublicDescription": "Sent HFENCE.GVMA request to other HART event", + "ConfigCode": "0x800000000000000e", + "EventName": "FW_HFENCE_GVMA_SENT", + "BriefDescription": "Sent HFENCE.GVMA request to other HART event" + }, + { + "PublicDescription": "Received HFENCE.GVMA request from other HART event", + "ConfigCode": "0x800000000000000f", + "EventName": "FW_HFENCE_GVMA_RECEIVED", + "BriefDescription": "Received HFENCE.GVMA request from other HART event" + }, + { + "PublicDescription": "Sent HFENCE.GVMA with VMID request to other HART event", + "ConfigCode": "0x8000000000000010", + "EventName": "FW_HFENCE_GVMA_VMID_SENT", + "BriefDescription": "Sent HFENCE.GVMA with VMID request to other HART event" + }, + { + "PublicDescription": "Received HFENCE.GVMA with VMID request from other HART event", + "ConfigCode": "0x8000000000000011", + "EventName": "FW_HFENCE_GVMA_VMID_RECEIVED", + "BriefDescription": "Received HFENCE.GVMA with VMID request from other HART event" + }, + { + "PublicDescription": "Sent HFENCE.VVMA request to other HART event", + "ConfigCode": "0x8000000000000012", + "EventName": "FW_HFENCE_VVMA_SENT", + "BriefDescription": "Sent HFENCE.VVMA request to other HART event" + }, + { + "PublicDescription": "Received HFENCE.VVMA request from other HART event", + "ConfigCode": "0x8000000000000013", + "EventName": "FW_HFENCE_VVMA_RECEIVED", + "BriefDescription": "Received HFENCE.VVMA request from other HART event" + }, + { + "PublicDescription": "Sent HFENCE.VVMA with ASID request to other HART event", + "ConfigCode": "0x8000000000000014", + "EventName": "FW_HFENCE_VVMA_ASID_SENT", + "BriefDescription": "Sent HFENCE.VVMA with ASID request to other HART event" + }, + { + "PublicDescription": "Received HFENCE.VVMA with ASID request from other HART event", + "ConfigCode": "0x8000000000000015", + "EventName": "FW_HFENCE_VVMA_ASID_RECEIVED", + "BriefDescription": "Received HFENCE.VVMA with ASID request from other HART event" + } +] -- GitLab From c4f769d4093d114f3c374ba06d6eef1fb763b56c Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Mon, 15 Aug 2022 16:22:40 +0300 Subject: [PATCH 0156/1480] perf vendor events riscv: add Sifive U74 JSON file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch add the Sifive U74 JSON file. Link: https://sifive.cdn.prismic.io/sifive/ad5577a0-9a00-45c9-a5d0-424a3d586060_u74_core_complex_manual_21G3.pdf Derived-from-code-by: João Mário Domingos Signed-off-by: Nikita Shubin Tested-by: Kautuk Consul Acked-by: Palmer Dabbelt Cc: Albert Ou Cc: Alexander Shishkin Cc: Anup Patel Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Peter Zijlstra Cc: linux-riscv@lists.infradead.org Cc: linux@yadro.com Link: https://lore.kernel.org/r/20220815132251.25702-4-nikita.shubin@maquefel.me Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/riscv/mapfile.csv | 17 ++++ .../arch/riscv/sifive/u74/firmware.json | 68 ++++++++++++++ .../arch/riscv/sifive/u74/instructions.json | 92 +++++++++++++++++++ .../arch/riscv/sifive/u74/memory.json | 32 +++++++ .../arch/riscv/sifive/u74/microarch.json | 57 ++++++++++++ 5 files changed, 266 insertions(+) create mode 100644 tools/perf/pmu-events/arch/riscv/mapfile.csv create mode 100644 tools/perf/pmu-events/arch/riscv/sifive/u74/firmware.json create mode 100644 tools/perf/pmu-events/arch/riscv/sifive/u74/instructions.json create mode 100644 tools/perf/pmu-events/arch/riscv/sifive/u74/memory.json create mode 100644 tools/perf/pmu-events/arch/riscv/sifive/u74/microarch.json diff --git a/tools/perf/pmu-events/arch/riscv/mapfile.csv b/tools/perf/pmu-events/arch/riscv/mapfile.csv new file mode 100644 index 0000000000000..c61b3d6ef6166 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/mapfile.csv @@ -0,0 +1,17 @@ +# Format: +# MVENDORID-MARCHID-MIMPID,Version,JSON/file/pathname,Type +# +# where +# MVENDORID JEDEC code of the core provider +# MARCHID base microarchitecture of the hart +# MIMPID unique encoding of the version +# of the processor implementation +# Version could be used to track version of JSON file +# but currently unused. +# JSON/file/pathname is the path to JSON file, relative +# to tools/perf/pmu-events/arch/riscv/. +# Type is core, uncore etc +# +# +#MVENDORID-MARCHID-MIMPID,Version,Filename,EventType +0x489-0x8000000000000007-0x[[:xdigit:]]+,v1,sifive/u74,core diff --git a/tools/perf/pmu-events/arch/riscv/sifive/u74/firmware.json b/tools/perf/pmu-events/arch/riscv/sifive/u74/firmware.json new file mode 100644 index 0000000000000..9b4a032186a7b --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/sifive/u74/firmware.json @@ -0,0 +1,68 @@ +[ + { + "ArchStdEvent": "FW_MISALIGNED_LOAD" + }, + { + "ArchStdEvent": "FW_MISALIGNED_STORE" + }, + { + "ArchStdEvent": "FW_ACCESS_LOAD" + }, + { + "ArchStdEvent": "FW_ACCESS_STORE" + }, + { + "ArchStdEvent": "FW_ILLEGAL_INSN" + }, + { + "ArchStdEvent": "FW_SET_TIMER" + }, + { + "ArchStdEvent": "FW_IPI_SENT" + }, + { + "ArchStdEvent": "FW_IPI_RECEIVED" + }, + { + "ArchStdEvent": "FW_FENCE_I_SENT" + }, + { + "ArchStdEvent": "FW_FENCE_I_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_SENT" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_ASID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_RECEIVED" + } +] diff --git a/tools/perf/pmu-events/arch/riscv/sifive/u74/instructions.json b/tools/perf/pmu-events/arch/riscv/sifive/u74/instructions.json new file mode 100644 index 0000000000000..5eab718c9256c --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/sifive/u74/instructions.json @@ -0,0 +1,92 @@ +[ + { + "EventName": "EXCEPTION_TAKEN", + "EventCode": "0x0000100", + "BriefDescription": "Exception taken" + }, + { + "EventName": "INTEGER_LOAD_RETIRED", + "EventCode": "0x0000200", + "BriefDescription": "Integer load instruction retired" + }, + { + "EventName": "INTEGER_STORE_RETIRED", + "EventCode": "0x0000400", + "BriefDescription": "Integer store instruction retired" + }, + { + "EventName": "ATOMIC_MEMORY_RETIRED", + "EventCode": "0x0000800", + "BriefDescription": "Atomic memory operation retired" + }, + { + "EventName": "SYSTEM_INSTRUCTION_RETIRED", + "EventCode": "0x0001000", + "BriefDescription": "System instruction retired" + }, + { + "EventName": "INTEGER_ARITHMETIC_RETIRED", + "EventCode": "0x0002000", + "BriefDescription": "Integer arithmetic instruction retired" + }, + { + "EventName": "CONDITIONAL_BRANCH_RETIRED", + "EventCode": "0x0004000", + "BriefDescription": "Conditional branch retired" + }, + { + "EventName": "JAL_INSTRUCTION_RETIRED", + "EventCode": "0x0008000", + "BriefDescription": "JAL instruction retired" + }, + { + "EventName": "JALR_INSTRUCTION_RETIRED", + "EventCode": "0x0010000", + "BriefDescription": "JALR instruction retired" + }, + { + "EventName": "INTEGER_MULTIPLICATION_RETIRED", + "EventCode": "0x0020000", + "BriefDescription": "Integer multiplication instruction retired" + }, + { + "EventName": "INTEGER_DIVISION_RETIRED", + "EventCode": "0x0040000", + "BriefDescription": "Integer division instruction retired" + }, + { + "EventName": "FP_LOAD_RETIRED", + "EventCode": "0x0080000", + "BriefDescription": "Floating-point load instruction retired" + }, + { + "EventName": "FP_STORE_RETIRED", + "EventCode": "0x0100000", + "BriefDescription": "Floating-point store instruction retired" + }, + { + "EventName": "FP_ADDITION_RETIRED", + "EventCode": "0x0200000", + "BriefDescription": "Floating-point addition retired" + }, + { + "EventName": "FP_MULTIPLICATION_RETIRED", + "EventCode": "0x0400000", + "BriefDescription": "Floating-point multiplication retired" + }, + { + "EventName": "FP_FUSEDMADD_RETIRED", + "EventCode": "0x0800000", + "BriefDescription": "Floating-point fused multiply-add retired" + }, + { + "EventName": "FP_DIV_SQRT_RETIRED", + "EventCode": "0x1000000", + "BriefDescription": "Floating-point division or square-root retired" + }, + { + "EventName": "OTHER_FP_RETIRED", + "EventCode": "0x2000000", + "BriefDescription": "Other floating-point instruction retired" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/riscv/sifive/u74/memory.json b/tools/perf/pmu-events/arch/riscv/sifive/u74/memory.json new file mode 100644 index 0000000000000..be1a46312ac36 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/sifive/u74/memory.json @@ -0,0 +1,32 @@ +[ + { + "EventName": "ICACHE_RETIRED", + "EventCode": "0x0000102", + "BriefDescription": "Instruction cache miss" + }, + { + "EventName": "DCACHE_MISS_MMIO_ACCESSES", + "EventCode": "0x0000202", + "BriefDescription": "Data cache miss or memory-mapped I/O access" + }, + { + "EventName": "DCACHE_WRITEBACK", + "EventCode": "0x0000402", + "BriefDescription": "Data cache write-back" + }, + { + "EventName": "INST_TLB_MISS", + "EventCode": "0x0000802", + "BriefDescription": "Instruction TLB miss" + }, + { + "EventName": "DATA_TLB_MISS", + "EventCode": "0x0001002", + "BriefDescription": "Data TLB miss" + }, + { + "EventName": "UTLB_MISS", + "EventCode": "0x0002002", + "BriefDescription": "UTLB miss" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/riscv/sifive/u74/microarch.json b/tools/perf/pmu-events/arch/riscv/sifive/u74/microarch.json new file mode 100644 index 0000000000000..50ffa55418cb8 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/sifive/u74/microarch.json @@ -0,0 +1,57 @@ +[ + { + "EventName": "ADDRESSGEN_INTERLOCK", + "EventCode": "0x0000101", + "BriefDescription": "Address-generation interlock" + }, + { + "EventName": "LONGLAT_INTERLOCK", + "EventCode": "0x0000201", + "BriefDescription": "Long-latency interlock" + }, + { + "EventName": "CSR_READ_INTERLOCK", + "EventCode": "0x0000401", + "BriefDescription": "CSR read interlock" + }, + { + "EventName": "ICACHE_ITIM_BUSY", + "EventCode": "0x0000801", + "BriefDescription": "Instruction cache/ITIM busy" + }, + { + "EventName": "DCACHE_DTIM_BUSY", + "EventCode": "0x0001001", + "BriefDescription": "Data cache/DTIM busy" + }, + { + "EventName": "BRANCH_DIRECTION_MISPREDICTION", + "EventCode": "0x0002001", + "BriefDescription": "Branch direction misprediction" + }, + { + "EventName": "BRANCH_TARGET_MISPREDICTION", + "EventCode": "0x0004001", + "BriefDescription": "Branch/jump target misprediction" + }, + { + "EventName": "PIPE_FLUSH_CSR_WRITE", + "EventCode": "0x0008001", + "BriefDescription": "Pipeline flush from CSR write" + }, + { + "EventName": "PIPE_FLUSH_OTHER_EVENT", + "EventCode": "0x0010001", + "BriefDescription": "Pipeline flush from other event" + }, + { + "EventName": "INTEGER_MULTIPLICATION_INTERLOCK", + "EventCode": "0x0020001", + "BriefDescription": "Integer multiplication interlock" + }, + { + "EventName": "FP_INTERLOCK", + "EventCode": "0x0040001", + "BriefDescription": "Floating-point interlock" + } +] \ No newline at end of file -- GitLab From f7400262ea2192fc79b6f5a68242b3495b016981 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:08 -0700 Subject: [PATCH 0157/1480] perf tools: Save evsel->pmu in parse_events() Now evsel has a pmu pointer, let's save the info and use it like in evsel__find_pmu(). The missing feature check needs to be changed as the pmu pointer can be set from the beginning. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 20 ++++++++++---------- tools/perf/util/parse-events.c | 1 + tools/perf/util/pmu.c | 4 ++++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 76605fde35078..b7140beca9700 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -467,6 +467,7 @@ struct evsel *evsel__clone(struct evsel *orig) evsel->collect_stat = orig->collect_stat; evsel->weak_group = orig->weak_group; evsel->use_config_name = orig->use_config_name; + evsel->pmu = orig->pmu; if (evsel__copy_config_terms(evsel, orig) < 0) goto out_err; @@ -1966,17 +1967,16 @@ bool evsel__detect_missing_features(struct evsel *evsel) perf_missing_features.mmap2 = true; pr_debug2_peo("switching off mmap2\n"); return true; - } else if ((evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host) && - (evsel->pmu == NULL || evsel->pmu->missing_features.exclude_guest)) { - if (evsel->pmu == NULL) { + } else if (evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host) { + if (evsel->pmu == NULL) evsel->pmu = evsel__find_pmu(evsel); - if (evsel->pmu) - evsel->pmu->missing_features.exclude_guest = true; - else { - /* we cannot find PMU, disable attrs now */ - evsel->core.attr.exclude_host = false; - evsel->core.attr.exclude_guest = false; - } + + if (evsel->pmu) + evsel->pmu->missing_features.exclude_guest = true; + else { + /* we cannot find PMU, disable attrs now */ + evsel->core.attr.exclude_host = false; + evsel->core.attr.exclude_guest = false; } if (evsel->exclude_GH) { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 5973f46c23755..6502cd679f577 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -266,6 +266,7 @@ __add_event(struct list_head *list, int *idx, evsel->core.own_cpus = perf_cpu_map__get(cpus); evsel->core.requires_cpu = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; + evsel->pmu = pmu; if (name) evsel->name = strdup(name); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 03284059175f7..6a86e6af0903c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1065,11 +1065,15 @@ struct perf_pmu *evsel__find_pmu(struct evsel *evsel) { struct perf_pmu *pmu = NULL; + if (evsel->pmu) + return evsel->pmu; + while ((pmu = perf_pmu__scan(pmu)) != NULL) { if (pmu->type == evsel->core.attr.type) break; } + evsel->pmu = pmu; return pmu; } -- GitLab From b86ac6796b6c1dea83b744812d36922c21f43323 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:09 -0700 Subject: [PATCH 0158/1480] perf tools: Use pmu info in evsel__is_hybrid() If evsel has pmu, it can use pmu->is_hybrid directly. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b7140beca9700..c9fef26d07027 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3131,6 +3131,9 @@ void evsel__zero_per_pkg(struct evsel *evsel) bool evsel__is_hybrid(struct evsel *evsel) { + if (evsel->pmu) + return evsel->pmu->is_hybrid; + return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name); } -- GitLab From 93d5e700156e03e66eb1bf2158ba3b8a8b354c71 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:10 -0700 Subject: [PATCH 0159/1480] perf stat: Use evsel__is_hybrid() more In the stat-display code, it needs to check if the current evsel is hybrid but it uses perf_pmu__has_hybrid() which can return true for non-hybrid event too. I think it's better to use evsel__is_hybrid(). Also remove a NULL check for the 'config' parameter in the hybrid_merge() since it's called after config->no_merge check. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 5c47ee9963a7c..4113aa86772f7 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -704,7 +704,7 @@ static void uniquify_event_name(struct evsel *counter) counter->name = new_name; } } else { - if (perf_pmu__has_hybrid()) { + if (evsel__is_hybrid(counter)) { ret = asprintf(&new_name, "%s/%s/", counter->pmu_name, counter->name); } else { @@ -744,26 +744,14 @@ static void collect_all_aliases(struct perf_stat_config *config, struct evsel *c } } -static bool is_uncore(struct evsel *evsel) -{ - struct perf_pmu *pmu = evsel__find_pmu(evsel); - - return pmu && pmu->is_uncore; -} - -static bool hybrid_uniquify(struct evsel *evsel) -{ - return perf_pmu__has_hybrid() && !is_uncore(evsel); -} - static bool hybrid_merge(struct evsel *counter, struct perf_stat_config *config, bool check) { - if (hybrid_uniquify(counter)) { + if (evsel__is_hybrid(counter)) { if (check) - return config && config->hybrid_merge; + return config->hybrid_merge; else - return config && !config->hybrid_merge; + return !config->hybrid_merge; } return false; -- GitLab From 375369abcdb774abadbc1c82d2e6c24f0f1f49a1 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:11 -0700 Subject: [PATCH 0160/1480] perf stat: Add aggr id for global mode To make the code simpler, I'd like to use the same aggregation code for the global mode. We can simply add an id function to return cpu 0 and use print_aggr(). No functional change intended. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 36 ++++++++++++++++++++++++++++++++++-- tools/perf/util/cpumap.c | 10 ++++++++++ tools/perf/util/cpumap.h | 6 +++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 265b051579726..75d16e9705a4e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1330,6 +1330,12 @@ static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __ return aggr_cpu_id__node(cpu, /*data=*/NULL); } +static struct aggr_cpu_id perf_stat__get_global(struct perf_stat_config *config __maybe_unused, + struct perf_cpu cpu) +{ + return aggr_cpu_id__global(cpu, /*data=*/NULL); +} + static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct perf_cpu cpu) { @@ -1366,6 +1372,12 @@ static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *co return perf_stat__get_aggr(config, perf_stat__get_node, cpu); } +static struct aggr_cpu_id perf_stat__get_global_cached(struct perf_stat_config *config, + struct perf_cpu cpu) +{ + return perf_stat__get_aggr(config, perf_stat__get_global, cpu); +} + static bool term_percore_set(void) { struct evsel *counter; @@ -1395,6 +1407,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) return NULL; case AGGR_GLOBAL: + return aggr_cpu_id__global; case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: @@ -1420,6 +1433,7 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode) } return NULL; case AGGR_GLOBAL: + return perf_stat__get_global_cached; case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: @@ -1535,6 +1549,16 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(struct perf_cpu cpu, vo return id; } +static struct aggr_cpu_id perf_env__get_global_aggr_by_cpu(struct perf_cpu cpu __maybe_unused, + void *data __maybe_unused) +{ + struct aggr_cpu_id id = aggr_cpu_id__empty(); + + /* it always aggregates to the cpu 0 */ + id.cpu = (struct perf_cpu){ .cpu = 0 }; + return id; +} + static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, struct perf_cpu cpu) { @@ -1558,6 +1582,12 @@ static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *conf return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env); } +static struct aggr_cpu_id perf_stat__get_global_file(struct perf_stat_config *config __maybe_unused, + struct perf_cpu cpu) +{ + return perf_env__get_global_aggr_by_cpu(cpu, &perf_stat.session->header.env); +} + static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode) { switch (aggr_mode) { @@ -1569,8 +1599,9 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode) return perf_env__get_core_aggr_by_cpu; case AGGR_NODE: return perf_env__get_node_aggr_by_cpu; - case AGGR_NONE: case AGGR_GLOBAL: + return perf_env__get_global_aggr_by_cpu; + case AGGR_NONE: case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: @@ -1590,8 +1621,9 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode) return perf_stat__get_core_file; case AGGR_NODE: return perf_stat__get_node_file; - case AGGR_NONE: case AGGR_GLOBAL: + return perf_stat__get_global_file; + case AGGR_NONE: case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 8486ca3bec75f..60209fe87456a 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -354,6 +354,16 @@ struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data __maybe_unu return id; } +struct aggr_cpu_id aggr_cpu_id__global(struct perf_cpu cpu, void *data __maybe_unused) +{ + struct aggr_cpu_id id = aggr_cpu_id__empty(); + + /* it always aggregates to the cpu 0 */ + cpu.cpu = 0; + id.cpu = cpu; + return id; +} + /* setup simple routines to easily access node numbers given a cpu number */ static int get_max_num(char *path, int *max) { diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 4a6d029576eeb..b2ff648bc4176 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -133,5 +133,9 @@ struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data); * cpu. The function signature is compatible with aggr_cpu_id_get_t. */ struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data); - +/** + * aggr_cpu_id__global - Create an aggr_cpu_id for global aggregation. + * The function signature is compatible with aggr_cpu_id_get_t. + */ +struct aggr_cpu_id aggr_cpu_id__global(struct perf_cpu cpu, void *data); #endif /* __PERF_CPUMAP_H */ -- GitLab From 8938cfa7480282fb3c75548958b239444affcc50 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:12 -0700 Subject: [PATCH 0161/1480] perf stat: Add cpu aggr id for no aggregation mode Likewise, add an aggr_id for cpu for none aggregation mode. This is not used actually yet but later code will use to unify the aggregation code. No functional change intended. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 48 +++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 75d16e9705a4e..b03b530fe9a6f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1336,6 +1336,12 @@ static struct aggr_cpu_id perf_stat__get_global(struct perf_stat_config *config return aggr_cpu_id__global(cpu, /*data=*/NULL); } +static struct aggr_cpu_id perf_stat__get_cpu(struct perf_stat_config *config __maybe_unused, + struct perf_cpu cpu) +{ + return aggr_cpu_id__cpu(cpu, /*data=*/NULL); +} + static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct perf_cpu cpu) { @@ -1378,6 +1384,12 @@ static struct aggr_cpu_id perf_stat__get_global_cached(struct perf_stat_config * return perf_stat__get_aggr(config, perf_stat__get_global, cpu); } +static struct aggr_cpu_id perf_stat__get_cpu_cached(struct perf_stat_config *config, + struct perf_cpu cpu) +{ + return perf_stat__get_aggr(config, perf_stat__get_cpu, cpu); +} + static bool term_percore_set(void) { struct evsel *counter; @@ -1404,8 +1416,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) case AGGR_NONE: if (term_percore_set()) return aggr_cpu_id__core; - - return NULL; + return aggr_cpu_id__cpu; case AGGR_GLOBAL: return aggr_cpu_id__global; case AGGR_THREAD: @@ -1428,10 +1439,9 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode) case AGGR_NODE: return perf_stat__get_node_cached; case AGGR_NONE: - if (term_percore_set()) { + if (term_percore_set()) return perf_stat__get_core_cached; - } - return NULL; + return perf_stat__get_cpu_cached; case AGGR_GLOBAL: return perf_stat__get_global_cached; case AGGR_THREAD: @@ -1541,6 +1551,26 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo return id; } +static struct aggr_cpu_id perf_env__get_cpu_aggr_by_cpu(struct perf_cpu cpu, void *data) +{ + struct perf_env *env = data; + struct aggr_cpu_id id = aggr_cpu_id__empty(); + + if (cpu.cpu != -1) { + /* + * core_id is relative to socket and die, + * we need a global id. So we set + * socket, die id and core id + */ + id.socket = env->cpu[cpu.cpu].socket_id; + id.die = env->cpu[cpu.cpu].die_id; + id.core = env->cpu[cpu.cpu].core_id; + id.cpu = cpu; + } + + return id; +} + static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(struct perf_cpu cpu, void *data) { struct aggr_cpu_id id = aggr_cpu_id__empty(); @@ -1576,6 +1606,12 @@ static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *conf return perf_env__get_core_aggr_by_cpu(cpu, &perf_stat.session->header.env); } +static struct aggr_cpu_id perf_stat__get_cpu_file(struct perf_stat_config *config __maybe_unused, + struct perf_cpu cpu) +{ + return perf_env__get_cpu_aggr_by_cpu(cpu, &perf_stat.session->header.env); +} + static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused, struct perf_cpu cpu) { @@ -1602,6 +1638,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode) case AGGR_GLOBAL: return perf_env__get_global_aggr_by_cpu; case AGGR_NONE: + return perf_env__get_cpu_aggr_by_cpu; case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: @@ -1624,6 +1661,7 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode) case AGGR_GLOBAL: return perf_stat__get_global_file; case AGGR_NONE: + return perf_stat__get_cpu_file; case AGGR_THREAD: case AGGR_UNSET: case AGGR_MAX: -- GitLab From 505ac48ba759cd88d9fd40ec5354cda28e17377b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:13 -0700 Subject: [PATCH 0162/1480] perf stat: Add 'needs_sort' argument to cpu_aggr_map__new() In case of no aggregation, it needs to keep the original (cpu) ordering in the aggr_map so that it can be in sync with the cpu map. This will make the code easier to handle AGGR_NONE similar to others. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 7 +++++-- tools/perf/util/cpumap.c | 6 ++++-- tools/perf/util/cpumap.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b03b530fe9a6f..9053fd4d15a77 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1458,8 +1458,9 @@ static int perf_stat_init_aggr_mode(void) aggr_cpu_id_get_t get_id = aggr_mode__get_aggr(stat_config.aggr_mode); if (get_id) { + bool needs_sort = stat_config.aggr_mode != AGGR_NONE; stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.user_requested_cpus, - get_id, /*data=*/NULL); + get_id, /*data=*/NULL, needs_sort); if (!stat_config.aggr_map) { pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]); return -1; @@ -1674,11 +1675,13 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st) { struct perf_env *env = &st->session->header.env; aggr_cpu_id_get_t get_id = aggr_mode__get_aggr_file(stat_config.aggr_mode); + bool needs_sort = stat_config.aggr_mode != AGGR_NONE; if (!get_id) return 0; - stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.user_requested_cpus, get_id, env); + stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.user_requested_cpus, + get_id, env, needs_sort); if (!stat_config.aggr_map) { pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]); return -1; diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 60209fe87456a..6e3fcf523de93 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -234,7 +234,7 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer) struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus, aggr_cpu_id_get_t get_id, - void *data) + void *data, bool needs_sort) { int idx; struct perf_cpu cpu; @@ -270,8 +270,10 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus, if (trimmed_c) c = trimmed_c; } + /* ensure we process id in increasing order */ - qsort(c->map, c->nr, sizeof(struct aggr_cpu_id), aggr_cpu_id__cmp); + if (needs_sort) + qsort(c->map, c->nr, sizeof(struct aggr_cpu_id), aggr_cpu_id__cmp); return c; diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index b2ff648bc4176..da28b3146ef9f 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -97,7 +97,7 @@ typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(struct perf_cpu cpu, void *data) */ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus, aggr_cpu_id_get_t get_id, - void *data); + void *data, bool needs_sort); bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b); bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a); -- GitLab From ca68b374d0409bea5cacd4c5a8e0fbb407922d38 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:14 -0700 Subject: [PATCH 0163/1480] perf stat: Add struct perf_stat_aggr to perf_stat_evsel The perf_stat_aggr struct is to keep aggregated counter values and the states according to the aggregation mode. The number of entries is depends on the mode and this is a preparation for the later use. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat.c | 34 +++++++++++++++++++++++++++------- tools/perf/util/stat.h | 19 +++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 8ec8bb4a99129..c9d5aa295b541 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -133,15 +133,33 @@ static void perf_stat_evsel_id_init(struct evsel *evsel) static void evsel__reset_stat_priv(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats; + struct perf_stat_aggr *aggr = ps->aggr; init_stats(&ps->res_stats); + + if (aggr) + memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr); } -static int evsel__alloc_stat_priv(struct evsel *evsel) + +static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr) { - evsel->stats = zalloc(sizeof(struct perf_stat_evsel)); - if (evsel->stats == NULL) + struct perf_stat_evsel *ps; + + ps = zalloc(sizeof(*ps)); + if (ps == NULL) return -ENOMEM; + + if (nr_aggr) { + ps->nr_aggr = nr_aggr; + ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr)); + if (ps->aggr == NULL) { + free(ps); + return -ENOMEM; + } + } + + evsel->stats = ps; perf_stat_evsel_id_init(evsel); evsel__reset_stat_priv(evsel); return 0; @@ -151,8 +169,10 @@ static void evsel__free_stat_priv(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats; - if (ps) + if (ps) { + zfree(&ps->aggr); zfree(&ps->group_data); + } zfree(&evsel->stats); } @@ -181,9 +201,9 @@ static void evsel__reset_prev_raw_counts(struct evsel *evsel) perf_counts__reset(evsel->prev_raw_counts); } -static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) +static int evsel__alloc_stats(struct evsel *evsel, int nr_aggr, bool alloc_raw) { - if (evsel__alloc_stat_priv(evsel) < 0 || + if (evsel__alloc_stat_priv(evsel, nr_aggr) < 0 || evsel__alloc_counts(evsel) < 0 || (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0)) return -ENOMEM; @@ -196,7 +216,7 @@ int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel__alloc_stats(evsel, alloc_raw)) + if (evsel__alloc_stats(evsel, 0, alloc_raw)) goto out_free; } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index b0899c6e002f5..42453513ffea8 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -8,6 +8,7 @@ #include #include "cpumap.h" #include "rblist.h" +#include "counts.h" struct perf_cpu_map; struct perf_stat_config; @@ -42,9 +43,27 @@ enum perf_stat_evsel_id { PERF_STAT_EVSEL_ID__MAX, }; +/* hold aggregated event info */ +struct perf_stat_aggr { + /* aggregated values */ + struct perf_counts_values counts; + /* number of entries (CPUs) aggregated */ + int nr; + /* whether any entry has failed to read/process event */ + bool failed; +}; + +/* per-evsel event stats */ struct perf_stat_evsel { + /* used for repeated runs */ struct stats res_stats; + /* evsel id for quick check */ enum perf_stat_evsel_id id; + /* number of allocated 'aggr' */ + int nr_aggr; + /* aggregated event values */ + struct perf_stat_aggr *aggr; + /* used for group read */ u64 *group_data; }; -- GitLab From 1f297a6eb2bd90663518cbb6e9e2a3b2add34b73 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:15 -0700 Subject: [PATCH 0164/1480] perf stat: Allocate evsel->stats->aggr properly The perf_stat_config.aggr_map should have a correct size of the aggregation map. Use it to allocate aggr_counts. Also AGGR_NONE with per-core events can be tricky because it doesn't aggreate basically but it needs to do so for per-core events only. So only per-core evsels will have stats->aggr data. Note that other caller of evlist__alloc_stat() might not have stat_config or aggr_map. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 4 ++-- tools/perf/builtin-stat.c | 6 +++--- tools/perf/tests/parse-metric.c | 2 +- tools/perf/tests/pmu-events.c | 2 +- tools/perf/util/stat.c | 9 +++++++-- tools/perf/util/stat.h | 3 ++- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7ca238277d835..d7ec8c1af2936 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2049,7 +2049,7 @@ static void perf_sample__fprint_metric(struct perf_script *script, u64 val; if (!evsel->stats) - evlist__alloc_stats(script->session->evlist, false); + evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false); if (evsel_script(leader)->gnum++ == 0) perf_stat__reset_shadow_stats(); val = sample->period * evsel->scale; @@ -3632,7 +3632,7 @@ static int set_maps(struct perf_script *script) perf_evlist__set_maps(&evlist->core, script->cpus, script->threads); - if (evlist__alloc_stats(evlist, true)) + if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true)) return -ENOMEM; script->allocated = true; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 9053fd4d15a77..92a8e4512f982 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2121,7 +2121,7 @@ static int set_maps(struct perf_stat *st) perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads); - if (evlist__alloc_stats(evsel_list, true)) + if (evlist__alloc_stats(&stat_config, evsel_list, /*alloc_raw=*/true)) return -ENOMEM; st->maps_allocated = true; @@ -2568,10 +2568,10 @@ int cmd_stat(int argc, const char **argv) goto out; } - if (evlist__alloc_stats(evsel_list, interval)) + if (perf_stat_init_aggr_mode()) goto out; - if (perf_stat_init_aggr_mode()) + if (evlist__alloc_stats(&stat_config, evsel_list, interval)) goto out; /* diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c index 68f5a2a03242a..21b7ac00d7985 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -103,7 +103,7 @@ static int __compute_metric(const char *name, struct value *vals, if (err) goto out; - err = evlist__alloc_stats(evlist, false); + err = evlist__alloc_stats(/*config=*/NULL, evlist, /*alloc_raw=*/false); if (err) goto out; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 097e05c796abf..5d0d3b239a68b 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -889,7 +889,7 @@ static int test__parsing_callback(const struct pmu_event *pe, const struct pmu_e goto out_err; } - err = evlist__alloc_stats(evlist, false); + err = evlist__alloc_stats(/*config=*/NULL, evlist, /*alloc_raw=*/false); if (err) goto out_err; /* diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index c9d5aa295b541..3741496285077 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -211,12 +211,17 @@ static int evsel__alloc_stats(struct evsel *evsel, int nr_aggr, bool alloc_raw) return 0; } -int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw) +int evlist__alloc_stats(struct perf_stat_config *config, + struct evlist *evlist, bool alloc_raw) { struct evsel *evsel; + int nr_aggr = 0; + + if (config && config->aggr_map) + nr_aggr = config->aggr_map->nr; evlist__for_each_entry(evlist, evsel) { - if (evsel__alloc_stats(evsel, 0, alloc_raw)) + if (evsel__alloc_stats(evsel, nr_aggr, alloc_raw)) goto out_free; } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 42453513ffea8..0980875b9be11 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -267,7 +267,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, struct runtime_stat *st); void perf_stat__collect_metric_expr(struct evlist *); -int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw); +int evlist__alloc_stats(struct perf_stat_config *config, + struct evlist *evlist, bool alloc_raw); void evlist__free_stats(struct evlist *evlist); void evlist__reset_stats(struct evlist *evlist); void evlist__reset_prev_raw_counts(struct evlist *evlist); -- GitLab From f976bc6b6bfc9b14eeaf9a8859191c8f85c253dc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:16 -0700 Subject: [PATCH 0165/1480] perf stat: Aggregate events using evsel->stats->aggr Add a logic to aggregate counter values to the new evsel->stats->aggr. This is not used yet so shadow stats are not updated. But later patch will convert the existing code to use it. With that, we don't need to handle AGGR_GLOBAL specially anymore. It can use the same logic with counts, prev_counts and aggr_counts. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-10-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 3 -- tools/perf/util/evsel.c | 9 +--- .../scripting-engines/trace-event-python.c | 6 --- tools/perf/util/stat.c | 46 ++++++++++++++++--- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 92a8e4512f982..abede56d79b6f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -963,9 +963,6 @@ try_again_reset: init_stats(&walltime_nsecs_stats); update_stats(&walltime_nsecs_stats, t1 - t0); - if (stat_config.aggr_mode == AGGR_GLOBAL) - evlist__save_aggr_prev_raw_counts(evsel_list); - evlist__copy_prev_raw_counts(evsel_list); evlist__reset_prev_raw_counts(evsel_list); perf_stat__reset_shadow_per_stat(&rt_stat); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c9fef26d07027..cdde5b5f8ad2b 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1526,13 +1526,8 @@ void evsel__compute_deltas(struct evsel *evsel, int cpu_map_idx, int thread, if (!evsel->prev_raw_counts) return; - if (cpu_map_idx == -1) { - tmp = evsel->prev_raw_counts->aggr; - evsel->prev_raw_counts->aggr = *count; - } else { - tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); - *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count; - } + tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); + *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count; count->val = count->val - tmp.val; count->ena = count->ena - tmp.ena; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 1f2040f36d4e9..7bc8559dce6af 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1653,12 +1653,6 @@ static void python_process_stat(struct perf_stat_config *config, struct perf_cpu_map *cpus = counter->core.cpus; int cpu, thread; - if (config->aggr_mode == AGGR_GLOBAL) { - process_stat(counter, (struct perf_cpu){ .cpu = -1 }, -1, tstamp, - &counter->counts->aggr); - return; - } - for (thread = 0; thread < threads->nr; thread++) { for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) { process_stat(counter, perf_cpu_map__cpu(cpus, cpu), diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 3741496285077..99874254809dc 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -387,6 +387,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, struct perf_counts_values *count) { struct perf_counts_values *aggr = &evsel->counts->aggr; + struct perf_stat_evsel *ps = evsel->stats; static struct perf_counts_values zero; bool skip = false; @@ -398,6 +399,44 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, if (skip) count = &zero; + if (!evsel->snapshot) + evsel__compute_deltas(evsel, cpu_map_idx, thread, count); + perf_counts_values__scale(count, config->scale, NULL); + + if (ps->aggr) { + struct perf_cpu cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx); + struct aggr_cpu_id aggr_id = config->aggr_get_id(config, cpu); + struct perf_stat_aggr *ps_aggr; + int i; + + for (i = 0; i < ps->nr_aggr; i++) { + if (!aggr_cpu_id__equal(&aggr_id, &config->aggr_map->map[i])) + continue; + + ps_aggr = &ps->aggr[i]; + ps_aggr->nr++; + + /* + * When any result is bad, make them all to give + * consistent output in interval mode. + */ + if (count->ena == 0 || count->run == 0 || + evsel->counts->scaled == -1) { + ps_aggr->counts.val = 0; + ps_aggr->counts.ena = 0; + ps_aggr->counts.run = 0; + ps_aggr->failed = true; + } + + if (!ps_aggr->failed) { + ps_aggr->counts.val += count->val; + ps_aggr->counts.ena += count->ena; + ps_aggr->counts.run += count->run; + } + break; + } + } + switch (config->aggr_mode) { case AGGR_THREAD: case AGGR_CORE: @@ -405,9 +444,6 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, case AGGR_SOCKET: case AGGR_NODE: case AGGR_NONE: - if (!evsel->snapshot) - evsel__compute_deltas(evsel, cpu_map_idx, thread, count); - perf_counts_values__scale(count, config->scale, NULL); if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) { perf_stat__update_shadow_stats(evsel, count->val, cpu_map_idx, &rt_stat); @@ -469,10 +505,6 @@ int perf_stat_process_counter(struct perf_stat_config *config, if (config->aggr_mode != AGGR_GLOBAL) return 0; - if (!counter->snapshot) - evsel__compute_deltas(counter, -1, -1, aggr); - perf_counts_values__scale(aggr, config->scale, &counter->counts->scaled); - update_stats(&ps->res_stats, *count); if (verbose > 0) { -- GitLab From 049aba09e2156dd2ff1a61bf1b8738b0fc864c9d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:17 -0700 Subject: [PATCH 0166/1480] perf stat: Factor out evsel__count_has_error() It's possible to have 0 enabled/running time for some per-task or per-cgroup events since it's not scheduled on any CPU. Treating the whole event as failed would not work in this case. Thinking again, the code only existed when any CPU-level aggregation is enabled (like per-socket, per-core, ...). To make it clearer, factor out the condition check into the new evsel__count_has_error() function and add some comments. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-11-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 99874254809dc..dc075d5a0f72a 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -381,6 +381,25 @@ static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals, return ret; } +static bool evsel__count_has_error(struct evsel *evsel, + struct perf_counts_values *count, + struct perf_stat_config *config) +{ + /* the evsel was failed already */ + if (evsel->err || evsel->counts->scaled == -1) + return true; + + /* this is meaningful for CPU aggregation modes only */ + if (config->aggr_mode == AGGR_GLOBAL) + return false; + + /* it's considered ok when it actually ran */ + if (count->ena != 0 && count->run != 0) + return false; + + return true; +} + static int process_counter_values(struct perf_stat_config *config, struct evsel *evsel, int cpu_map_idx, int thread, @@ -420,8 +439,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, * When any result is bad, make them all to give * consistent output in interval mode. */ - if (count->ena == 0 || count->run == 0 || - evsel->counts->scaled == -1) { + if (evsel__count_has_error(evsel, count, config) && !ps_aggr->failed) { ps_aggr->counts.val = 0; ps_aggr->counts.ena = 0; ps_aggr->counts.run = 0; -- GitLab From 050059e1b1affc080ede9fe691768e2383eb6367 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:18 -0700 Subject: [PATCH 0167/1480] perf stat: Aggregate per-thread stats using evsel->stats->aggr Per-thread aggregation doesn't use the CPU numbers but the logic should be the same. Initialize cpu_aggr_map separately for AGGR_THREAD and use thread map idx to aggregate counter values. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-12-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 31 +++++++++++++++++++++++++++++++ tools/perf/util/stat.c | 24 ++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index abede56d79b6f..6777fef0d56c3 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1465,6 +1465,21 @@ static int perf_stat_init_aggr_mode(void) stat_config.aggr_get_id = aggr_mode__get_id(stat_config.aggr_mode); } + if (stat_config.aggr_mode == AGGR_THREAD) { + nr = perf_thread_map__nr(evsel_list->core.threads); + stat_config.aggr_map = cpu_aggr_map__empty_new(nr); + if (stat_config.aggr_map == NULL) + return -ENOMEM; + + for (int s = 0; s < nr; s++) { + struct aggr_cpu_id id = aggr_cpu_id__empty(); + + id.thread_idx = s; + stat_config.aggr_map->map[s] = id; + } + return 0; + } + /* * The evsel_list->cpus is the base we operate on, * taking the highest cpu number to be the size of @@ -1674,6 +1689,22 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st) aggr_cpu_id_get_t get_id = aggr_mode__get_aggr_file(stat_config.aggr_mode); bool needs_sort = stat_config.aggr_mode != AGGR_NONE; + if (stat_config.aggr_mode == AGGR_THREAD) { + int nr = perf_thread_map__nr(evsel_list->core.threads); + + stat_config.aggr_map = cpu_aggr_map__empty_new(nr); + if (stat_config.aggr_map == NULL) + return -ENOMEM; + + for (int s = 0; s < nr; s++) { + struct aggr_cpu_id id = aggr_cpu_id__empty(); + + id.thread_idx = s; + stat_config.aggr_map->map[s] = id; + } + return 0; + } + if (!get_id) return 0; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index dc075d5a0f72a..5b04c9d161568 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -422,6 +422,24 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, evsel__compute_deltas(evsel, cpu_map_idx, thread, count); perf_counts_values__scale(count, config->scale, NULL); + if (config->aggr_mode == AGGR_THREAD) { + struct perf_counts_values *aggr_counts = &ps->aggr[thread].counts; + + /* + * Skip value 0 when enabling --per-thread globally, + * otherwise too many 0 output. + */ + if (count->val == 0 && config->system_wide) + return 0; + + ps->aggr[thread].nr++; + + aggr_counts->val += count->val; + aggr_counts->ena += count->ena; + aggr_counts->run += count->run; + goto update; + } + if (ps->aggr) { struct perf_cpu cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx); struct aggr_cpu_id aggr_id = config->aggr_get_id(config, cpu); @@ -436,8 +454,9 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, ps_aggr->nr++; /* - * When any result is bad, make them all to give - * consistent output in interval mode. + * When any result is bad, make them all to give consistent output + * in interval mode. But per-task counters can have 0 enabled time + * when some tasks are idle. */ if (evsel__count_has_error(evsel, count, config) && !ps_aggr->failed) { ps_aggr->counts.val = 0; @@ -455,6 +474,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, } } +update: switch (config->aggr_mode) { case AGGR_THREAD: case AGGR_CORE: -- GitLab From ae7e6492ee54e18cc3d6ed4bb5ca857726a7e9c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:19 -0700 Subject: [PATCH 0168/1480] perf stat: Allocate aggr counts for recorded data In the process_stat_config_event() it sets the aggr_mode that means the earlier evlist__alloc_stats() cannot allocate the aggr counts due to the missing aggr_mode. Do it after setting the aggr_map using evlist__alloc_aggr_stats(). Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-13-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 20 +++++++++++++++----- tools/perf/util/stat.c | 39 +++++++++++++++++++++++++++++++-------- tools/perf/util/stat.h | 2 ++ 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6777fef0d56c3..2a6a5d0c5563a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1342,7 +1342,11 @@ static struct aggr_cpu_id perf_stat__get_cpu(struct perf_stat_config *config __m static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct perf_cpu cpu) { - struct aggr_cpu_id id = aggr_cpu_id__empty(); + struct aggr_cpu_id id; + + /* per-process mode - should use global aggr mode */ + if (cpu.cpu == -1) + return get_id(config, cpu); if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu.cpu])) config->cpus_aggr_map->map[cpu.cpu] = get_id(config, cpu); @@ -2125,17 +2129,23 @@ int process_stat_config_event(struct perf_session *session, if (perf_cpu_map__empty(st->cpus)) { if (st->aggr_mode != AGGR_UNSET) pr_warning("warning: processing task data, aggregation mode not set\n"); - return 0; - } - - if (st->aggr_mode != AGGR_UNSET) + } else if (st->aggr_mode != AGGR_UNSET) { stat_config.aggr_mode = st->aggr_mode; + } if (perf_stat.data.is_pipe) perf_stat_init_aggr_mode(); else perf_stat_init_aggr_mode_file(st); + if (stat_config.aggr_map) { + int nr_aggr = stat_config.aggr_map->nr; + + if (evlist__alloc_aggr_stats(session->evlist, nr_aggr) < 0) { + pr_err("cannot allocate aggr counts\n"); + return -1; + } + } return 0; } diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 5b04c9d161568..1b9048115a185 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -141,6 +141,31 @@ static void evsel__reset_stat_priv(struct evsel *evsel) memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr); } +static int evsel__alloc_aggr_stats(struct evsel *evsel, int nr_aggr) +{ + struct perf_stat_evsel *ps = evsel->stats; + + if (ps == NULL) + return 0; + + ps->nr_aggr = nr_aggr; + ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr)); + if (ps->aggr == NULL) + return -ENOMEM; + + return 0; +} + +int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) { + if (evsel__alloc_aggr_stats(evsel, nr_aggr) < 0) + return -1; + } + return 0; +} static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr) { @@ -150,16 +175,14 @@ static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr) if (ps == NULL) return -ENOMEM; - if (nr_aggr) { - ps->nr_aggr = nr_aggr; - ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr)); - if (ps->aggr == NULL) { - free(ps); - return -ENOMEM; - } + evsel->stats = ps; + + if (nr_aggr && evsel__alloc_aggr_stats(evsel, nr_aggr) < 0) { + evsel->stats = NULL; + free(ps); + return -ENOMEM; } - evsel->stats = ps; perf_stat_evsel_id_init(evsel); evsel__reset_stat_priv(evsel); return 0; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 0980875b9be11..4c00f814bd79a 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -275,6 +275,8 @@ void evlist__reset_prev_raw_counts(struct evlist *evlist); void evlist__copy_prev_raw_counts(struct evlist *evlist); void evlist__save_aggr_prev_raw_counts(struct evlist *evlist); +int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr); + int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); struct perf_tool; -- GitLab From 8f97963e09761c239522649921d7b1c57ff2debb Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:20 -0700 Subject: [PATCH 0169/1480] perf stat: Reset aggr counts for each interval The evsel->stats->aggr->count should be reset for interval processing since we want to use the values directly for display. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-14-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 3 +++ tools/perf/util/stat.c | 20 +++++++++++++++++--- tools/perf/util/stat.h | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2a6a5d0c5563a..bff28a199dfd7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -492,6 +492,8 @@ static void process_interval(void) diff_timespec(&rs, &ts, &ref_time); perf_stat__reset_shadow_per_stat(&rt_stat); + evlist__reset_aggr_stats(evsel_list); + read_counters(&rs); if (STAT_RECORD) { @@ -965,6 +967,7 @@ try_again_reset: evlist__copy_prev_raw_counts(evsel_list); evlist__reset_prev_raw_counts(evsel_list); + evlist__reset_aggr_stats(evsel_list); perf_stat__reset_shadow_per_stat(&rt_stat); } else { update_stats(&walltime_nsecs_stats, t1 - t0); diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 1b9048115a185..a4066f0d36379 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -130,17 +130,23 @@ static void perf_stat_evsel_id_init(struct evsel *evsel) } } -static void evsel__reset_stat_priv(struct evsel *evsel) +static void evsel__reset_aggr_stats(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats; struct perf_stat_aggr *aggr = ps->aggr; - init_stats(&ps->res_stats); - if (aggr) memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr); } +static void evsel__reset_stat_priv(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + + init_stats(&ps->res_stats); + evsel__reset_aggr_stats(evsel); +} + static int evsel__alloc_aggr_stats(struct evsel *evsel, int nr_aggr) { struct perf_stat_evsel *ps = evsel->stats; @@ -276,6 +282,14 @@ void evlist__reset_stats(struct evlist *evlist) } } +void evlist__reset_aggr_stats(struct evlist *evlist) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + evsel__reset_aggr_stats(evsel); +} + void evlist__reset_prev_raw_counts(struct evlist *evlist) { struct evsel *evsel; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 4c00f814bd79a..809f9f0aff0c3 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -276,6 +276,7 @@ void evlist__copy_prev_raw_counts(struct evlist *evlist); void evlist__save_aggr_prev_raw_counts(struct evlist *evlist); int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr); +void evlist__reset_aggr_stats(struct evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); -- GitLab From 8962cbec5a0672b3966e9c48ac22e207d56e13ca Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:21 -0700 Subject: [PATCH 0170/1480] perf stat: Split process_counters() to share it with process_stat_round_event() It'd do more processing with aggregation. Let's split the function so that it can be shared with by process_stat_round_event() too. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-15-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index bff28a199dfd7..838d29590bed9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -465,15 +465,19 @@ static int read_bpf_map_counters(void) return 0; } -static void read_counters(struct timespec *rs) +static int read_counters(struct timespec *rs) { - struct evsel *counter; - if (!stat_config.stop_read_counter) { if (read_bpf_map_counters() || read_affinity_counters(rs)) - return; + return -1; } + return 0; +} + +static void process_counters(void) +{ + struct evsel *counter; evlist__for_each_entry(evsel_list, counter) { if (counter->err) @@ -494,7 +498,8 @@ static void process_interval(void) perf_stat__reset_shadow_per_stat(&rt_stat); evlist__reset_aggr_stats(evsel_list); - read_counters(&rs); + if (read_counters(&rs) == 0) + process_counters(); if (STAT_RECORD) { if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL)) @@ -980,7 +985,8 @@ try_again_reset: * avoid arbitrary skew, we must read all counters before closing any * group leaders. */ - read_counters(&(struct timespec) { .tv_nsec = t1-t0 }); + if (read_counters(&(struct timespec) { .tv_nsec = t1-t0 }) == 0) + process_counters(); /* * We need to keep evsel_list alive, because it's processed @@ -2099,13 +2105,11 @@ static int process_stat_round_event(struct perf_session *session, union perf_event *event) { struct perf_record_stat_round *stat_round = &event->stat_round; - struct evsel *counter; struct timespec tsh, *ts = NULL; const char **argv = session->header.env.cmdline_argv; int argc = session->header.env.nr_cmdline; - evlist__for_each_entry(evsel_list, counter) - perf_stat_process_counter(&stat_config, counter); + process_counters(); if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) update_stats(&walltime_nsecs_stats, stat_round->time); -- GitLab From 942c5593393d9418bf521e77fa1eab47599efc4d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:22 -0700 Subject: [PATCH 0171/1480] perf stat: Add perf_stat_merge_counters() The perf_stat_merge_counters() is to aggregate the same events in different PMUs like in case of uncore or hybrid. The same logic is in the stat-display routines but I think it should be handled when it processes the event counters. As it works on the aggr_counters, it doesn't change the output yet. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-16-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 2 + tools/perf/util/stat.c | 96 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 2 + 3 files changed, 100 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 838d29590bed9..371d6e8969422 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -486,6 +486,8 @@ static void process_counters(void) pr_warning("failed to process counter %s\n", counter->name); counter->err = 0; } + + perf_stat_merge_counters(&stat_config, evsel_list); } static void process_interval(void) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index a4066f0d36379..aff1e7390585c 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -595,6 +595,102 @@ int perf_stat_process_counter(struct perf_stat_config *config, return 0; } +static int evsel__merge_aggr_counters(struct evsel *evsel, struct evsel *alias) +{ + struct perf_stat_evsel *ps_a = evsel->stats; + struct perf_stat_evsel *ps_b = alias->stats; + int i; + + if (ps_a->aggr == NULL && ps_b->aggr == NULL) + return 0; + + if (ps_a->nr_aggr != ps_b->nr_aggr) { + pr_err("Unmatched aggregation mode between aliases\n"); + return -1; + } + + for (i = 0; i < ps_a->nr_aggr; i++) { + struct perf_counts_values *aggr_counts_a = &ps_a->aggr[i].counts; + struct perf_counts_values *aggr_counts_b = &ps_b->aggr[i].counts; + + /* NB: don't increase aggr.nr for aliases */ + + aggr_counts_a->val += aggr_counts_b->val; + aggr_counts_a->ena += aggr_counts_b->ena; + aggr_counts_a->run += aggr_counts_b->run; + } + + return 0; +} +/* events should have the same name, scale, unit, cgroup but on different PMUs */ +static bool evsel__is_alias(struct evsel *evsel_a, struct evsel *evsel_b) +{ + if (strcmp(evsel__name(evsel_a), evsel__name(evsel_b))) + return false; + + if (evsel_a->scale != evsel_b->scale) + return false; + + if (evsel_a->cgrp != evsel_b->cgrp) + return false; + + if (strcmp(evsel_a->unit, evsel_b->unit)) + return false; + + if (evsel__is_clock(evsel_a) != evsel__is_clock(evsel_b)) + return false; + + return !!strcmp(evsel_a->pmu_name, evsel_b->pmu_name); +} + +static void evsel__merge_aliases(struct evsel *evsel) +{ + struct evlist *evlist = evsel->evlist; + struct evsel *alias; + + alias = list_prepare_entry(evsel, &(evlist->core.entries), core.node); + list_for_each_entry_continue(alias, &evlist->core.entries, core.node) { + /* Merge the same events on different PMUs. */ + if (evsel__is_alias(evsel, alias)) { + evsel__merge_aggr_counters(evsel, alias); + alias->merged_stat = true; + } + } +} + +static bool evsel__should_merge_hybrid(struct evsel *evsel, struct perf_stat_config *config) +{ + struct perf_pmu *pmu; + + if (!config->hybrid_merge) + return false; + + pmu = evsel__find_pmu(evsel); + return pmu && pmu->is_hybrid; +} + +static void evsel__merge_stats(struct evsel *evsel, struct perf_stat_config *config) +{ + /* this evsel is already merged */ + if (evsel->merged_stat) + return; + + if (evsel->auto_merge_stats || evsel__should_merge_hybrid(evsel, config)) + evsel__merge_aliases(evsel); +} + +/* merge the same uncore and hybrid events if requested */ +void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *evlist) +{ + struct evsel *evsel; + + if (config->no_merge) + return; + + evlist__for_each_entry(evlist, evsel) + evsel__merge_stats(evsel, config); +} + int perf_event__process_stat_event(struct perf_session *session, union perf_event *event) { diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 809f9f0aff0c3..728bbc823b0d2 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -280,6 +280,8 @@ void evlist__reset_aggr_stats(struct evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); +void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *evlist); + struct perf_tool; union perf_event; struct perf_session; -- GitLab From 1d6d2bea5b97359ff09a8d793674aab3e5f79023 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:23 -0700 Subject: [PATCH 0172/1480] perf stat: Add perf_stat_process_percore() The perf_stat_process_percore() is to aggregate counts for an event per-core even if the aggr_mode is AGGR_NONE. This is enabled when user requested it on the command line. To handle that, it keeps the per-cpu counts at first. And then it aggregates the counts that have the same core id in the aggr->counts and updates the values for each cpu back. Later, per-core events will skip one of the CPUs unless percore-show-thread option is given. In that case, it can simply print all cpu stats with the updated (per-core) values. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-17-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 1 + tools/perf/util/stat.c | 71 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 3 ++ 3 files changed, 75 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 371d6e8969422..d6a006e41da09 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -488,6 +488,7 @@ static void process_counters(void) } perf_stat_merge_counters(&stat_config, evsel_list); + perf_stat_process_percore(&stat_config, evsel_list); } static void process_interval(void) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index aff1e7390585c..26c48ef7ca920 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -691,6 +691,77 @@ void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *ev evsel__merge_stats(evsel, config); } +static void evsel__update_percore_stats(struct evsel *evsel, struct aggr_cpu_id *core_id) +{ + struct perf_stat_evsel *ps = evsel->stats; + struct perf_counts_values counts = { 0, }; + struct aggr_cpu_id id; + struct perf_cpu cpu; + int idx; + + /* collect per-core counts */ + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + id = aggr_cpu_id__core(cpu, NULL); + if (!aggr_cpu_id__equal(core_id, &id)) + continue; + + counts.val += aggr->counts.val; + counts.ena += aggr->counts.ena; + counts.run += aggr->counts.run; + } + + /* update aggregated per-core counts for each CPU */ + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + id = aggr_cpu_id__core(cpu, NULL); + if (!aggr_cpu_id__equal(core_id, &id)) + continue; + + aggr->counts.val = counts.val; + aggr->counts.ena = counts.ena; + aggr->counts.run = counts.run; + + aggr->used = true; + } +} + +/* we have an aggr_map for cpu, but want to aggregate the counters per-core */ +static void evsel__process_percore(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + struct aggr_cpu_id core_id; + struct perf_cpu cpu; + int idx; + + if (!evsel->percore) + return; + + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + if (aggr->used) + continue; + + core_id = aggr_cpu_id__core(cpu, NULL); + evsel__update_percore_stats(evsel, &core_id); + } +} + +/* process cpu stats on per-core events */ +void perf_stat_process_percore(struct perf_stat_config *config, struct evlist *evlist) +{ + struct evsel *evsel; + + if (config->aggr_mode != AGGR_NONE) + return; + + evlist__for_each_entry(evlist, evsel) + evsel__process_percore(evsel); +} + int perf_event__process_stat_event(struct perf_session *session, union perf_event *event) { diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 728bbc823b0d2..d23f8743e4422 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -51,6 +51,8 @@ struct perf_stat_aggr { int nr; /* whether any entry has failed to read/process event */ bool failed; + /* to mark this data is processed already */ + bool used; }; /* per-evsel event stats */ @@ -281,6 +283,7 @@ void evlist__reset_aggr_stats(struct evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *evlist); +void perf_stat_process_percore(struct perf_stat_config *config, struct evlist *evlist); struct perf_tool; union perf_event; -- GitLab From 88f1d3512c947ad8e396e50acfce5ee55133df0a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:24 -0700 Subject: [PATCH 0173/1480] perf stat: Add perf_stat_process_shadow_stats() This function updates the shadow stats using the aggregated counts uniformly since it uses the aggr_counts for the every aggr mode. It'd have duplicate shadow stats for each items for now since the display routines will update them once again. But that'd be fine as it shows the average values and it'd be gone eventually. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-18-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 1 + tools/perf/util/stat.c | 50 ++++++++++++++++++++------------------- tools/perf/util/stat.h | 1 + 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d6a006e41da09..d7c52cef70a3a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -489,6 +489,7 @@ static void process_counters(void) perf_stat_merge_counters(&stat_config, evsel_list); perf_stat_process_percore(&stat_config, evsel_list); + perf_stat_process_shadow_stats(&stat_config, evsel_list); } static void process_interval(void) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 26c48ef7ca920..c0955a0427ab3 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -474,7 +474,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, aggr_counts->val += count->val; aggr_counts->ena += count->ena; aggr_counts->run += count->run; - goto update; + return 0; } if (ps->aggr) { @@ -511,32 +511,10 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, } } -update: - switch (config->aggr_mode) { - case AGGR_THREAD: - case AGGR_CORE: - case AGGR_DIE: - case AGGR_SOCKET: - case AGGR_NODE: - case AGGR_NONE: - if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) { - perf_stat__update_shadow_stats(evsel, count->val, - cpu_map_idx, &rt_stat); - } - - if (config->aggr_mode == AGGR_THREAD) { - perf_stat__update_shadow_stats(evsel, count->val, - thread, &rt_stat); - } - break; - case AGGR_GLOBAL: + if (config->aggr_mode == AGGR_GLOBAL) { aggr->val += count->val; aggr->ena += count->ena; aggr->run += count->run; - case AGGR_UNSET: - case AGGR_MAX: - default: - break; } return 0; @@ -762,6 +740,30 @@ void perf_stat_process_percore(struct perf_stat_config *config, struct evlist *e evsel__process_percore(evsel); } +static void evsel__update_shadow_stats(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + int i; + + if (ps->aggr == NULL) + return; + + for (i = 0; i < ps->nr_aggr; i++) { + struct perf_counts_values *aggr_counts = &ps->aggr[i].counts; + + perf_stat__update_shadow_stats(evsel, aggr_counts->val, i, &rt_stat); + } +} + +void perf_stat_process_shadow_stats(struct perf_stat_config *config __maybe_unused, + struct evlist *evlist) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + evsel__update_shadow_stats(evsel); +} + int perf_event__process_stat_event(struct perf_session *session, union perf_event *event) { diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index d23f8743e4422..3d413ba8c68a6 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -284,6 +284,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *evlist); void perf_stat_process_percore(struct perf_stat_config *config, struct evlist *evlist); +void perf_stat_process_shadow_stats(struct perf_stat_config *config, struct evlist *evlist); struct perf_tool; union perf_event; -- GitLab From 91f85f98da7ab8c32105f42dd03884c01ec4498f Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:25 -0700 Subject: [PATCH 0174/1480] perf stat: Display event stats using aggr counts Now aggr counts are ready for use. Convert the display routines to use the aggr counts and update the shadow stat with them. It doesn't need to aggregate counts or collect aliases anymore during the display. Get rid of now unused struct perf_aggr_thread_value. Note that there's a difference in the display order among the aggr mode. For per-core/die/socket/node aggregation, it shows relevant events in the same unit together, whereas global/thread/no aggregation it shows the same events for different units together. So it still uses separate codes to display them due to the ordering. One more thing to note is that it breaks per-core event display for now. The next patch will fix it to have identical output as of now. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-19-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 421 ++++----------------------------- tools/perf/util/stat.c | 5 - tools/perf/util/stat.h | 9 - 3 files changed, 49 insertions(+), 386 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 4113aa86772f7..bfae2784609c8 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -442,31 +442,6 @@ static void print_metric_header(struct perf_stat_config *config, fprintf(os->fh, "%*s ", config->metric_only_len, unit); } -static int first_shadow_map_idx(struct perf_stat_config *config, - struct evsel *evsel, const struct aggr_cpu_id *id) -{ - struct perf_cpu_map *cpus = evsel__cpus(evsel); - struct perf_cpu cpu; - int idx; - - if (config->aggr_mode == AGGR_NONE) - return perf_cpu_map__idx(cpus, id->cpu); - - if (config->aggr_mode == AGGR_THREAD) - return id->thread_idx; - - if (!config->aggr_get_id) - return 0; - - perf_cpu_map__for_each_cpu(cpu, idx, cpus) { - struct aggr_cpu_id cpu_id = config->aggr_get_id(config, cpu); - - if (aggr_cpu_id__equal(&cpu_id, id)) - return idx; - } - return 0; -} - static void abs_printout(struct perf_stat_config *config, struct aggr_cpu_id id, int nr, struct evsel *evsel, double avg) { @@ -537,7 +512,7 @@ static bool is_mixed_hw_group(struct evsel *counter) static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int nr, struct evsel *counter, double uval, char *prefix, u64 run, u64 ena, double noise, - struct runtime_stat *st) + struct runtime_stat *st, int map_idx) { struct perf_stat_output_ctx out; struct outstate os = { @@ -648,8 +623,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int print_running(config, run, ena); } - perf_stat__print_shadow_stats(config, counter, uval, - first_shadow_map_idx(config, counter, &id), + perf_stat__print_shadow_stats(config, counter, uval, map_idx, &out, &config->metric_events, st); if (!config->csv_output && !config->metric_only && !config->json_output) { print_noise(config, counter, noise); @@ -657,34 +631,6 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int } } -static void aggr_update_shadow(struct perf_stat_config *config, - struct evlist *evlist) -{ - int idx, s; - struct perf_cpu cpu; - struct aggr_cpu_id s2, id; - u64 val; - struct evsel *counter; - struct perf_cpu_map *cpus; - - for (s = 0; s < config->aggr_map->nr; s++) { - id = config->aggr_map->map[s]; - evlist__for_each_entry(evlist, counter) { - cpus = evsel__cpus(counter); - val = 0; - perf_cpu_map__for_each_cpu(cpu, idx, cpus) { - s2 = config->aggr_get_id(config, cpu); - if (!aggr_cpu_id__equal(&s2, &id)) - continue; - val += perf_counts(counter->counts, idx, 0)->val; - } - perf_stat__update_shadow_stats(counter, val, - first_shadow_map_idx(config, counter, &id), - &rt_stat); - } - } -} - static void uniquify_event_name(struct evsel *counter) { char *new_name; @@ -721,137 +667,51 @@ static void uniquify_event_name(struct evsel *counter) counter->uniquified_name = true; } -static void collect_all_aliases(struct perf_stat_config *config, struct evsel *counter, - void (*cb)(struct perf_stat_config *config, struct evsel *counter, void *data, - bool first), - void *data) +static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config) { - struct evlist *evlist = counter->evlist; - struct evsel *alias; - - alias = list_prepare_entry(counter, &(evlist->core.entries), core.node); - list_for_each_entry_continue (alias, &evlist->core.entries, core.node) { - /* Merge events with the same name, etc. but on different PMUs. */ - if (!strcmp(evsel__name(alias), evsel__name(counter)) && - alias->scale == counter->scale && - alias->cgrp == counter->cgrp && - !strcmp(alias->unit, counter->unit) && - evsel__is_clock(alias) == evsel__is_clock(counter) && - strcmp(alias->pmu_name, counter->pmu_name)) { - alias->merged_stat = true; - cb(config, alias, data, false); - } - } + return evsel__is_hybrid(evsel) && !config->hybrid_merge; } -static bool hybrid_merge(struct evsel *counter, struct perf_stat_config *config, - bool check) +static void uniquify_counter(struct perf_stat_config *config, struct evsel *counter) { - if (evsel__is_hybrid(counter)) { - if (check) - return config->hybrid_merge; - else - return !config->hybrid_merge; - } - - return false; -} - -static bool collect_data(struct perf_stat_config *config, struct evsel *counter, - void (*cb)(struct perf_stat_config *config, struct evsel *counter, void *data, - bool first), - void *data) -{ - if (counter->merged_stat) - return false; - cb(config, counter, data, true); - if (config->no_merge || hybrid_merge(counter, config, false)) + if (config->no_merge || hybrid_uniquify(counter, config)) uniquify_event_name(counter); - else if (counter->auto_merge_stats || hybrid_merge(counter, config, true)) - collect_all_aliases(config, counter, cb, data); - return true; -} - -struct aggr_data { - u64 ena, run, val; - struct aggr_cpu_id id; - int nr; - int cpu_map_idx; -}; - -static void aggr_cb(struct perf_stat_config *config, - struct evsel *counter, void *data, bool first) -{ - struct aggr_data *ad = data; - int idx; - struct perf_cpu cpu; - struct perf_cpu_map *cpus; - struct aggr_cpu_id s2; - - cpus = evsel__cpus(counter); - perf_cpu_map__for_each_cpu(cpu, idx, cpus) { - struct perf_counts_values *counts; - - s2 = config->aggr_get_id(config, cpu); - if (!aggr_cpu_id__equal(&s2, &ad->id)) - continue; - if (first) - ad->nr++; - counts = perf_counts(counter->counts, idx, 0); - /* - * When any result is bad, make them all to give - * consistent output in interval mode. - */ - if (counts->ena == 0 || counts->run == 0 || - counter->counts->scaled == -1) { - ad->ena = 0; - ad->run = 0; - break; - } - ad->val += counts->val; - ad->ena += counts->ena; - ad->run += counts->run; - } } static void print_counter_aggrdata(struct perf_stat_config *config, struct evsel *counter, int s, char *prefix, bool metric_only, - bool *first, struct perf_cpu cpu) + bool *first) { - struct aggr_data ad; FILE *output = config->output; u64 ena, run, val; - int nr; - struct aggr_cpu_id id; double uval; + struct perf_stat_evsel *ps = counter->stats; + struct perf_stat_aggr *aggr = &ps->aggr[s]; + struct aggr_cpu_id id = config->aggr_map->map[s]; + double avg = aggr->counts.val; - ad.id = id = config->aggr_map->map[s]; - ad.val = ad.ena = ad.run = 0; - ad.nr = 0; - if (!collect_data(config, counter, aggr_cb, &ad)) + if (counter->supported && aggr->nr == 0) return; - if (perf_pmu__has_hybrid() && ad.ena == 0) - return; + uniquify_counter(config, counter); + + val = aggr->counts.val; + ena = aggr->counts.ena; + run = aggr->counts.run; - nr = ad.nr; - ena = ad.ena; - run = ad.run; - val = ad.val; if (*first && metric_only) { *first = false; - aggr_printout(config, counter, id, nr); + aggr_printout(config, counter, id, aggr->nr); } if (prefix && !metric_only) fprintf(output, "%s", prefix); uval = val * counter->scale; - if (cpu.cpu != -1) - id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); - printout(config, id, nr, counter, uval, - prefix, run, ena, 1.0, &rt_stat); + printout(config, id, aggr->nr, counter, uval, + prefix, run, ena, avg, &rt_stat, s); + if (!metric_only) fputc('\n', output); } @@ -869,8 +729,6 @@ static void print_aggr(struct perf_stat_config *config, if (!config->aggr_map || !config->aggr_get_id) return; - aggr_update_shadow(config, evlist); - /* * With metric_only everything is on a single line. * Without each counter has its own line. @@ -881,188 +739,36 @@ static void print_aggr(struct perf_stat_config *config, first = true; evlist__for_each_entry(evlist, counter) { + if (counter->merged_stat) + continue; + print_counter_aggrdata(config, counter, s, - prefix, metric_only, - &first, (struct perf_cpu){ .cpu = -1 }); + prefix, metric_only, + &first); } if (metric_only) fputc('\n', output); } } -static int cmp_val(const void *a, const void *b) -{ - return ((struct perf_aggr_thread_value *)b)->val - - ((struct perf_aggr_thread_value *)a)->val; -} - -static struct perf_aggr_thread_value *sort_aggr_thread( - struct evsel *counter, - int *ret, - struct target *_target) -{ - int nthreads = perf_thread_map__nr(counter->core.threads); - int i = 0; - double uval; - struct perf_aggr_thread_value *buf; - - buf = calloc(nthreads, sizeof(struct perf_aggr_thread_value)); - if (!buf) - return NULL; - - for (int thread = 0; thread < nthreads; thread++) { - int idx; - u64 ena = 0, run = 0, val = 0; - - perf_cpu_map__for_each_idx(idx, evsel__cpus(counter)) { - struct perf_counts_values *counts = - perf_counts(counter->counts, idx, thread); - - val += counts->val; - ena += counts->ena; - run += counts->run; - } - - uval = val * counter->scale; - - /* - * Skip value 0 when enabling --per-thread globally, - * otherwise too many 0 output. - */ - if (uval == 0.0 && target__has_per_thread(_target)) - continue; - - buf[i].counter = counter; - buf[i].id = aggr_cpu_id__empty(); - buf[i].id.thread_idx = thread; - buf[i].uval = uval; - buf[i].val = val; - buf[i].run = run; - buf[i].ena = ena; - i++; - } - - qsort(buf, i, sizeof(struct perf_aggr_thread_value), cmp_val); - - if (ret) - *ret = i; - - return buf; -} - -static void print_aggr_thread(struct perf_stat_config *config, - struct target *_target, - struct evsel *counter, char *prefix) -{ - FILE *output = config->output; - int thread, sorted_threads; - struct aggr_cpu_id id; - struct perf_aggr_thread_value *buf; - - buf = sort_aggr_thread(counter, &sorted_threads, _target); - if (!buf) { - perror("cannot sort aggr thread"); - return; - } - - for (thread = 0; thread < sorted_threads; thread++) { - if (prefix) - fprintf(output, "%s", prefix); - - id = buf[thread].id; - printout(config, id, 0, buf[thread].counter, buf[thread].uval, - prefix, buf[thread].run, buf[thread].ena, 1.0, - &rt_stat); - fputc('\n', output); - } - - free(buf); -} - -struct caggr_data { - double avg, avg_enabled, avg_running; -}; - -static void counter_aggr_cb(struct perf_stat_config *config __maybe_unused, - struct evsel *counter, void *data, - bool first __maybe_unused) -{ - struct caggr_data *cd = data; - struct perf_counts_values *aggr = &counter->counts->aggr; - - cd->avg += aggr->val; - cd->avg_enabled += aggr->ena; - cd->avg_running += aggr->run; -} - -/* - * Print out the results of a single counter: - * aggregated counts in system-wide mode - */ -static void print_counter_aggr(struct perf_stat_config *config, - struct evsel *counter, char *prefix) -{ - bool metric_only = config->metric_only; - FILE *output = config->output; - double uval; - struct caggr_data cd = { .avg = 0.0 }; - - if (!collect_data(config, counter, counter_aggr_cb, &cd)) - return; - - if (prefix && !metric_only) - fprintf(output, "%s", prefix); - - uval = cd.avg * counter->scale; - printout(config, aggr_cpu_id__empty(), 0, counter, uval, prefix, cd.avg_running, - cd.avg_enabled, cd.avg, &rt_stat); - if (!metric_only) - fprintf(output, "\n"); -} - -static void counter_cb(struct perf_stat_config *config __maybe_unused, - struct evsel *counter, void *data, - bool first __maybe_unused) -{ - struct aggr_data *ad = data; - - ad->val += perf_counts(counter->counts, ad->cpu_map_idx, 0)->val; - ad->ena += perf_counts(counter->counts, ad->cpu_map_idx, 0)->ena; - ad->run += perf_counts(counter->counts, ad->cpu_map_idx, 0)->run; -} - -/* - * Print out the results of a single counter: - * does not use aggregated count in system-wide - */ static void print_counter(struct perf_stat_config *config, struct evsel *counter, char *prefix) { - FILE *output = config->output; - u64 ena, run, val; - double uval; - int idx; - struct perf_cpu cpu; - struct aggr_cpu_id id; - - perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) { - struct aggr_data ad = { .cpu_map_idx = idx }; - - if (!collect_data(config, counter, counter_cb, &ad)) - return; - val = ad.val; - ena = ad.ena; - run = ad.run; + bool metric_only = config->metric_only; + bool first = false; + int s; - if (prefix) - fprintf(output, "%s", prefix); + /* AGGR_THREAD doesn't have config->aggr_get_id */ + if (!config->aggr_map) + return; - uval = val * counter->scale; - id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); - printout(config, id, 0, counter, uval, prefix, - run, ena, 1.0, &rt_stat); + if (counter->merged_stat) + return; - fputc('\n', output); + for (s = 0; s < config->aggr_map->nr; s++) { + print_counter_aggrdata(config, counter, s, + prefix, metric_only, + &first); } } @@ -1081,6 +787,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, u64 ena, run, val; double uval; struct aggr_cpu_id id; + struct perf_stat_evsel *ps = counter->stats; int counter_idx = perf_cpu_map__idx(evsel__cpus(counter), cpu); if (counter_idx < 0) @@ -1093,13 +800,13 @@ static void print_no_aggr_metric(struct perf_stat_config *config, aggr_printout(config, counter, id, 0); first = false; } - val = perf_counts(counter->counts, counter_idx, 0)->val; - ena = perf_counts(counter->counts, counter_idx, 0)->ena; - run = perf_counts(counter->counts, counter_idx, 0)->run; + val = ps->aggr[counter_idx].counts.val; + ena = ps->aggr[counter_idx].counts.ena; + run = ps->aggr[counter_idx].counts.run; uval = val * counter->scale; printout(config, id, 0, counter, uval, prefix, - run, ena, 1.0, &rt_stat); + run, ena, 1.0, &rt_stat, counter_idx); } if (!first) fputc('\n', config->output); @@ -1135,8 +842,8 @@ static void print_metric_headers(struct perf_stat_config *config, }; bool first = true; - if (config->json_output && !config->interval) - fprintf(config->output, "{"); + if (config->json_output && !config->interval) + fprintf(config->output, "{"); if (prefix && !config->json_output) fprintf(config->output, "%s", prefix); @@ -1379,31 +1086,6 @@ static void print_footer(struct perf_stat_config *config) "the same PMU. Try reorganizing the group.\n"); } -static void print_percore_thread(struct perf_stat_config *config, - struct evsel *counter, char *prefix) -{ - int s; - struct aggr_cpu_id s2, id; - struct perf_cpu_map *cpus; - bool first = true; - int idx; - struct perf_cpu cpu; - - cpus = evsel__cpus(counter); - perf_cpu_map__for_each_cpu(cpu, idx, cpus) { - s2 = config->aggr_get_id(config, cpu); - for (s = 0; s < config->aggr_map->nr; s++) { - id = config->aggr_map->map[s]; - if (aggr_cpu_id__equal(&s2, &id)) - break; - } - - print_counter_aggrdata(config, counter, s, - prefix, false, - &first, cpu); - } -} - static void print_percore(struct perf_stat_config *config, struct evsel *counter, char *prefix) { @@ -1416,15 +1098,14 @@ static void print_percore(struct perf_stat_config *config, return; if (config->percore_show_thread) - return print_percore_thread(config, counter, prefix); + return print_counter(config, counter, prefix); for (s = 0; s < config->aggr_map->nr; s++) { if (prefix && metric_only) fprintf(output, "%s", prefix); print_counter_aggrdata(config, counter, s, - prefix, metric_only, - &first, (struct perf_cpu){ .cpu = -1 }); + prefix, metric_only, &first); } if (metric_only) @@ -1469,17 +1150,13 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf print_aggr(config, evlist, prefix); break; case AGGR_THREAD: - evlist__for_each_entry(evlist, counter) { - print_aggr_thread(config, _target, counter, prefix); - } - break; case AGGR_GLOBAL: if (config->iostat_run) iostat_print_counters(evlist, config, ts, prefix = buf, - print_counter_aggr); + print_counter); else { evlist__for_each_entry(evlist, counter) { - print_counter_aggr(config, counter, prefix); + print_counter(config, counter, prefix); } if (metric_only) fputc('\n', config->output); diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index c0955a0427ab3..0316557adce9e 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -565,11 +565,6 @@ int perf_stat_process_counter(struct perf_stat_config *config, evsel__name(counter), count[0], count[1], count[2]); } - /* - * Save the full runtime - to allow normalization during printout: - */ - perf_stat__update_shadow_stats(counter, *count, 0, &rt_stat); - return 0; } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 3d413ba8c68a6..382a1ab92ce18 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -224,15 +224,6 @@ static inline void update_rusage_stats(struct rusage_stats *ru_stats, struct rus struct evsel; struct evlist; -struct perf_aggr_thread_value { - struct evsel *counter; - struct aggr_cpu_id id; - double uval; - u64 val; - u64 run; - u64 ena; -}; - bool __perf_stat_evsel__is(struct evsel *evsel, enum perf_stat_evsel_id id); #define perf_stat_evsel__is(evsel, id) \ -- GitLab From cec94d69636a023302d484ec036158b792001d3c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:26 -0700 Subject: [PATCH 0175/1480] perf stat: Display percore events properly The recent change in the perf stat broke the percore event display. Note that the aggr counts are already processed so that the every sibling thread in the same core will get the per-core counter values. Check percore evsels and skip the sibling threads in the display. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-20-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 16 ---------------- tools/perf/util/stat-display.c | 27 +++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d7c52cef70a3a..9d35a33389766 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1404,18 +1404,6 @@ static struct aggr_cpu_id perf_stat__get_cpu_cached(struct perf_stat_config *con return perf_stat__get_aggr(config, perf_stat__get_cpu, cpu); } -static bool term_percore_set(void) -{ - struct evsel *counter; - - evlist__for_each_entry(evsel_list, counter) { - if (counter->percore) - return true; - } - - return false; -} - static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) { switch (aggr_mode) { @@ -1428,8 +1416,6 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) case AGGR_NODE: return aggr_cpu_id__node; case AGGR_NONE: - if (term_percore_set()) - return aggr_cpu_id__core; return aggr_cpu_id__cpu; case AGGR_GLOBAL: return aggr_cpu_id__global; @@ -1453,8 +1439,6 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode) case AGGR_NODE: return perf_stat__get_node_cached; case AGGR_NONE: - if (term_percore_set()) - return perf_stat__get_core_cached; return perf_stat__get_cpu_cached; case AGGR_GLOBAL: return perf_stat__get_global_cached; diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bfae2784609c8..657434cd29eea 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1091,7 +1091,8 @@ static void print_percore(struct perf_stat_config *config, { bool metric_only = config->metric_only; FILE *output = config->output; - int s; + struct cpu_aggr_map *core_map; + int s, c, i; bool first = true; if (!config->aggr_map || !config->aggr_get_id) @@ -1100,13 +1101,35 @@ static void print_percore(struct perf_stat_config *config, if (config->percore_show_thread) return print_counter(config, counter, prefix); - for (s = 0; s < config->aggr_map->nr; s++) { + core_map = cpu_aggr_map__empty_new(config->aggr_map->nr); + if (core_map == NULL) { + fprintf(output, "Cannot allocate per-core aggr map for display\n"); + return; + } + + for (s = 0, c = 0; s < config->aggr_map->nr; s++) { + struct perf_cpu curr_cpu = config->aggr_map->map[s].cpu; + struct aggr_cpu_id core_id = aggr_cpu_id__core(curr_cpu, NULL); + bool found = false; + + for (i = 0; i < c; i++) { + if (aggr_cpu_id__equal(&core_map->map[i], &core_id)) { + found = true; + break; + } + } + if (found) + continue; + if (prefix && metric_only) fprintf(output, "%s", prefix); print_counter_aggrdata(config, counter, s, prefix, metric_only, &first); + + core_map->map[c++] = core_id; } + free(core_map); if (metric_only) fputc('\n', output); -- GitLab From 8b76a3188b85724f345ea5d03ff206cc9bbe6d72 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 17 Oct 2022 19:02:27 -0700 Subject: [PATCH 0176/1480] perf stat: Remove unused perf_counts.aggr field The aggr field in the struct perf_counts is to keep the aggregated value in the AGGR_GLOBAL for the old code. But it's not used anymore. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Andi Kleen Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221018020227.85905-21-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/counts.c | 1 - tools/perf/util/counts.h | 1 - tools/perf/util/stat.c | 39 ++++++--------------------------------- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index 7a447d9184588..11cd85b278a63 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c @@ -48,7 +48,6 @@ void perf_counts__reset(struct perf_counts *counts) { xyarray__reset(counts->loaded); xyarray__reset(counts->values); - memset(&counts->aggr, 0, sizeof(struct perf_counts_values)); } void evsel__reset_counts(struct evsel *evsel) diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 5de275194f2b1..42760242e0df0 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -11,7 +11,6 @@ struct evsel; struct perf_counts { s8 scaled; - struct perf_counts_values aggr; struct xyarray *values; struct xyarray *loaded; }; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 0316557adce9e..3a432a949d469 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -308,8 +308,6 @@ static void evsel__copy_prev_raw_counts(struct evsel *evsel) *perf_counts(evsel->prev_raw_counts, idx, thread); } } - - evsel->counts->aggr = evsel->prev_raw_counts->aggr; } void evlist__copy_prev_raw_counts(struct evlist *evlist) @@ -320,26 +318,6 @@ void evlist__copy_prev_raw_counts(struct evlist *evlist) evsel__copy_prev_raw_counts(evsel); } -void evlist__save_aggr_prev_raw_counts(struct evlist *evlist) -{ - struct evsel *evsel; - - /* - * To collect the overall statistics for interval mode, - * we copy the counts from evsel->prev_raw_counts to - * evsel->counts. The perf_stat_process_counter creates - * aggr values from per cpu values, but the per cpu values - * are 0 for AGGR_GLOBAL. So we use a trick that saves the - * previous aggr value to the first member of perf_counts, - * then aggr calculation in process_counter_values can work - * correctly. - */ - evlist__for_each_entry(evlist, evsel) { - *perf_counts(evsel->prev_raw_counts, 0, 0) = - evsel->prev_raw_counts->aggr; - } -} - static size_t pkg_id_hash(const void *__key, void *ctx __maybe_unused) { uint64_t *key = (uint64_t *) __key; @@ -442,7 +420,6 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, int cpu_map_idx, int thread, struct perf_counts_values *count) { - struct perf_counts_values *aggr = &evsel->counts->aggr; struct perf_stat_evsel *ps = evsel->stats; static struct perf_counts_values zero; bool skip = false; @@ -511,12 +488,6 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, } } - if (config->aggr_mode == AGGR_GLOBAL) { - aggr->val += count->val; - aggr->ena += count->ena; - aggr->run += count->run; - } - return 0; } @@ -541,13 +512,10 @@ static int process_counter_maps(struct perf_stat_config *config, int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter) { - struct perf_counts_values *aggr = &counter->counts->aggr; struct perf_stat_evsel *ps = counter->stats; - u64 *count = counter->counts->aggr.values; + u64 *count; int ret; - aggr->val = aggr->ena = aggr->run = 0; - if (counter->per_pkg) evsel__zero_per_pkg(counter); @@ -558,6 +526,11 @@ int perf_stat_process_counter(struct perf_stat_config *config, if (config->aggr_mode != AGGR_GLOBAL) return 0; + /* + * GLOBAL aggregation mode only has a single aggr counts, + * so we can use ps->aggr[0] as the actual output. + */ + count = ps->aggr[0].counts.values; update_stats(&ps->res_stats, *count); if (verbose > 0) { -- GitLab From a87edbec35725ced484f6b8275f1246ed7194329 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Sat, 22 Oct 2022 17:27:34 +0800 Subject: [PATCH 0177/1480] perf daemon: Complete list of supported subcommand in help message perf daemon supports start, signal, stop and ping subcommands, complete it Before: # perf daemon -h Usage: perf daemon start [] or: perf daemon [] -v, --verbose be more verbose -x, --field-separator[=] print counts with custom separator --base base directory --config config file path After: # perf daemon -h Usage: perf daemon {start|signal|stop|ping} [] or: perf daemon [] -v, --verbose be more verbose -x, --field-separator[=] print counts with custom separator --base base directory --config config file path Signed-off-by: Yang Jihong Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221022092735.114967-3-yangjihong1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c index 6cb3f6cc36d0a..3ce0c960ccc9b 100644 --- a/tools/perf/builtin-daemon.c +++ b/tools/perf/builtin-daemon.c @@ -100,7 +100,7 @@ static struct daemon __daemon = { }; static const char * const daemon_usage[] = { - "perf daemon start []", + "perf daemon {start|signal|stop|ping} []", "perf daemon []", NULL }; -- GitLab From 0cef66a98420f1210be697ed47bd7417ed428847 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Sat, 22 Oct 2022 17:27:35 +0800 Subject: [PATCH 0178/1480] perf config: Add missing newline on pr_warning() call in home_perfconfig() Add missing newline on pr_warning() call in home_perfconfig(). Before: # perf record File /home/yangjihong/.perfconfig not owned by current user or root, ignoring it.Couldn't synthesize bpf events. After: # perf record File /home/yangjihong/.perfconfig not owned by current user or root, ignoring it. Couldn't synthesize bpf events. Signed-off-by: Yang Jihong Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221022092735.114967-4-yangjihong1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 3f2ae19a1dd40..658170b8dcef7 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -556,7 +556,7 @@ static char *home_perfconfig(void) config = strdup(mkpath("%s/.perfconfig", home)); if (config == NULL) { - pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.", home); + pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.\n", home); return NULL; } @@ -564,7 +564,7 @@ static char *home_perfconfig(void) goto out_free; if (st.st_uid && (st.st_uid != geteuid())) { - pr_warning("File %s not owned by current user or root, ignoring it.", config); + pr_warning("File %s not owned by current user or root, ignoring it.\n", config); goto out_free; } -- GitLab From 743ef218c2fbe63502615a2044977041ee068322 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Oct 2022 17:25:18 -0300 Subject: [PATCH 0179/1480] perf unwind arm64: Remove needless event.h & thread.h includes To reduce compile time and header dependency chains just add forward declarations for pointer types and include linux/types.h for u64. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/arm64-frame-pointer-unwind-support.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/arm64-frame-pointer-unwind-support.h b/tools/perf/util/arm64-frame-pointer-unwind-support.h index 32af9ce94398e..42d3a45490f50 100644 --- a/tools/perf/util/arm64-frame-pointer-unwind-support.h +++ b/tools/perf/util/arm64-frame-pointer-unwind-support.h @@ -2,8 +2,10 @@ #ifndef __PERF_ARM_FRAME_POINTER_UNWIND_SUPPORT_H #define __PERF_ARM_FRAME_POINTER_UNWIND_SUPPORT_H -#include "event.h" -#include "thread.h" +#include + +struct perf_sample; +struct thread; u64 get_leaf_frame_caller_aarch64(struct perf_sample *sample, struct thread *thread, int user_idx); -- GitLab From 6bc13cab5798bd9b049694983ae5702666d24e83 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Oct 2022 17:32:19 -0300 Subject: [PATCH 0180/1480] perf arch x86: Add missing stdlib.h to get free() prototype It was getting indirectly, out of luck, add it. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/event.c | 1 + tools/perf/arch/x86/util/tsc.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index e670f35475815..55ff6aec10fdd 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "../../../util/event.h" #include "../../../util/synthetic-events.h" diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index eb2b5195bd020..9b99f48b923cf 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "../../../util/debug.h" #include "../../../util/tsc.h" -- GitLab From 06bf28cbc63287c69fe834b527127a56b65de2d7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Oct 2022 17:33:04 -0300 Subject: [PATCH 0181/1480] perf scripting python: Add missing util/perf_regs.h include to get perf_reg_name() prototype It was getting it via event.h, that doesn't need that include anymore and will drop it. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/scripting-engines/trace-event-python.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 7bc8559dce6af..1985d1a42a224 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -52,6 +52,7 @@ #include "print_binary.h" #include "stat.h" #include "mem-events.h" +#include "util/perf_regs.h" #if PY_MAJOR_VERSION < 3 #define _PyUnicode_FromString(arg) \ -- GitLab From b15cf900d11d4db2c2dac544a27f3e1217bdd0d4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Oct 2022 17:34:44 -0300 Subject: [PATCH 0182/1480] perf event: Drop perf_regs.h include, not needed anymore Since commit c897899752478d4c ("perf tools: Prevent out-of-bounds access to registers") the util/event.h header doesn't use anything from util/perf_regs.h, so drop it to untangle the header dependency tree a bit, speeding up compilation. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 12eae69170225..65495f6945b4d 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -12,8 +12,6 @@ #include #include -#include "perf_regs.h" - struct dso; struct machine; struct perf_event_attr; -- GitLab From ad7ad6b5ddf63b436a5344fb686887f2d8b7cf3d Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 20 Oct 2022 18:25:09 +0300 Subject: [PATCH 0183/1480] perf scripts python: intel-pt-events.py: Add ability interleave output Intel PT timestamps are not provided for every branch, let alone every instruction, so there can be many samples with the same timestamp. With per-cpu contexts, decoding is done for each CPU in turn, which can make it difficult to see what is happening on different CPUs at the same time. Currently the interleaving from perf script --itrace=i0ns is quite coarse grained. There are often long stretches executing on one CPU and nothing on another. Some people are interested in seeing what happened on multiple CPUs before a crash to debug races etc. To improve perf script interleaving for parallel execution, the intel-pt-events.py script has been enhanced to enable interleaving the output with the same timestamp from different CPUs. It is understood that interleaving is not perfect or causal. Add parameter --interleave [] to interleave sample output for the same timestamp so that no more than n samples for a CPU are displayed in a row. 'n' defaults to 4. Note this only affects the order of output, and only when the timestamp is the same. Example: $ perf script intel-pt-events.py --insn-trace --interleave 3 ... bash 2267/2267 [004] 9323.692625625 563caa3c86f0 jz 0x563caa3c89c7 run_pending_traps+0x30 (/usr/bin/bash) IPC: 1.52 (38/25) bash 2267/2267 [004] 9323.692625625 563caa3c89c7 movq 0x118(%rsp), %rax run_pending_traps+0x307 (/usr/bin/bash) bash 2267/2267 [004] 9323.692625625 563caa3c89cf subq %fs:0x28, %rax run_pending_traps+0x30f (/usr/bin/bash) bash 2270/2270 [007] 9323.692625625 55dc58cabf02 jz 0x55dc58cabf48 unquoted_glob_pattern_p+0x102 (/usr/bin/bash) IPC: 1.56 (25/16) bash 2270/2270 [007] 9323.692625625 55dc58cabf04 cmp $0x5d, %al unquoted_glob_pattern_p+0x104 (/usr/bin/bash) bash 2270/2270 [007] 9323.692625625 55dc58cabf06 jnz 0x55dc58cabf10 unquoted_glob_pattern_p+0x106 (/usr/bin/bash) bash 2264/2264 [001] 9323.692625625 7fd556a4376c jbe 0x7fd556a43ac8 round_and_return+0x3fc (/usr/lib/x86_64-linux-gnu/libc.so.6) IPC: 4.30 (43/10) bash 2264/2264 [001] 9323.692625625 7fd556a43772 and $0x8, %edx round_and_return+0x402 (/usr/lib/x86_64-linux-gnu/libc.so.6) bash 2264/2264 [001] 9323.692625625 7fd556a43775 jnz 0x7fd556a43ac8 round_and_return+0x405 (/usr/lib/x86_64-linux-gnu/libc.so.6) bash 2267/2267 [004] 9323.692625625 563caa3c89d8 jnz 0x563caa3c8b11 run_pending_traps+0x318 (/usr/bin/bash) bash 2267/2267 [004] 9323.692625625 563caa3c89de add $0x128, %rsp run_pending_traps+0x31e (/usr/bin/bash) bash 2267/2267 [004] 9323.692625625 563caa3c89e5 popq %rbx run_pending_traps+0x325 (/usr/bin/bash) ... Signed-off-by: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lore.kernel.org/r/20221020152509.5298-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-intel-pt.txt | 12 +++- tools/perf/scripts/python/intel-pt-events.py | 65 +++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-intel-pt.txt b/tools/perf/Documentation/perf-intel-pt.txt index 92464a5d7eafd..7b6ccd2fa3bf1 100644 --- a/tools/perf/Documentation/perf-intel-pt.txt +++ b/tools/perf/Documentation/perf-intel-pt.txt @@ -189,8 +189,16 @@ There is also script intel-pt-events.py which provides an example of how to unpack the raw data for power events and PTWRITE. The script also displays branches, and supports 2 additional modes selected by option: - --insn-trace - instruction trace - --src-trace - source trace + - --insn-trace - instruction trace + - --src-trace - source trace + +The intel-pt-events.py script also has options: + + - --all-switch-events - display all switch events, not only the last consecutive. + - --interleave [] - interleave sample output for the same timestamp so that + no more than n samples for a CPU are displayed in a row. 'n' defaults to 4. + Note this only affects the order of output, and only when the timestamp is the + same. As mentioned above, it is easy to capture too much data. One way to limit the data captured is to use 'snapshot' mode which is explained further below. diff --git a/tools/perf/scripts/python/intel-pt-events.py b/tools/perf/scripts/python/intel-pt-events.py index 6be7fd8fd6158..08862a2582f44 100644 --- a/tools/perf/scripts/python/intel-pt-events.py +++ b/tools/perf/scripts/python/intel-pt-events.py @@ -13,10 +13,12 @@ from __future__ import print_function +import io import os import sys import struct import argparse +import contextlib from libxed import LibXED from ctypes import create_string_buffer, addressof @@ -39,6 +41,11 @@ glb_src = False glb_source_file_name = None glb_line_number = None glb_dso = None +glb_stash_dict = {} +glb_output = None +glb_output_pos = 0 +glb_cpu = -1 +glb_time = 0 def get_optional_null(perf_dict, field): if field in perf_dict: @@ -70,6 +77,7 @@ def trace_begin(): ap.add_argument("--insn-trace", action='store_true') ap.add_argument("--src-trace", action='store_true') ap.add_argument("--all-switch-events", action='store_true') + ap.add_argument("--interleave", type=int, nargs='?', const=4, default=0) global glb_args global glb_insn global glb_src @@ -94,11 +102,39 @@ def trace_begin(): perf_set_itrace_options(perf_script_context, itrace) def trace_end(): + if glb_args.interleave: + flush_stashed_output() print("End") def trace_unhandled(event_name, context, event_fields_dict): print(' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])) +def stash_output(): + global glb_stash_dict + global glb_output_pos + output_str = glb_output.getvalue()[glb_output_pos:] + n = len(output_str) + if n: + glb_output_pos += n + if glb_cpu not in glb_stash_dict: + glb_stash_dict[glb_cpu] = [] + glb_stash_dict[glb_cpu].append(output_str) + +def flush_stashed_output(): + global glb_stash_dict + while glb_stash_dict: + cpus = list(glb_stash_dict.keys()) + # Output at most glb_args.interleave output strings per cpu + for cpu in cpus: + items = glb_stash_dict[cpu] + countdown = glb_args.interleave + while len(items) and countdown: + sys.stdout.write(items[0]) + del items[0] + countdown -= 1 + if not items: + del glb_stash_dict[cpu] + def print_ptwrite(raw_buf): data = struct.unpack_from("= 2 and x[0]: machine_pid = x[0] vcpu = x[1] @@ -403,6 +464,8 @@ def auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x): sys.exit(1) def context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x): + if glb_args.interleave: + flush_stashed_output() if out: out_str = "Switch out " else: -- GitLab From 439dbef2a94e825241160e1bbd050d01e5728608 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:36 -0700 Subject: [PATCH 0184/1480] perf test: Do not use instructions:u explicitly I think it's to support non-root user tests. But perf record can handle the case and fall back to a software event (cpu-clock). Practically this would affect when it's run on a VM, but it seems no reason to prevent running the test in the guest. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 301f95427159d..747c33a1ec454 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -21,18 +21,18 @@ trap trap_cleanup exit term int test_per_thread() { echo "Basic --per-thread mode test" - if ! perf record -e instructions:u -o ${perfdata} --quiet true 2> /dev/null + if ! perf record -o /dev/null --quiet true 2> /dev/null then - echo "Per-thread record [Skipped instructions:u not supported]" + echo "Per-thread record [Skipped event not supported]" if [ $err -ne 1 ] then err=2 fi return fi - if ! perf record -e instructions:u --per-thread -o ${perfdata} true 2> /dev/null + if ! perf record --per-thread -o ${perfdata} true 2> /dev/null then - echo "Per-thread record of instructions:u [Failed]" + echo "Per-thread record [Failed record]" err=1 return fi @@ -49,7 +49,7 @@ test_register_capture() { echo "Register capture test" if ! perf list | egrep -q 'br_inst_retired.near_call' then - echo "Register capture test [Skipped missing instruction]" + echo "Register capture test [Skipped missing event]" if [ $err -ne 1 ] then err=2 -- GitLab From 9e455f4f29e3aeab29b6c1f7d086ddc43fc1a502 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:37 -0700 Subject: [PATCH 0185/1480] perf test: Fix shellcheck issues in the record test Basically there are 3 issues: 1. quote shell expansion 2. do not use egrep 3. use upper case letters for signal names Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 747c33a1ec454..4640714628092 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -8,16 +8,16 @@ err=0 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) cleanup() { - rm -f ${perfdata} - rm -f ${perfdata}.old - trap - exit term int + rm -f "${perfdata}" + rm -f "${perfdata}".old + trap - EXIT TERM INT } trap_cleanup() { cleanup exit 1 } -trap trap_cleanup exit term int +trap trap_cleanup EXIT TERM INT test_per_thread() { echo "Basic --per-thread mode test" @@ -30,13 +30,13 @@ test_per_thread() { fi return fi - if ! perf record --per-thread -o ${perfdata} true 2> /dev/null + if ! perf record --per-thread -o "${perfdata}" true 2> /dev/null then echo "Per-thread record [Failed record]" err=1 return fi - if ! perf report -i ${perfdata} -q | egrep -q true + if ! perf report -i "${perfdata}" -q | grep -q true then echo "Per-thread record [Failed missing output]" err=1 @@ -47,7 +47,7 @@ test_per_thread() { test_register_capture() { echo "Register capture test" - if ! perf list | egrep -q 'br_inst_retired.near_call' + if ! perf list | grep -q 'br_inst_retired.near_call' then echo "Register capture test [Skipped missing event]" if [ $err -ne 1 ] @@ -56,7 +56,7 @@ test_register_capture() { fi return fi - if ! perf record --intr-regs=\? 2>&1 | egrep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15' + if ! perf record --intr-regs=\? 2>&1 | grep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15' then echo "Register capture test [Skipped missing registers]" return @@ -64,7 +64,7 @@ test_register_capture() { if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \ -c 1000 --per-thread true 2> /dev/null \ | perf script -F ip,sym,iregs -i - 2> /dev/null \ - | egrep -q "DI:" + | grep -q "DI:" then echo "Register capture test [Failed missing output]" err=1 -- GitLab From 4321ad4ee98b7325d6133e1d5b7fa25bcbdeb57e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:38 -0700 Subject: [PATCH 0186/1480] perf test: Use a test program in 'perf record' tests If the system has cc it could build a test program with two threads and then use it for more detailed testing. Also it accepts an option to run a thread forever to ensure multi-thread runs. If cc is not found, it falls back to use the default value 'true'. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 64 ++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 4640714628092..9529814812390 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -6,10 +6,17 @@ set -e err=0 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX) +testsym="test_loop" cleanup() { rm -f "${perfdata}" rm -f "${perfdata}".old + + if [ "${testprog}" != "true" ]; then + rm -f "${testprog}" + fi + trap - EXIT TERM INT } @@ -19,9 +26,56 @@ trap_cleanup() { } trap trap_cleanup EXIT TERM INT +build_test_program() { + if ! [ -x "$(command -v cc)" ]; then + # No CC found. Fall back to 'true' + testprog=true + testsym=true + return + fi + + echo "Build a test program" + cat < +#include +#include + +void test_loop(void) { + volatile int count = 1000000; + + while (count--) + continue; +} + +void *thfunc(void *arg) { + int forever = *(int *)arg; + + do { + test_loop(); + } while (forever); + + return NULL; +} + +int main(int argc, char *argv[]) { + pthread_t th; + int forever = 0; + + if (argc > 1) + forever = atoi(argv[1]); + + pthread_create(&th, NULL, thfunc, &forever); + test_loop(); + pthread_join(th, NULL); + + return 0; +} +EOF +} + test_per_thread() { echo "Basic --per-thread mode test" - if ! perf record -o /dev/null --quiet true 2> /dev/null + if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null then echo "Per-thread record [Skipped event not supported]" if [ $err -ne 1 ] @@ -30,13 +84,13 @@ test_per_thread() { fi return fi - if ! perf record --per-thread -o "${perfdata}" true 2> /dev/null + if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null then echo "Per-thread record [Failed record]" err=1 return fi - if ! perf report -i "${perfdata}" -q | grep -q true + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" then echo "Per-thread record [Failed missing output]" err=1 @@ -62,7 +116,7 @@ test_register_capture() { return fi if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \ - -c 1000 --per-thread true 2> /dev/null \ + -c 1000 --per-thread ${testprog} 2> /dev/null \ | perf script -F ip,sym,iregs -i - 2> /dev/null \ | grep -q "DI:" then @@ -73,6 +127,8 @@ test_register_capture() { echo "Register capture test [Success]" } +build_test_program + test_per_thread test_register_capture -- GitLab From 6b7e02ab1262141cfebd05b68410fa297f557961 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:39 -0700 Subject: [PATCH 0187/1480] perf test: Wait for a new thread when testing --per-thread record Just running the target program is not enough to test multi-thread target because it'd be racy perf vs target startup. I used the initial delay but it cannot guarantee for perf to see the thread. Instead, use wait_for_threads helper from shell/lib/waiting.sh to make sure it starts the sibling thread first. Then perf record can use -p option to profile the target process. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 9529814812390..d1640d1daf2e3 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -4,6 +4,9 @@ set -e +shelldir=$(dirname "$0") +. "${shelldir}"/lib/waiting.sh + err=0 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX) @@ -96,6 +99,30 @@ test_per_thread() { err=1 return fi + + # run the test program in background (forever) + ${testprog} 1 & + TESTPID=$! + + rm -f "${perfdata}" + + wait_for_threads ${TESTPID} 2 + perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null + kill ${TESTPID} + + if [ ! -e "${perfdata}" ] + then + echo "Per-thread record [Failed record -p]" + err=1 + return + fi + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" + then + echo "Per-thread record [Failed -p missing output]" + err=1 + return + fi + echo "Basic --per-thread mode test [Success]" } -- GitLab From 2cadf2c7b99a980455500c34571a540300c49c72 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:40 -0700 Subject: [PATCH 0188/1480] perf test: Add system-wide mode in 'perf record' tests Add system wide recording test with the same pattern. It'd skip the test when it fails to run 'perf record'. For system-wide mode, it needs to avoid build-id collection and synthesis because the test only cares about the test program and kernel would generate the necessary events as the process starts. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index d1640d1daf2e3..345764afb7456 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -154,10 +154,31 @@ test_register_capture() { echo "Register capture test [Success]" } +test_system_wide() { + echo "Basic --system-wide mode test" + if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null + then + echo "System-wide record [Skipped not supported]" + if [ $err -ne 1 ] + then + err=2 + fi + return + fi + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" + then + echo "System-wide record [Failed missing output]" + err=1 + return + fi + echo "Basic --system-wide mode test [Success]" +} + build_test_program test_per_thread test_register_capture +test_system_wide cleanup exit $err -- GitLab From c8c935677487ba6f7dd18d48e39ab30bbb4cb5d9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:41 -0700 Subject: [PATCH 0189/1480] perf test: Add target workload test in 'perf record' tests Add a subtest which profiles the given workload on the command line. As it's a minimal requirement, the test should run ok so it doesn't skip the test even if it failed to run the 'perf record' command. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 345764afb7456..c59d1459c9603 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -174,11 +174,29 @@ test_system_wide() { echo "Basic --system-wide mode test [Success]" } +test_workload() { + echo "Basic target workload test" + if ! perf record -o "${perfdata}" ${testprog} 2> /dev/null + then + echo "Workload record [Failed record]" + err=1 + return + fi + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" + then + echo "Workload record [Failed missing output]" + err=1 + return + fi + echo "Basic target workload test [Success]" +} + build_test_program test_per_thread test_register_capture test_system_wide +test_workload cleanup exit $err -- GitLab From 7f4ed3f0b1fc951bcb91a78bf68ac45aac13ec0b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:42 -0700 Subject: [PATCH 0190/1480] perf test: Test record with --threads option The --threads option changed the 'perf record' behavior significantly, so it'd be nice if we test it separately. Add --threads options with different argument in each test supported and check the result. Also update the cleanup routine because threads recording produces data in a directory. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index c59d1459c9603..01aa9531b3694 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -13,8 +13,8 @@ testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX) testsym="test_loop" cleanup() { - rm -f "${perfdata}" - rm -f "${perfdata}".old + rm -rf "${perfdata}" + rm -rf "${perfdata}".old if [ "${testprog}" != "true" ]; then rm -f "${testprog}" @@ -171,6 +171,19 @@ test_system_wide() { err=1 return fi + if ! perf record -aB --synth=no -e cpu-clock,cs --threads=cpu \ + -o "${perfdata}" ${testprog} 2> /dev/null + then + echo "System-wide record [Failed record --threads option]" + err=1 + return + fi + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" + then + echo "System-wide record [Failed --threads missing output]" + err=1 + return + fi echo "Basic --system-wide mode test [Success]" } @@ -188,6 +201,19 @@ test_workload() { err=1 return fi + if ! perf record -e cpu-clock,cs --threads=package \ + -o "${perfdata}" ${testprog} 2> /dev/null + then + echo "Workload record [Failed record --threads option]" + err=1 + return + fi + if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" + then + echo "Workload record [Failed --threads missing output]" + err=1 + return + fi echo "Basic target workload test [Success]" } -- GitLab From 8b380e6afd124d18cd51a43d2505e4eb05e2ba09 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 20 Oct 2022 10:26:43 -0700 Subject: [PATCH 0191/1480] perf test: Do not set TEST_SKIP for record subtests It now has 4 sub tests and at least one of them should run. But once the TEST_SKIP (= 2) return value is set, it won't be overwritten unless there's a failure. I think we should return success when one or more tests are skipped but the remaining subtests are passed. So update the test code not to set the err variable when it skips the test. Reviewed-by: Adrian Hunter Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221020172643.3458767-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 01aa9531b3694..e93b3a8871fe3 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -81,10 +81,6 @@ test_per_thread() { if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null then echo "Per-thread record [Skipped event not supported]" - if [ $err -ne 1 ] - then - err=2 - fi return fi if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null @@ -131,10 +127,6 @@ test_register_capture() { if ! perf list | grep -q 'br_inst_retired.near_call' then echo "Register capture test [Skipped missing event]" - if [ $err -ne 1 ] - then - err=2 - fi return fi if ! perf record --intr-regs=\? 2>&1 | grep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15' @@ -159,10 +151,6 @@ test_system_wide() { if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null then echo "System-wide record [Skipped not supported]" - if [ $err -ne 1 ] - then - err=2 - fi return fi if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" -- GitLab From 65319890c32db29fb56b41f84265a2c7029943f4 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 18 Oct 2022 10:41:35 +0100 Subject: [PATCH 0192/1480] perf tools: Fix "kernel lock contention analysis" test by not printing warnings in quiet mode Especially when CONFIG_LOCKDEP and other debug configs are enabled, Perf can print the following warning when running the "kernel lock contention analysis" test: Warning: Processed 1378918 events and lost 4 chunks! Check IO/CPU overload! Warning: Processed 4593325 samples and lost 70.00%! The test already supplies -q to run in quiet mode, so extend quiet mode to perf_stdio__warning() and also ui__warning() for consistency. This fixes the following failure due to the extra lines counted: perf test "lock cont" -vvv 82: kernel lock contention analysis test : --- start --- test child forked, pid 3125 Testing perf lock record and perf lock contention [Fail] Recorded result count is not 1: 9 test child finished with -1 ---- end ---- kernel lock contention analysis test: FAILED! Fixes: ec685de25b6718f8 ("perf test: Add kernel lock contention test") Signed-off-by: James Clark Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221018094137.783081-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/util.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index 689b27c34246c..1d38ddf01b604 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c @@ -15,6 +15,9 @@ static int perf_stdio__error(const char *format, va_list args) static int perf_stdio__warning(const char *format, va_list args) { + if (quiet) + return 0; + fprintf(stderr, "Warning:\n"); vfprintf(stderr, format, args); return 0; @@ -45,6 +48,8 @@ int ui__warning(const char *format, ...) { int ret; va_list args; + if (quiet) + return 0; va_start(args, format); ret = perf_eops->warning(format, args); -- GitLab From a527c2c1e2d43e9f145f5d0c5d6ac0bdf5220e22 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 18 Oct 2022 10:41:36 +0100 Subject: [PATCH 0193/1480] perf tools: Make quiet mode consistent between tools Use the global quiet variable everywhere so that all tools hide warnings in quiet mode and update the documentation to reflect this. 'perf probe' claimed that errors are not printed in quiet mode but I don't see this so remove it from the docs. Signed-off-by: James Clark Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221018094137.783081-3-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-annotate.txt | 2 +- tools/perf/Documentation/perf-diff.txt | 2 +- tools/perf/Documentation/perf-lock.txt | 2 +- tools/perf/Documentation/perf-probe.txt | 2 +- tools/perf/Documentation/perf-record.txt | 2 +- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-stat.txt | 4 ++-- tools/perf/bench/numa.c | 9 +++++---- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-probe.c | 7 +++---- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-stat.c | 8 ++++---- tools/perf/util/stat.h | 1 - 16 files changed, 25 insertions(+), 26 deletions(-) diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 18fcc52809fbf..980fe2c292752 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -41,7 +41,7 @@ OPTIONS -q:: --quiet:: - Do not show any message. (Suppress -v) + Do not show any warnings or messages. (Suppress -v) -n:: --show-nr-samples:: diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index be65bd55ab2aa..f3067a4af2940 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -75,7 +75,7 @@ OPTIONS -q:: --quiet:: - Do not show any message. (Suppress -v) + Do not show any warnings or messages. (Suppress -v) -f:: --force:: diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt index 3b1e16563b795..4958a1ffa1cca 100644 --- a/tools/perf/Documentation/perf-lock.txt +++ b/tools/perf/Documentation/perf-lock.txt @@ -42,7 +42,7 @@ COMMON OPTIONS -q:: --quiet:: - Do not show any message. (Suppress -v) + Do not show any warnings or messages. (Suppress -v) -D:: --dump-raw-trace:: diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index 080981d38d7ba..7f8e8ba3a7872 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -57,7 +57,7 @@ OPTIONS -q:: --quiet:: - Be quiet (do not show any messages including errors). + Do not show any warnings or messages. Can not use with -v. -a:: diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index e41ae950fdc3b..9ea6d44aca58c 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -282,7 +282,7 @@ OPTIONS -q:: --quiet:: - Don't print any message, useful for scripting. + Don't print any warnings or messages, useful for scripting. -v:: --verbose:: diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 4533db2ee56bb..4fa509b159489 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -27,7 +27,7 @@ OPTIONS -q:: --quiet:: - Do not show any message. (Suppress -v) + Do not show any warnings or messages. (Suppress -v) -n:: --show-nr-samples:: diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index d7ff1867feda6..18abdc1dce055 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -354,8 +354,8 @@ forbids the event merging logic from sharing events between groups and may be used to increase accuracy in this case. --quiet:: -Don't print output. This is useful with perf stat record below to only -write data to the perf.data file. +Don't print output, warnings or messages. This is useful with perf stat +record below to only write data to the perf.data file. STAT RECORD ----------- diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index e78dedf9e682c..9717c6c17433c 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -116,7 +117,6 @@ struct params { long bytes_thread; int nr_tasks; - bool show_quiet; bool show_convergence; bool measure_convergence; @@ -197,7 +197,8 @@ static const struct option options[] = { OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details, " "convergence is reached when each process (all its threads) is running on a single NUMA node."), OPT_BOOLEAN('m', "measure_convergence", &p0.measure_convergence, "measure convergence latency"), - OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "quiet mode"), + OPT_BOOLEAN('q', "quiet" , &quiet, + "quiet mode (do not show any warnings or messages)"), OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"), /* Special option string parsing callbacks: */ @@ -1474,7 +1475,7 @@ static int init(void) /* char array in count_process_nodes(): */ BUG_ON(g->p.nr_nodes < 0); - if (g->p.show_quiet && !g->p.show_details) + if (quiet && !g->p.show_details) g->p.show_details = -1; /* Some memory should be specified: */ @@ -1553,7 +1554,7 @@ static void print_res(const char *name, double val, if (!name) name = "main,"; - if (!g->p.show_quiet) + if (!quiet) printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short); else printf(" %14.3f %s\n", val, txt_long); diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index f839e69492e80..517d928c00e3f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -525,7 +525,7 @@ int cmd_annotate(int argc, const char **argv) OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), - OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"), + OPT_BOOLEAN('q', "quiet", &quiet, "do now show any warnings or messages"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), #ifdef HAVE_GTK2_SUPPORT diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d925096dd7f02..ed07cc6cca56c 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1260,7 +1260,7 @@ static const char * const diff_usage[] = { static const struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), - OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"), + OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"), OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), OPT_CALLBACK('c', "compute", &compute, diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 9722d4ab2e557..66520712a1675 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -1869,7 +1869,7 @@ int cmd_lock(int argc, const char **argv) "file", "vmlinux pathname"), OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", "kallsyms pathname"), - OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"), + OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"), OPT_END() }; diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index f62298f5db3b4..2ae50fc9e5976 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -40,7 +40,6 @@ static struct { int command; /* Command short_name */ bool list_events; bool uprobes; - bool quiet; bool target_used; int nevents; struct perf_probe_event events[MAX_PROBES]; @@ -514,8 +513,8 @@ __cmd_probe(int argc, const char **argv) struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose (show parsed arguments, etc)"), - OPT_BOOLEAN('q', "quiet", ¶ms.quiet, - "be quiet (do not show any messages)"), + OPT_BOOLEAN('q', "quiet", &quiet, + "be quiet (do not show any warnings or messages)"), OPT_CALLBACK_DEFAULT('l', "list", NULL, "[GROUP:]EVENT", "list up probe events", opt_set_filter_with_command, DEFAULT_LIST_FILTER), @@ -634,7 +633,7 @@ __cmd_probe(int argc, const char **argv) if (ret) return ret; - if (params.quiet) { + if (quiet) { if (verbose != 0) { pr_err(" Error: -v and -q are exclusive.\n"); return -EINVAL; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e128b855dddec..59f3d98a0196d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -3388,7 +3388,7 @@ static struct option __record_options[] = { &record_parse_callchain_opt), OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), - OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), + OPT_BOOLEAN('q', "quiet", &quiet, "don't print any warnings or messages"), OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, "per thread counts"), OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8361890176c23..b6d77d3da64f6 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1222,7 +1222,7 @@ int cmd_report(int argc, const char **argv) "input file name"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), - OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"), + OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"), diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 9d35a33389766..e52601a54b26d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1033,7 +1033,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv) /* Do not print anything if we record to the pipe. */ if (STAT_RECORD && perf_stat.data.is_pipe) return; - if (stat_config.quiet) + if (quiet) return; evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv); @@ -1283,8 +1283,8 @@ static struct option stat_options[] = { "print summary for interval mode"), OPT_BOOLEAN(0, "no-csv-summary", &stat_config.no_csv_summary, "don't print 'summary' for CSV summary output"), - OPT_BOOLEAN(0, "quiet", &stat_config.quiet, - "don't print output (useful with record)"), + OPT_BOOLEAN(0, "quiet", &quiet, + "don't print any output, messages or warnings (useful with record)"), OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", "Only enable events on applying cpu with this type " "for hybrid platform (e.g. core or atom)", @@ -2383,7 +2383,7 @@ int cmd_stat(int argc, const char **argv) goto out; } - if (!output && !stat_config.quiet) { + if (!output && !quiet) { struct timespec tm; mode = append_file ? "a" : "w"; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 382a1ab92ce18..499c3bf813336 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -160,7 +160,6 @@ struct perf_stat_config { bool metric_no_group; bool metric_no_merge; bool stop_read_counter; - bool quiet; bool iostat_run; char *user_requested_cpu_list; bool system_wide; -- GitLab From cff624146450bd25a1acea0439b7654167e0f722 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2022 13:50:17 -0300 Subject: [PATCH 0194/1480] perf bpf: No need to include compiler.h when HAVE_LIBBPF_SUPPORT is true Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_map.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/bpf_map.h b/tools/perf/util/bpf_map.h index d6abd5e47af8d..c2f7c13cba23f 100644 --- a/tools/perf/util/bpf_map.h +++ b/tools/perf/util/bpf_map.h @@ -3,7 +3,6 @@ #define __PERF_BPF_MAP_H 1 #include -#include struct bpf_map; #ifdef HAVE_LIBBPF_SUPPORT @@ -12,6 +11,8 @@ int bpf_map__fprintf(struct bpf_map *map, FILE *fp); #else +#include + static inline int bpf_map__fprintf(struct bpf_map *map __maybe_unused, FILE *fp __maybe_unused) { return 0; -- GitLab From 46db0ba12be6cfd043df1d09b5831cb84ce2307f Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 10 Oct 2022 12:32:04 +0800 Subject: [PATCH 0195/1480] bus: mhi: host: Use mhi_soc_reset() API in place of register write Currently, a direct register write is used when ramdump collection in panic path occurs. Replace that with new mhi_soc_reset() API such that a controller defined reset() function is exercised if one is present and the regular SOC reset is done if it is not. Signed-off-by: Qiang Yu Reviewed-by: Loic Poulain Reviewed-by: Jeffrey Hugo Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/1665376324-34258-1-git-send-email-quic_qianyu@quicinc.com Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/boot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 26d0eddb14771..1c69feee17030 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -118,9 +118,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) /* Hardware reset so force device to enter RDDM */ dev_dbg(dev, "Did not enter RDDM, do a host req reset\n"); - mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, - MHI_SOC_RESET_REQ_OFFSET, - MHI_SOC_RESET_REQ); + mhi_soc_reset(mhi_cntrl); udelay(delayus); } -- GitLab From 869a99907faea6d1835b0bd0d0422ae3519c6ea9 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Sun, 16 Oct 2022 11:05:32 +0800 Subject: [PATCH 0196/1480] bus: mhi: host: Fix race between channel preparation and M0 event There is a race condition where mhi_prepare_channel() updates the read and write pointers as the base address and in parallel, if an M0 transition occurs, the tasklet goes ahead and rings doorbells for all channels with a delta in TRE rings assuming they are already enabled. This causes a null pointer access. Fix it by adding a channel enabled check before ringing channel doorbells. Cc: stable@vger.kernel.org # 5.19 Fixes: a6e2e3522f29 "bus: mhi: core: Add support for PM state transitions" Signed-off-by: Qiang Yu Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/1665889532-13634-1-git-send-email-quic_qianyu@quicinc.com [mani: CCed stable list] Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 4a42186ff1112..083459028a4b8 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -301,7 +301,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) read_lock_irq(&mhi_chan->lock); /* Only ring DB if ring is not empty */ - if (tre_ring->base && tre_ring->wp != tre_ring->rp) + if (tre_ring->base && tre_ring->wp != tre_ring->rp && + mhi_chan->ch_state == MHI_CH_STATE_ENABLED) mhi_ring_chan_db(mhi_cntrl, mhi_chan); read_unlock_irq(&mhi_chan->lock); } -- GitLab From 2d5253a096c6057bbf7caa5520856dcdf7eca8bb Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Fri, 16 Sep 2022 16:43:29 +0200 Subject: [PATCH 0197/1480] bus: mhi: host: pci_generic: Add a secondary AT port to Telit FN990 Add a secondary AT port using one of OEM reserved channel. Signed-off-by: Fabio Porcedda Reviewed-by: Loic Poulain Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20220916144329.243368-3-fabio.porcedda@gmail.com Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/pci_generic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index caa4ce28cf9e5..c4259cb2d2899 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -340,6 +340,8 @@ static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = { MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0), MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0), MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), + MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1), + MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3), }; -- GitLab From 1d96c542b29129abbee819f355a1facbee07626e Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 28 Oct 2022 23:09:32 +0530 Subject: [PATCH 0198/1480] MAINTAINERS: Remove Hemant from MHI bus Hemant moved out of Qualcomm and expressed his wish to not continue doing any reviews for MHI patches. So let's remove him from MAINTAINERS file. Reviewed-by: Jeffrey Hugo Signed-off-by: Manivannan Sadhasivam --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index cf0f185023724..ad9279218885d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13395,7 +13395,6 @@ F: arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts MHI BUS M: Manivannan Sadhasivam -R: Hemant Kumar L: mhi@lists.linux.dev L: linux-arm-msm@vger.kernel.org S: Maintained -- GitLab From 2fe5dc3dcc2920669217e3696ec15fec6630a92f Mon Sep 17 00:00:00 2001 From: Emily Peri Date: Fri, 28 Oct 2022 11:39:19 -0700 Subject: [PATCH 0199/1480] staging: rtl8723bs: replace ternary statement with min_t macro Ternary statements that pick the min of two values can be replaced by the macro min_t(). This improves readability, since its quicker to understand min_t(type, x, y) than x < y ? x : y. Issue found by coccicheck. Signed-off-by: Emily Peri Link: https://lore.kernel.org/r/Y1wh1zYMAbbKSrGB@marshmallow Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 6aeb169c6ebf0..54004f846cf0f 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -1551,7 +1551,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen); if (wps_ie && wps_ielen > 0) { - padapter->securitypriv.wps_ie_len = wps_ielen < MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN; + padapter->securitypriv.wps_ie_len = min_t(uint, wps_ielen, MAX_WPS_IE_LEN); memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len); set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); } else { -- GitLab From 737143dc87dfd3cb600a46092387c9caa814ce88 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 30 Oct 2022 09:10:20 +0100 Subject: [PATCH 0200/1480] staging: r8188eu: use min() instead of ternary operator Replace a ternary operator usage with the min() macro to improve readability. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221030081020.8533-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c index 8516e253bb031..22aab3f986b4d 100644 --- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -3568,7 +3568,7 @@ static int rtw_wx_set_priv(struct net_device *dev, if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { - cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len; + cp_sz = min(probereq_wpsie_len, MAX_WPS_IE_LEN); pmlmepriv->wps_probe_req_ie_len = 0; kfree(pmlmepriv->wps_probe_req_ie); -- GitLab From cbcab58a7cbf51e0e1e8e5dec0bd44be48e966db Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Wed, 26 Oct 2022 02:06:18 +0900 Subject: [PATCH 0201/1480] staging: r8188eu: remove unnecessary variable in ioctl_linux Returning value 0 directly instead of storing it in variable ret. This commit can prevent cocci warning as follows: Unneeded variable: "ret". Return "0" on line 3030 Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Kang Minchul Link: https://lore.kernel.org/r/20221025170621.271903-2-tegongkang@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c index 22aab3f986b4d..f3b3d74685390 100644 --- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -2979,8 +2979,6 @@ static int rtw_p2p_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - int ret = 0; - if (!memcmp(extra, "enable =", 7)) { rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]); } else if (!memcmp(extra, "setDN =", 6)) { @@ -3027,7 +3025,7 @@ static int rtw_p2p_set(struct net_device *dev, rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]); } - return ret; + return 0; } static int rtw_p2p_get2(struct net_device *dev, -- GitLab From f67469fe658a484f8c000bfcf66a191417bd6e30 Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Wed, 26 Oct 2022 02:06:19 +0900 Subject: [PATCH 0202/1480] staging: r8188eu: remove unnecessary vaiable in rtw_recv Return _SUCCESS directly instead of storing it in a variable. This can prevent cocci warning as follows: Unneeded variable: "ret". Return "_SUCCESS" on line 1516 Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Kang Minchul Link: https://lore.kernel.org/r/20221025170621.271903-3-tegongkang@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_recv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index 4b68a543f68b7..94f85cd7038dc 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -1415,7 +1415,6 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; - int ret = _SUCCESS; nr_subframes = 0; @@ -1513,7 +1512,7 @@ exit: prframe->len = 0; rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ - return ret; + return _SUCCESS; } static bool check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) -- GitLab From 0a7bf6a948b2a772ebed3915b6c47189d63dc246 Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Wed, 26 Oct 2022 02:06:20 +0900 Subject: [PATCH 0203/1480] staging: r8188eu: remove unnecessary variable in rtl8188eu_xmit Return 0 directly instead of storing it in a variable. This can prevent cocci warning as follows: Unneeded variable: "pull". Return "0" on line 298 Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Kang Minchul Link: https://lore.kernel.org/r/20221025170621.271903-4-tegongkang@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188eu_xmit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c index 8e4a5acc0b188..6d1f56d1f9d72 100644 --- a/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c @@ -149,7 +149,6 @@ static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw) static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) { - int pull = 0; uint qsel; u8 data_rate, pwr_status, offset; struct adapter *adapt = pxmitframe->padapter; @@ -295,7 +294,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag ODM_SetTxAntByTxInfo_88E(&haldata->odmpriv, pmem, pattrib->mac_id); rtl8188eu_cal_txdesc_chksum(ptxdesc); - return pull; + return 0; } /* for non-agg data frame or management frame */ -- GitLab From 95571b8db71e586c8071670fde0c6db5e4ced353 Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Wed, 26 Oct 2022 02:06:21 +0900 Subject: [PATCH 0204/1480] staging: r8188eu: make rtw_sta_flush to void Make function rtw_sta_flush to void in order to prevent cocci warning as follows: Unneeded variable: "ret". Return "0" on line 1031 Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Kang Minchul Link: https://lore.kernel.org/r/20221025170621.271903-5-tegongkang@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_ap.c | 7 ++----- drivers/staging/r8188eu/include/rtw_ap.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_ap.c b/drivers/staging/r8188eu/core/rtw_ap.c index 24eb8dce9bfeb..e0ca4b6e17cca 100644 --- a/drivers/staging/r8188eu/core/rtw_ap.c +++ b/drivers/staging/r8188eu/core/rtw_ap.c @@ -1017,10 +1017,9 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, return beacon_updated; } -int rtw_sta_flush(struct adapter *padapter) +void rtw_sta_flush(struct adapter *padapter) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1028,7 +1027,7 @@ int rtw_sta_flush(struct adapter *padapter) u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) - return ret; + return; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; @@ -1050,8 +1049,6 @@ int rtw_sta_flush(struct adapter *padapter) issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); associated_clients_update(padapter, true); - - return ret; } /* called > TSR LEVEL for USB or SDIO Interface*/ diff --git a/drivers/staging/r8188eu/include/rtw_ap.h b/drivers/staging/r8188eu/include/rtw_ap.h index 8b4134eb30956..89b02c97e041d 100644 --- a/drivers/staging/r8188eu/include/rtw_ap.h +++ b/drivers/staging/r8188eu/include/rtw_ap.h @@ -26,7 +26,7 @@ u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta); void sta_info_update(struct adapter *padapter, struct sta_info *psta); u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, bool active, u16 reason); -int rtw_sta_flush(struct adapter *padapter); +void rtw_sta_flush(struct adapter *padapter); void start_ap_mode(struct adapter *padapter); void stop_ap_mode(struct adapter *padapter); void update_bmc_sta(struct adapter *padapter); -- GitLab From f369953d9cd99a3977859a4bbad58897bc3da153 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Thu, 27 Oct 2022 20:56:27 +0700 Subject: [PATCH 0205/1480] staging: rtl8192e: rtllib_module: remove unnecessary parentheses This patch is intended to remove unnecessary parentheses in the rtllib_module.c file following the Linux kernel coding-style regulations. The modification is recommended by the checkpatch script. Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/20221027135627.vzc3woeuhrivozqz@plymouth Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 41697ef55dbd2..ce8b73f437a3d 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -107,7 +107,7 @@ struct net_device *alloc_rtllib(int sizeof_priv) spin_lock_init(&ieee->lock); spin_lock_init(&ieee->wpax_suitlist_lock); spin_lock_init(&ieee->reorder_spinlock); - atomic_set(&(ieee->atm_swbw), 0); + atomic_set(&ieee->atm_swbw, 0); /* SAM FIXME */ lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock); -- GitLab From 607732b42ce6aad76bbca3de8ea853c03e374958 Mon Sep 17 00:00:00 2001 From: Yogesh Hegde Date: Sun, 30 Oct 2022 19:02:04 +0530 Subject: [PATCH 0206/1480] staging: rtl8192e: Rename variables rateIndex and rateBitmap to avoid CamelCase Rename variables * rateIndex to rate_index * rateBitmap to rate_bitmap to avoid CamelCase which is not accepted by checkpatch.pl . Signed-off-by: Yogesh Hegde Link: https://lore.kernel.org/r/20221030133204.GA416592@zephyrus Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index c9e495538e2c7..767c746fc73d9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -2121,8 +2121,8 @@ static void _rtl92e_dm_end_sw_fsync(struct net_device *dev) static void _rtl92e_dm_start_sw_fsync(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - u32 rateIndex; - u32 rateBitmap; + u32 rate_index; + u32 rate_bitmap; priv->rate_record = 0; priv->ContinueDiffCount = 0; @@ -2136,12 +2136,12 @@ static void _rtl92e_dm_start_sw_fsync(struct net_device *dev) priv->rtllib->fsync_firstdiff_ratethreshold = 200; priv->rtllib->fsync_seconddiff_ratethreshold = 200; } - for (rateIndex = 0; rateIndex <= 27; rateIndex++) { - rateBitmap = 1 << rateIndex; - if (priv->rtllib->fsync_rate_bitmap & rateBitmap) + for (rate_index = 0; rate_index <= 27; rate_index++) { + rate_bitmap = 1 << rate_index; + if (priv->rtllib->fsync_rate_bitmap & rate_bitmap) priv->rate_record += priv->stats.received_rate_histogram[1] - [rateIndex]; + [rate_index]; } if (timer_pending(&priv->fsync_timer)) del_timer_sync(&priv->fsync_timer); -- GitLab From 130d7c481008703b4b103c9322e5fdfac130cc55 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:39:28 +0700 Subject: [PATCH 0207/1480] staging: rtl8192e: rtllib_crypt_tkip: multiple blank lines removal Removed multiple unnecessary blank lines in accordance with the Linux kernel coding-style regulations. The issues were reported by the checkpatch script. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/f2103758c23f37b61fcbe14f8ed0da8d6b31f5c6.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 24 -------------------- 1 file changed, 24 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 8bc95651e384f..468f28f48ebaa 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -91,7 +91,6 @@ fail: return NULL; } - static void rtllib_tkip_deinit(void *priv) { struct rtllib_tkip_data *_priv = priv; @@ -103,49 +102,41 @@ static void rtllib_tkip_deinit(void *priv) kfree_sensitive(priv); } - static inline u16 RotR1(u16 val) { return (val >> 1) | (val << 15); } - static inline u8 Lo8(u16 val) { return val & 0xff; } - static inline u8 Hi8(u16 val) { return val >> 8; } - static inline u16 Lo16(u32 val) { return val & 0xffff; } - static inline u16 Hi16(u32 val) { return val >> 16; } - static inline u16 Mk16(u8 hi, u8 lo) { return lo | (hi << 8); } - static inline u16 Mk16_le(u16 *v) { return *v; } - static const u16 Sbox[256] = { 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, @@ -181,17 +172,14 @@ static const u16 Sbox[256] = { 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, }; - static inline u16 _S_(u16 v) { u16 t = Sbox[Hi8(v)]; return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); } - #define PHASE1_LOOP_COUNT 8 - static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) { int i, j; @@ -213,7 +201,6 @@ static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) } } - static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, u16 IV16) { @@ -263,7 +250,6 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, #endif } - static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_tkip_data *tkey = priv; @@ -293,7 +279,6 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) } else tkey->tx_phase1_done = 1; - len = skb->len - hdr_len; pos = skb_push(skb, 8); memmove(pos, pos + 8, hdr_len); @@ -337,7 +322,6 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return ret; return 0; - } static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) @@ -453,7 +437,6 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return keyidx; } - static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr, u8 *data, size_t data_len, u8 *mic) { @@ -511,7 +494,6 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ } - static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_tkip_data *tkey = priv; @@ -539,7 +521,6 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) return 0; } - static void rtllib_michael_mic_failure(struct net_device *dev, struct rtllib_hdr_4addr *hdr, int keyidx) @@ -609,7 +590,6 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, return 0; } - static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv) { struct rtllib_tkip_data *tkey = priv; @@ -640,7 +620,6 @@ static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv) return 0; } - static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv) { struct rtllib_tkip_data *tkey = priv; @@ -671,7 +650,6 @@ static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv) return TKIP_KEY_LEN; } - static void rtllib_tkip_print_stats(struct seq_file *m, void *priv) { struct rtllib_tkip_data *tkip = priv; @@ -713,13 +691,11 @@ static struct lib80211_crypto_ops rtllib_crypt_tkip = { .owner = THIS_MODULE, }; - static int __init rtllib_crypto_tkip_init(void) { return lib80211_register_crypto_ops(&rtllib_crypt_tkip); } - static void __exit rtllib_crypto_tkip_exit(void) { lib80211_unregister_crypto_ops(&rtllib_crypt_tkip); -- GitLab From 6360fc223387179bb943d8865b853d0bb273dcf4 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:40:15 +0700 Subject: [PATCH 0208/1480] staging: rtl8192e: rtllib_crypt_tkip: blank line before close brace removal Removed multiple blank lines that are not necessary before a closing brace. The issues were found with the checkpatch script and were dealt with in accordance with the Linux kernel coding-style guidelines. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/1ba11754f1b1e39b1525a837b8493ba8434d5e3b.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 468f28f48ebaa..40930c9b00179 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -321,7 +321,6 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!tcb_desc->bHwSec) return ret; return 0; - } static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) @@ -420,7 +419,6 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) tkey->dot11RSNAStatsTKIPICVErrors++; return -5; } - } /* Update real counters only after Michael MIC verification has -- GitLab From dcbdcfca138ae185d7013e25ff02d9defd392884 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:41:08 +0700 Subject: [PATCH 0209/1480] staging: rtl8192e: rtllib_crypt_tkip: fixed alignment matching open parentheses Aligned multiple lines to be at the same indentation of open parentheses before it in accordance with the Linux kernel coding-style regulations. The issues were found by running the checkpatch script on the file. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/4253b94d6b7d94713afb02fa63d0a98686e77cc1.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 40930c9b00179..6c98f43f967e2 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -271,7 +271,7 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!tcb_desc->bHwSec) { if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); + tkey->tx_iv32); tkey->tx_phase1_done = 1; } tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, @@ -372,8 +372,8 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!tcb_desc->bHwSec || (skb->cb[0] == 1)) { if ((iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) && - tkey->initialized) { + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) && + tkey->initialized) { if (net_ratelimit()) { netdev_dbg(skb->dev, "Replay detected: STA= %pM previous TSC %08x%04x received TSC %08x%04x\n", @@ -513,7 +513,7 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; pos = skb_put(skb, 8); if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) return -1; return 0; -- GitLab From 8d1dcc729ada8e604442190e2887ff85d37ea6ca Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:41:56 +0700 Subject: [PATCH 0210/1480] staging: rtl8192e: rtllib_crypt_tkip: fixes on unbalanced braces Added braces around needed arms of statements which needs them in accordance with the Linux kernel coding-style regulations. The issues were found with the help of the checkpatch script. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/641d8360c5f86b54efc96d7f8ef70be1371db480.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 6c98f43f967e2..d1b86de76eb20 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -276,8 +276,9 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) } tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - } else + } else { tkey->tx_phase1_done = 1; + } len = skb->len - hdr_len; pos = skb_push(skb, 8); @@ -610,10 +611,11 @@ static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv) (seq[3] << 8) | seq[2]; tkey->rx_iv16 = (seq[1] << 8) | seq[0]; } - } else if (len == 0) + } else if (len == 0) { tkey->key_set = 0; - else + } else { return -1; + } return 0; } -- GitLab From 1f610736f7f40efbcac07a1c100ef703c74d30c1 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:42:55 +0700 Subject: [PATCH 0211/1480] staging: rtl8192e: rtllib_crypt_tkip: split multiple assignments Split a multiple assignments statement to individual assignments on different lines in accordance with the Linux kernel coding-style regulations. Also repositioned comments on it and the statement before for increased legibility. The multiple assignments issue was found by the checkpatch script, with the comments legibility issue were through direct observation. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/a9ab257d0042afd3b3231eefe4f58c0c3ac7649f.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index d1b86de76eb20..b8a52b9f9d070 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -488,9 +488,13 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) break; } - hdr[12] = 0; /* priority */ + /* priority */ + hdr[12] = 0; - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ + /* reserved */ + hdr[13] = 0; + hdr[14] = 0; + hdr[15] = 0; } static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) -- GitLab From 1838742b1d4e6d89d9448fba2f3340b0aaaede73 Mon Sep 17 00:00:00 2001 From: Aaron Lawrence Date: Wed, 26 Oct 2022 19:43:51 +0700 Subject: [PATCH 0212/1480] staging: rtl8192e: rtllib_crypt_tkip: rewritten comparison to NULL Rewritten a comparison to NULL with a negation operator in accordance with the Linux kernel coding-style regulations. The fix was directly recommended by the checkpatch script. Tested-by: Philipp Hortmann Signed-off-by: Aaron Lawrence Link: https://lore.kernel.org/r/ca33296630627020694f4b653580f689a8a3d1c7.1666787061.git.t4rmin@zohomail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index b8a52b9f9d070..9fdfcc017ee69 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -62,7 +62,7 @@ static void *rtllib_tkip_init(int key_idx) return NULL; priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) + if (!priv) goto fail; priv->key_idx = key_idx; -- GitLab From 1a048cde49046f37f91d340d25d7622f8f87a994 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 29 Oct 2022 19:10:10 +0200 Subject: [PATCH 0213/1480] staging: r8188eu: replace get_da with ieee80211_get_DA Replace a call to the driver-specific get_da function with ieee80211_get_DA from ieee80211.h. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221029171011.1572091-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index ffb708f242e6c..127dbc4e8b9ac 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -798,11 +798,12 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram unsigned char *p; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; u8 *pframe = precv_frame->rx_data; uint pkt_len = precv_frame->len; /* check A1 matches or not */ - if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) + if (memcmp(myid(&padapter->eeprompriv), ieee80211_get_DA(hdr), ETH_ALEN)) return; if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) -- GitLab From dbc97f832aa798c16453eeb4eb5fe74b5c998223 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 29 Oct 2022 19:10:11 +0200 Subject: [PATCH 0214/1480] staging: r8188eu: remove get_da Replace the last get_da call with ieee80211_get_DA and remove the get_da function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221029171011.1572091-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 3 ++- drivers/staging/r8188eu/include/wifi.h | 22 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c index dff0cba751df4..f01ae71bcdb11 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c @@ -108,6 +108,7 @@ void update_recvframe_attrib_88e(struct recv_frame *precvframe, struct recv_stat */ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat *pphy_status) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precvframe->rx_data; struct adapter *padapter = precvframe->adapter; struct rx_pkt_attrib *pattrib = &precvframe->attrib; struct hal_data_8188e *pHalData = &padapter->haldata; @@ -125,7 +126,7 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && - (!memcmp(get_da(wlanhdr), + (!memcmp(ieee80211_get_DA(hdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ieee80211_is_beacon(fc); diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index 6b50089cea294..92a584a8b6c07 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -217,28 +217,6 @@ enum WIFI_REG_DOMAIN { #define GetAddr4Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 24)) -static inline unsigned char *get_da(unsigned char *pframe) -{ - unsigned char *da; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); - - switch (to_fr_ds) { - case 0x00: /* ToDs=0, FromDs=0 */ - da = GetAddr1Ptr(pframe); - break; - case 0x01: /* ToDs=0, FromDs=1 */ - da = GetAddr1Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ - da = GetAddr3Ptr(pframe); - break; - default: /* ToDs=1, FromDs=1 */ - da = GetAddr3Ptr(pframe); - break; - } - return da; -} - static inline unsigned char *get_sa(unsigned char *pframe) { unsigned char *sa; -- GitLab From c5a7eecdcdb6c9d3a907ee66db2b5cffc8bdb4e1 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Tue, 25 Oct 2022 11:12:23 +0200 Subject: [PATCH 0215/1480] Revert "staging: r8712u: Tracking kmemleak false positives." This reverts commit 5d3da4a20a271e3cf5496a50cbb8118aa019374f. This commit annotated false positive for kmemleak. The reasoning is that the buffers are freed when the driver is unloaded. However, there is actually potential memory leak when probe fails. Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/26ce206b2c40c7db48c146aa6105789db9dfcc1a.1666688642.git.namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_recv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index de9a568eaffaa..4db7eed64a034 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -17,9 +17,7 @@ #define _RTL871X_RECV_C_ #include -#include #include -#include #include #include #include @@ -61,7 +59,6 @@ void _r8712_init_recv_priv(struct recv_priv *precvpriv, GFP_ATOMIC); if (!precvpriv->pallocated_frame_buf) return; - kmemleak_not_leak(precvpriv->pallocated_frame_buf); precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - ((addr_t)(precvpriv->pallocated_frame_buf) & -- GitLab From 63b5e50571ce4d87cd6c1c4d99de74c9d86fd0d8 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Tue, 25 Oct 2022 11:12:24 +0200 Subject: [PATCH 0216/1480] staging: rtl8712: check for alloc fail in _r8712_init_recv_priv() The function _r8712_init_recv_priv() and also r8712_init_recv_priv() just returns silently if they fail to allocate memory. Change their return type to int and add necessary checks and handling if they return -ENOMEM Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/506ac35a667e511db568b06b86834fd0ceeba453.1666688642.git.namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/os_intfs.c | 4 +++- drivers/staging/rtl8712/recv_osdep.h | 8 ++++---- drivers/staging/rtl8712/rtl8712_recv.c | 7 ++++--- drivers/staging/rtl8712/rtl871x_recv.c | 13 +++++++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 003e972051240..12adb470d216c 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -309,7 +309,9 @@ int r8712_init_drv_sw(struct _adapter *padapter) if (ret) return ret; _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); - _r8712_init_recv_priv(&padapter->recvpriv, padapter); + ret = _r8712_init_recv_priv(&padapter->recvpriv, padapter); + if (ret) + return ret; memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); timer_setup(&padapter->securitypriv.tkip_timer, diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h index d8c1fa74f5440..fbe3f28685064 100644 --- a/drivers/staging/rtl8712/recv_osdep.h +++ b/drivers/staging/rtl8712/recv_osdep.h @@ -18,15 +18,15 @@ #include "drv_types.h" #include -void _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); +int _r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter); void _r8712_free_recv_priv(struct recv_priv *precvpriv); void r8712_recv_entry(union recv_frame *precv_frame); void r8712_recv_indicatepkt(struct _adapter *adapter, union recv_frame *precv_frame); void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup); -void r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); +int r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter); void r8712_free_recv_priv(struct recv_priv *precvpriv); void r8712_os_recv_resource_alloc(struct _adapter *padapter, union recv_frame *precvframe); diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 7f1fdd0585511..7da014ab0723e 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -30,8 +30,8 @@ static void recv_tasklet(struct tasklet_struct *t); -void r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) +int r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter) { int i; struct recv_buf *precvbuf; @@ -44,7 +44,7 @@ void r8712_init_recv_priv(struct recv_priv *precvpriv, precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_ATOMIC); if (!precvpriv->pallocated_recv_buf) - return; + return -ENOMEM; precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 - ((addr_t)(precvpriv->pallocated_recv_buf) & 3); precvbuf = (struct recv_buf *)precvpriv->precv_buf; @@ -75,6 +75,7 @@ void r8712_init_recv_priv(struct recv_priv *precvpriv, } pskb = NULL; } + return 0; } void r8712_free_recv_priv(struct recv_priv *precvpriv) diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 4db7eed64a034..8a3566214af72 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -42,9 +42,10 @@ void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) _init_queue(&psta_recvpriv->defrag_q); } -void _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) +int _r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter) { + int ret; sint i; union recv_frame *precvframe; @@ -58,7 +59,7 @@ void _r8712_init_recv_priv(struct recv_priv *precvpriv, sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, GFP_ATOMIC); if (!precvpriv->pallocated_frame_buf) - return; + return -ENOMEM; precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - ((addr_t)(precvpriv->pallocated_frame_buf) & @@ -73,7 +74,11 @@ void _r8712_init_recv_priv(struct recv_priv *precvpriv, precvframe++; } precvpriv->rx_pending_cnt = 1; - r8712_init_recv_priv(precvpriv, padapter); + ret = r8712_init_recv_priv(precvpriv, padapter); + if (ret) + kfree(precvpriv->pallocated_frame_buf); + + return ret; } void _r8712_free_recv_priv(struct recv_priv *precvpriv) -- GitLab From 242443430dd8ef932a56cf483080a46f2948dd65 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Tue, 25 Oct 2022 11:12:25 +0200 Subject: [PATCH 0217/1480] staging: rtl8712: check for return value of _r8712_init_xmit_priv() The return value of _r8712_init_xmit_priv() is never checked and the driver always continue execution as if all is well. This will cause problems if, for example, buffers cannot be allocated and the driver continue and use those buffers. Check for return value of _r8712_init_xmit_priv() and return error (if any) during probing. Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/b550803561acf26af71f2377215c28b94435a644.1666688642.git.namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/os_intfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 12adb470d216c..205b7d66a40ab 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -308,7 +308,9 @@ int r8712_init_drv_sw(struct _adapter *padapter) ret = r8712_init_mlme_priv(padapter); if (ret) return ret; - _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); + ret = _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); + if (ret) + return ret; ret = _r8712_init_recv_priv(&padapter->recvpriv, padapter); if (ret) return ret; -- GitLab From 336ccc31cda111c830332d4b56def49c9c1d48e6 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Tue, 25 Oct 2022 11:12:26 +0200 Subject: [PATCH 0218/1480] staging: rtl8712: fix potential memory leak In r8712_init_drv_sw(), whenever any function call returns error, it is returned immediately without properly cleaning up the other successfully executed functions. This can cause memory leak. Instead of return immediately, free all the allocated buffers first. Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/0a3414b12031f6cdcba81a8725e91eb9567ff34f.1666688642.git.namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/os_intfs.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 205b7d66a40ab..a2f3645be0cc8 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -304,29 +304,42 @@ int r8712_init_drv_sw(struct _adapter *padapter) padapter->cmdpriv.padapter = padapter; ret = r8712_init_evt_priv(&padapter->evtpriv); if (ret) - return ret; + goto free_cmd; ret = r8712_init_mlme_priv(padapter); if (ret) - return ret; + goto free_evt; ret = _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); if (ret) - return ret; + goto free_mlme; ret = _r8712_init_recv_priv(&padapter->recvpriv, padapter); if (ret) - return ret; + goto free_xmit; memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); timer_setup(&padapter->securitypriv.tkip_timer, r8712_use_tkipkey_handler, 0); ret = _r8712_init_sta_priv(&padapter->stapriv); if (ret) - return ret; + goto free_recv; padapter->stapriv.padapter = padapter; r8712_init_bcmc_stainfo(padapter); r8712_init_pwrctrl_priv(padapter); mp871xinit(padapter); init_default_value(padapter); r8712_InitSwLeds(padapter); + + return 0; + +free_recv: + _r8712_free_recv_priv(&padapter->recvpriv); +free_xmit: + _free_xmit_priv(&padapter->xmitpriv); +free_mlme: + r8712_free_mlme_priv(&padapter->mlmepriv); +free_evt: + r8712_free_evt_priv(&padapter->evtpriv); +free_cmd: + r8712_free_cmd_priv(&padapter->cmdpriv); return ret; } -- GitLab From 5c4fb46e9116bd7cf87bd76b417a865626e13c30 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:14 +0100 Subject: [PATCH 0219/1480] staging: r8188eu: replace a GetAddr1Ptr call Define a struct ieee80211_mgmt and use it to read the destination address. This replaces one call to the driver-specific GetAddr1Ptr function, which should eventually be removed. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 127dbc4e8b9ac..5a366688a3f7d 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3815,13 +3815,14 @@ exit: unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; unsigned int ret = _FAIL; u8 *pframe = precv_frame->rx_data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 category, action; /* check RA matches or not */ - if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN)) + if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) goto exit; category = frame_body[0]; -- GitLab From 5998e3192274da5fd9521b1019cc62b5ea2283b7 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:15 +0100 Subject: [PATCH 0220/1480] staging: r8188eu: remove duplicate category check The caller of on_action_public has already checked the action category. We can remove the check in on_action_public. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 5a366688a3f7d..7d4f208d161bb 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3819,16 +3819,12 @@ unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv unsigned int ret = _FAIL; u8 *pframe = precv_frame->rx_data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); - u8 category, action; + u8 action; /* check RA matches or not */ if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) goto exit; - category = frame_body[0]; - if (category != WLAN_CATEGORY_PUBLIC) - goto exit; - action = frame_body[1]; switch (action) { case ACT_PUBLIC_VENDOR: -- GitLab From 721d7f496a0602d061bd127bd88de7e70181f521 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:16 +0100 Subject: [PATCH 0221/1480] staging: r8188eu: make on_action_public static void The on_action_public function is called only by OnAction. This function also lives in rtw_mlme_ext.c and does not check the return value from on_action_public. We can make on_action_public a static void function. The ret variable is no longer needed if we don't return a value. It can be removed. Reported-by: kernel test robot Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 12 ++++-------- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 7d4f208d161bb..88600f62ffb4b 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3813,30 +3813,26 @@ exit: return ret; } -unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) +static void on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - unsigned int ret = _FAIL; u8 *pframe = precv_frame->rx_data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 action; /* check RA matches or not */ if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) - goto exit; + return; action = frame_body[1]; switch (action) { case ACT_PUBLIC_VENDOR: - ret = on_action_public_vendor(precv_frame); + on_action_public_vendor(precv_frame); break; default: - ret = on_action_public_default(precv_frame); + on_action_public_default(precv_frame); break; } - -exit: - return ret; } unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index c8beaa927cba1..ec2e9352011be 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -538,8 +538,6 @@ void start_create_ibss(struct adapter *padapter); unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame); -unsigned int on_action_public(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame); -- GitLab From b22b8618ab3cf011a5536e30e3fb99b32c911ecb Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:17 +0100 Subject: [PATCH 0222/1480] staging: r8188eu: make OnAction_back static void OnAction_back is called only by OnAction, its return value is not checked. We can make it a static void function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 13 +++++-------- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 88600f62ffb4b..779c022b1c506 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1481,7 +1481,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } -unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; struct sta_info *psta = NULL; @@ -1494,21 +1494,20 @@ unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_fr struct sta_priv *pstapriv = &padapter->stapriv; /* check RA matches or not */ if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN))/* for if1, sta/ap mode */ - return _SUCCESS; + return; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) - return _SUCCESS; + return; psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (!psta) - return _SUCCESS; + return; frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); if (!pmlmeinfo->HT_enable) - return _SUCCESS; + return; /* All union members start with an action code, it's ok to use addba_req. */ switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: @@ -1550,8 +1549,6 @@ unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_fr default: break; } - - return _SUCCESS; } static int get_reg_classes_full_count(struct p2p_channels *channel_list) diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index ec2e9352011be..4ccdce1ad9be3 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,8 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnAction_back(struct adapter *padapter, - struct recv_frame *precv_frame); unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame); -- GitLab From aa415931f9682fd4ac71ac34ffa5c157cef2b680 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:18 +0100 Subject: [PATCH 0223/1480] staging: r8188eu: make OnAction_p2p static void OnAction_p2p is called only by OnAction, its return value is not checked. We can make it a static void function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 9 ++++----- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 3 --- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 779c022b1c506..f1054192bfb19 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3832,7 +3832,7 @@ static void on_action_public(struct adapter *padapter, struct recv_frame *precv_ } } -unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) +static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) { u8 *frame_body; u8 category, OUI_Subtype; @@ -3842,16 +3842,16 @@ unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fra /* check RA matches or not */ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ - return _SUCCESS; + return; frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); category = frame_body[0]; if (category != RTW_WLAN_CATEGORY_P2P) - return _SUCCESS; + return; if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) - return _SUCCESS; + return; len -= sizeof(struct ieee80211_hdr_3addr); OUI_Subtype = frame_body[5]; @@ -3869,7 +3869,6 @@ unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fra default: break; } - return _SUCCESS; } static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 4ccdce1ad9be3..ce5b57e23e53b 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -536,9 +536,6 @@ void start_clnt_auth(struct adapter *padapter); void start_clnt_join(struct adapter *padapter); void start_create_ibss(struct adapter *padapter); -unsigned int OnAction_p2p(struct adapter *padapter, - struct recv_frame *precv_frame); - void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res); void mlmeext_sta_del_event_callback(struct adapter *padapter); void mlmeext_sta_add_event_callback(struct adapter *padapter, -- GitLab From b31b29788f103c2720898af2d499d8b53c1eb980 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:19 +0100 Subject: [PATCH 0224/1480] staging: r8188eu: remove category check in OnAction_p2p The caller of OnAction_p2p has already checked the action category. We can remove the check in OnAction_p2p. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index f1054192bfb19..efcb2f3b6d3f7 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3835,7 +3835,7 @@ static void on_action_public(struct adapter *padapter, struct recv_frame *precv_ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) { u8 *frame_body; - u8 category, OUI_Subtype; + u8 OUI_Subtype; u8 *pframe = precv_frame->rx_data; uint len = precv_frame->len; struct wifidirect_info *pwdinfo = &padapter->wdinfo; @@ -3846,10 +3846,6 @@ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fram frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); - category = frame_body[0]; - if (category != RTW_WLAN_CATEGORY_P2P) - return; - if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) return; -- GitLab From e246bf42ef82ac25d8a7ad45ddd07fbf161f7e7f Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:20 +0100 Subject: [PATCH 0225/1480] staging: r8188eu: replace switch-case with if OnAction_p2p has a switch-case statement where only a single case is handled. Use if instead, this makes the code shorter and easier to read. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index efcb2f3b6d3f7..64d01da9c8140 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3852,19 +3852,8 @@ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fram len -= sizeof(struct ieee80211_hdr_3addr); OUI_Subtype = frame_body[5]; - switch (OUI_Subtype) { - case P2P_NOTICE_OF_ABSENCE: - break; - case P2P_PRESENCE_REQUEST: + if (OUI_Subtype == P2P_PRESENCE_REQUEST) process_p2p_presence_req(pwdinfo, pframe, len); - break; - case P2P_PRESENCE_RESPONSE: - break; - case P2P_GO_DISC_REQUEST: - break; - default: - break; - } } static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) -- GitLab From fc47cb05cf19017c3eb87da9b82e20f57b595ad3 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:21 +0100 Subject: [PATCH 0226/1480] staging: r8188eu: replace GetAddr1Ptr call in OnAction_p2p Define a struct ieee80211_mgmt in OnAction_p2p and use it to check the destination address. This replaces a call to the driver-specific GetAddr1Ptr function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 64d01da9c8140..6d95d3bc23e6c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3834,6 +3834,7 @@ static void on_action_public(struct adapter *padapter, struct recv_frame *precv_ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; u8 *frame_body; u8 OUI_Subtype; u8 *pframe = precv_frame->rx_data; @@ -3841,7 +3842,7 @@ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_fram struct wifidirect_info *pwdinfo = &padapter->wdinfo; /* check RA matches or not */ - if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ + if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN))/* for if1, sta/ap mode */ return; frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); -- GitLab From a05159da5a4e49fd4b34cb00fb33badeb4dc9ec3 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:22 +0100 Subject: [PATCH 0227/1480] staging: r8188eu: clean up on_action_public Use the struct mgmt to read the action_code. This is much simpler than parsing the message ourselves. Add a comment about reading the action code. All members of the action enum start with an action_code byte. It does not matter which member we use. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 6d95d3bc23e6c..b3cef3504ad30 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3813,23 +3813,16 @@ exit: static void on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - u8 *pframe = precv_frame->rx_data; - u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); - u8 action; /* check RA matches or not */ if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) return; - action = frame_body[1]; - switch (action) { - case ACT_PUBLIC_VENDOR: + /* All members of the action enum start with action_code. */ + if (mgmt->u.action.u.s1g.action_code == WLAN_PUB_ACTION_VENDOR_SPECIFIC) on_action_public_vendor(precv_frame); - break; - default: + else on_action_public_default(precv_frame); - break; - } } static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) -- GitLab From a399a3b05209dc759b20c6d6e4aa331f2e60bc8a Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:23 +0100 Subject: [PATCH 0228/1480] staging: r8188eu: remove return value from on_action_public_vendor The only caller of on_action_public_vendor does not check the return value. We can make it a void function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-11-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index b3cef3504ad30..b395457a6a60a 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3779,17 +3779,13 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame) return _SUCCESS; } -static unsigned int on_action_public_vendor(struct recv_frame *precv_frame) +static void on_action_public_vendor(struct recv_frame *precv_frame) { - unsigned int ret = _FAIL; u8 *pframe = precv_frame->rx_data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); - if (!memcmp(frame_body + 2, P2P_OUI, 4)) { - ret = on_action_public_p2p(precv_frame); - } - - return ret; + if (!memcmp(frame_body + 2, P2P_OUI, 4)) + on_action_public_p2p(precv_frame); } static unsigned int on_action_public_default(struct recv_frame *precv_frame) -- GitLab From 8161a8335821bb6944eef2de8b750544d59c49c2 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:24 +0100 Subject: [PATCH 0229/1480] staging: r8188eu: remove return value from on_action_public_default The only caller of on_action_public_default does not check the return value. We can make it a void function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-12-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index b395457a6a60a..f5923792f0675 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3788,22 +3788,15 @@ static void on_action_public_vendor(struct recv_frame *precv_frame) on_action_public_p2p(precv_frame); } -static unsigned int on_action_public_default(struct recv_frame *precv_frame) +static void on_action_public_default(struct recv_frame *precv_frame) { - unsigned int ret = _FAIL; u8 *pframe = precv_frame->rx_data; u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); u8 token; token = frame_body[2]; - if (rtw_action_public_decache(precv_frame, token) == _FAIL) - goto exit; - - ret = _SUCCESS; - -exit: - return ret; + rtw_action_public_decache(precv_frame, token); } static void on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) -- GitLab From 9001c5029dded946e7862e5785278f7c1d9dfe55 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:25 +0100 Subject: [PATCH 0230/1480] staging: r8188eu: rtw_action_public_decache's token is a u8 Both callers of rtw_action_public_decache pass a u8 value for the token parameter. We can change token from s32 to u8 and remove the code for token < 0. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-13-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index f5923792f0675..93f3d387e92dd 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3490,7 +3490,7 @@ inline void issue_probereq_p2p(struct adapter *adapter, u8 *da) _issue_probereq_p2p(adapter, da); } -static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) +static s32 rtw_action_public_decache(struct recv_frame *recv_frame, u8 token) { struct adapter *adapter = recv_frame->adapter; struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; @@ -3499,21 +3499,13 @@ static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) (recv_frame->attrib.frag_num & 0xf); if (GetRetry(frame)) { - if (token >= 0) { - if ((seq_ctrl == mlmeext->action_public_rxseq) && - (token == mlmeext->action_public_dialog_token)) - return _FAIL; - } else { - if (seq_ctrl == mlmeext->action_public_rxseq) - return _FAIL; - } + if ((seq_ctrl == mlmeext->action_public_rxseq) && + (token == mlmeext->action_public_dialog_token)) + return _FAIL; } mlmeext->action_public_rxseq = seq_ctrl; - - if (token >= 0) - mlmeext->action_public_dialog_token = token; - + mlmeext->action_public_dialog_token = token; return _SUCCESS; } -- GitLab From ae85931f8f483ed58f7c90c99c75afd8482e0399 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 30 Oct 2022 18:33:26 +0100 Subject: [PATCH 0231/1480] staging: r8188eu: check destination address in OnAction All subfunctions of OnAction check if the destination address matches the local interface's address. It's simpler to move this check to OnAction. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221030173326.1588647-14-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 93f3d387e92dd..e985fc5fc575e 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1492,9 +1492,6 @@ static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_fra struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->rx_data; struct sta_priv *pstapriv = &padapter->stapriv; - /* check RA matches or not */ - if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN))/* for if1, sta/ap mode */ - return; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) @@ -3795,10 +3792,6 @@ static void on_action_public(struct adapter *padapter, struct recv_frame *precv_ { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - /* check RA matches or not */ - if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) - return; - /* All members of the action enum start with action_code. */ if (mgmt->u.action.u.s1g.action_code == WLAN_PUB_ACTION_VENDOR_SPECIFIC) on_action_public_vendor(precv_frame); @@ -3808,17 +3801,12 @@ static void on_action_public(struct adapter *padapter, struct recv_frame *precv_ static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) { - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; u8 *frame_body; u8 OUI_Subtype; u8 *pframe = precv_frame->rx_data; uint len = precv_frame->len; struct wifidirect_info *pwdinfo = &padapter->wdinfo; - /* check RA matches or not */ - if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN))/* for if1, sta/ap mode */ - return; - frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) @@ -3835,6 +3823,9 @@ static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; + if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) + return; + switch (mgmt->u.action.category) { case WLAN_CATEGORY_BACK: OnAction_back(padapter, precv_frame); -- GitLab From 3c728e079d83f581a1f8b7755f6e26087b15c4fb Mon Sep 17 00:00:00 2001 From: Tamas Zsoldos Date: Tue, 5 Jul 2022 16:59:35 +0200 Subject: [PATCH 0232/1480] coresight: etm4x: add CPU hotplug support for probing etm4x devices cannot be successfully probed when their CPU is offline. For example, when booting with maxcpus=n, ETM probing will fail on CPUs >n, and the probing won't be reattempted once the CPUs come online. This will leave those CPUs unable to make use of ETM. This change adds a mechanism to delay the probing if the corresponding CPU is offline, and to try it again when the CPU comes online. Signed-off-by: Tamas Zsoldos Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20220705145935.24679-1-tamas.zsoldos@arm.com --- .../coresight/coresight-etm4x-core.c | 153 +++++++++++++----- 1 file changed, 113 insertions(+), 40 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 80fefaba58eeb..9dc0d7f57565a 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -66,10 +66,13 @@ static enum cpuhp_state hp_online; struct etm4_init_arg { unsigned int pid; - struct etmv4_drvdata *drvdata; + struct device *dev; struct csdev_access *csa; }; +static DEFINE_PER_CPU(struct etm4_init_arg *, delayed_probe); +static int etm4_probe_cpu(unsigned int cpu); + /* * Check if TRCSSPCICRn(i) is implemented for a given instance. * @@ -1085,7 +1088,7 @@ static void etm4_init_arch_data(void *info) struct csdev_access *csa; int i; - drvdata = init_arg->drvdata; + drvdata = dev_get_drvdata(init_arg->dev); csa = init_arg->csa; /* @@ -1528,7 +1531,7 @@ void etm4_config_trace_mode(struct etmv4_config *config) static int etm4_online_cpu(unsigned int cpu) { if (!etmdrvdata[cpu]) - return 0; + return etm4_probe_cpu(cpu); if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) coresight_enable(etmdrvdata[cpu]->csdev); @@ -1904,48 +1907,20 @@ static void etm4_pm_clear(void) } } -static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid) +static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg) { int ret; struct coresight_platform_data *pdata = NULL; - struct etmv4_drvdata *drvdata; + struct device *dev = init_arg->dev; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); struct coresight_desc desc = { 0 }; - struct etm4_init_arg init_arg = { 0 }; u8 major, minor; char *type_name; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) - return -ENOMEM; - - dev_set_drvdata(dev, drvdata); - - if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE) - pm_save_enable = coresight_loses_context_with_cpu(dev) ? - PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER; - - if (pm_save_enable != PARAM_PM_SAVE_NEVER) { - drvdata->save_state = devm_kmalloc(dev, - sizeof(struct etmv4_save_state), GFP_KERNEL); - if (!drvdata->save_state) - return -ENOMEM; - } - - drvdata->base = base; - - spin_lock_init(&drvdata->spinlock); - - drvdata->cpu = coresight_get_cpu(dev); - if (drvdata->cpu < 0) - return drvdata->cpu; - - init_arg.drvdata = drvdata; - init_arg.csa = &desc.access; - init_arg.pid = etm_pid; + return -EINVAL; - if (smp_call_function_single(drvdata->cpu, - etm4_init_arch_data, &init_arg, 1)) - dev_err(dev, "ETM arch init failed\n"); + desc.access = *init_arg->csa; if (!drvdata->arch) return -EINVAL; @@ -2016,6 +1991,68 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid) return 0; } +static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid) +{ + struct etmv4_drvdata *drvdata; + struct csdev_access access = { 0 }; + struct etm4_init_arg init_arg = { 0 }; + struct etm4_init_arg *delayed; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + dev_set_drvdata(dev, drvdata); + + if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE) + pm_save_enable = coresight_loses_context_with_cpu(dev) ? + PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER; + + if (pm_save_enable != PARAM_PM_SAVE_NEVER) { + drvdata->save_state = devm_kmalloc(dev, + sizeof(struct etmv4_save_state), GFP_KERNEL); + if (!drvdata->save_state) + return -ENOMEM; + } + + drvdata->base = base; + + spin_lock_init(&drvdata->spinlock); + + drvdata->cpu = coresight_get_cpu(dev); + if (drvdata->cpu < 0) + return drvdata->cpu; + + init_arg.dev = dev; + init_arg.csa = &access; + init_arg.pid = etm_pid; + + /* + * Serialize against CPUHP callbacks to avoid race condition + * between the smp call and saving the delayed probe. + */ + cpus_read_lock(); + if (smp_call_function_single(drvdata->cpu, + etm4_init_arch_data, &init_arg, 1)) { + /* The CPU was offline, try again once it comes online. */ + delayed = devm_kmalloc(dev, sizeof(*delayed), GFP_KERNEL); + if (!delayed) { + cpus_read_unlock(); + return -ENOMEM; + } + + *delayed = init_arg; + + per_cpu(delayed_probe, drvdata->cpu) = delayed; + + cpus_read_unlock(); + return 0; + } + cpus_read_unlock(); + + return etm4_add_coresight_dev(&init_arg); +} + static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id) { void __iomem *base; @@ -2054,6 +2091,35 @@ static int etm4_probe_platform_dev(struct platform_device *pdev) return ret; } +static int etm4_probe_cpu(unsigned int cpu) +{ + int ret; + struct etm4_init_arg init_arg; + struct csdev_access access = { 0 }; + struct etm4_init_arg *iap = *this_cpu_ptr(&delayed_probe); + + if (!iap) + return 0; + + init_arg = *iap; + devm_kfree(init_arg.dev, iap); + *this_cpu_ptr(&delayed_probe) = NULL; + + ret = pm_runtime_resume_and_get(init_arg.dev); + if (ret < 0) { + dev_err(init_arg.dev, "Failed to get PM runtime!\n"); + return 0; + } + + init_arg.csa = &access; + etm4_init_arch_data(&init_arg); + + etm4_add_coresight_dev(&init_arg); + + pm_runtime_put(init_arg.dev); + return 0; +} + static struct amba_cs_uci_id uci_id_etm4[] = { { /* ETMv4 UCI data */ @@ -2068,16 +2134,20 @@ static void clear_etmdrvdata(void *info) int cpu = *(int *)info; etmdrvdata[cpu] = NULL; + per_cpu(delayed_probe, cpu) = NULL; } static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) { - etm_perf_symlink(drvdata->csdev, false); + bool had_delayed_probe; /* * Taking hotplug lock here to avoid racing between etm4_remove_dev() * and CPU hotplug call backs. */ cpus_read_lock(); + + had_delayed_probe = per_cpu(delayed_probe, drvdata->cpu); + /* * The readers for etmdrvdata[] are CPU hotplug call backs * and PM notification call backs. Change etmdrvdata[i] on @@ -2085,12 +2155,15 @@ static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) * inside one call back function. */ if (smp_call_function_single(drvdata->cpu, clear_etmdrvdata, &drvdata->cpu, 1)) - etmdrvdata[drvdata->cpu] = NULL; + clear_etmdrvdata(&drvdata->cpu); cpus_read_unlock(); - cscfg_unregister_csdev(drvdata->csdev); - coresight_unregister(drvdata->csdev); + if (!had_delayed_probe) { + etm_perf_symlink(drvdata->csdev, false); + cscfg_unregister_csdev(drvdata->csdev); + coresight_unregister(drvdata->csdev); + } return 0; } -- GitLab From 8d0d129e94d4518fd17c13b4991ff10b7f4cd85a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2022 13:52:17 -0300 Subject: [PATCH 0233/1480] perf bpf: No need to include headers just use forward declarations In the bpf-prologue.h header we are just using pointers, so no need to include headers for that, just provide forward declarations for those types. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-prologue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/bpf-prologue.h b/tools/perf/util/bpf-prologue.h index c50c7358009f2..66dcf751ef654 100644 --- a/tools/perf/util/bpf-prologue.h +++ b/tools/perf/util/bpf-prologue.h @@ -6,9 +6,8 @@ #ifndef __BPF_PROLOGUE_H #define __BPF_PROLOGUE_H -#include -#include -#include "probe-event.h" +struct probe_trace_arg; +struct bpf_insn; #define BPF_PROLOGUE_MAX_ARGS 3 #define BPF_PROLOGUE_START_ARG_REG BPF_REG_3 @@ -19,6 +18,7 @@ int bpf__gen_prologue(struct probe_trace_arg *args, int nargs, struct bpf_insn *new_prog, size_t *new_cnt, size_t cnt_space); #else +#include #include static inline int -- GitLab From 08043330167f1e21abe60ff7e124ed87d4fd029d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2022 17:02:23 -0300 Subject: [PATCH 0234/1480] perf branch: Remove some needless headers, add a needed one map_symbol.h is needed because we have structs that contains 'struct addr_map_symbol', so add it, remove the others. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/branch.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index f838b23db1804..94f36a187fe73 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -7,11 +7,9 @@ * detected in at least musl libc, used in Alpine Linux. -acme */ #include -#include -#include -#include #include #include +#include "util/map_symbol.h" #include "event.h" struct branch_flags { -- GitLab From 9823147da6c893d9295949e5ed982a8630deb6db Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2022 17:24:27 -0300 Subject: [PATCH 0235/1480] perf tools: Move 'struct perf_sample' to a separate header file to disentangle headers Some places were including event.h just to get 'struct perf_sample', move it to a separate place so that we speed up a bit the build. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/unwind-libdw.c | 2 +- tools/perf/arch/arm64/util/machine.c | 1 + tools/perf/arch/arm64/util/unwind-libdw.c | 2 +- tools/perf/arch/powerpc/util/event.c | 1 + tools/perf/arch/powerpc/util/unwind-libdw.c | 2 +- tools/perf/arch/s390/util/unwind-libdw.c | 1 + tools/perf/arch/x86/tests/sample-parsing.c | 1 + tools/perf/arch/x86/util/event.c | 1 + tools/perf/arch/x86/util/unwind-libdw.c | 2 +- tools/perf/bench/inject-buildid.c | 2 +- tools/perf/builtin-mem.c | 1 + tools/perf/tests/dlfilter-test.c | 1 + tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 1 + tools/perf/tests/parse-no-sample-id-all.c | 1 + tools/perf/tests/perf-record.c | 1 + tools/perf/tests/perf-time-to-tsc.c | 1 + tools/perf/tests/sw-clock.c | 1 + tools/perf/tests/switch-tracking.c | 1 + tools/perf/util/amd-sample-raw.c | 1 + tools/perf/util/auxtrace.c | 1 + tools/perf/util/branch.h | 2 +- tools/perf/util/data-convert-bt.c | 1 + tools/perf/util/event.h | 111 +---------------- tools/perf/util/evlist.c | 1 + .../intel-pt-decoder/intel-pt-insn-decoder.c | 1 + tools/perf/util/perf_regs.c | 2 +- tools/perf/util/s390-cpumsf.c | 1 + tools/perf/util/s390-sample-raw.c | 1 + tools/perf/util/sample.h | 117 ++++++++++++++++++ tools/perf/util/trace-event-scripting.c | 2 +- 31 files changed, 147 insertions(+), 118 deletions(-) create mode 100644 tools/perf/util/sample.h diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/arch/arm/util/unwind-libdw.c index b7692cb0c7339..1834a0cd9ce3a 100644 --- a/tools/perf/arch/arm/util/unwind-libdw.c +++ b/tools/perf/arch/arm/util/unwind-libdw.c @@ -2,7 +2,7 @@ #include #include "../../../util/unwind-libdw.h" #include "../../../util/perf_regs.h" -#include "../../../util/event.h" +#include "../../../util/sample.h" bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) { diff --git a/tools/perf/arch/arm64/util/machine.c b/tools/perf/arch/arm64/util/machine.c index 41c1596e52071..235a0a1e1ec7b 100644 --- a/tools/perf/arch/arm64/util/machine.c +++ b/tools/perf/arch/arm64/util/machine.c @@ -7,6 +7,7 @@ #include "symbol.h" #include "callchain.h" #include "record.h" +#include "util/perf_regs.h" void arch__add_leaf_frame_record_opts(struct record_opts *opts) { diff --git a/tools/perf/arch/arm64/util/unwind-libdw.c b/tools/perf/arch/arm64/util/unwind-libdw.c index a509416296495..09385081bb03c 100644 --- a/tools/perf/arch/arm64/util/unwind-libdw.c +++ b/tools/perf/arch/arm64/util/unwind-libdw.c @@ -2,7 +2,7 @@ #include #include "../../../util/unwind-libdw.h" #include "../../../util/perf_regs.h" -#include "../../../util/event.h" +#include "../../../util/sample.h" bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) { diff --git a/tools/perf/arch/powerpc/util/event.c b/tools/perf/arch/powerpc/util/event.c index cf430a4c55b9a..77d8cc2b5691f 100644 --- a/tools/perf/arch/powerpc/util/event.c +++ b/tools/perf/arch/powerpc/util/event.c @@ -9,6 +9,7 @@ #include "../../../util/tool.h" #include "../../../util/map.h" #include "../../../util/debug.h" +#include "../../../util/sample.h" void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type) diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c index 7b2d96ec28e39..e616642c754c4 100644 --- a/tools/perf/arch/powerpc/util/unwind-libdw.c +++ b/tools/perf/arch/powerpc/util/unwind-libdw.c @@ -3,7 +3,7 @@ #include #include "../../../util/unwind-libdw.h" #include "../../../util/perf_regs.h" -#include "../../../util/event.h" +#include "../../../util/sample.h" /* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ static const int special_regs[3][2] = { diff --git a/tools/perf/arch/s390/util/unwind-libdw.c b/tools/perf/arch/s390/util/unwind-libdw.c index 387c698cdd1be..7d92452d52877 100644 --- a/tools/perf/arch/s390/util/unwind-libdw.c +++ b/tools/perf/arch/s390/util/unwind-libdw.c @@ -3,6 +3,7 @@ #include "../../util/unwind-libdw.h" #include "../../util/perf_regs.h" #include "../../util/event.h" +#include "../../util/sample.h" #include "dwarf-regs-table.h" diff --git a/tools/perf/arch/x86/tests/sample-parsing.c b/tools/perf/arch/x86/tests/sample-parsing.c index bfbd3662b69e8..690c7c07e90d1 100644 --- a/tools/perf/arch/x86/tests/sample-parsing.c +++ b/tools/perf/arch/x86/tests/sample-parsing.c @@ -10,6 +10,7 @@ #include "event.h" #include "evsel.h" #include "debug.h" +#include "util/sample.h" #include "util/synthetic-events.h" #include "tests/tests.h" diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index 55ff6aec10fdd..a3acefe6d0c65 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -10,6 +10,7 @@ #include "../../../util/tool.h" #include "../../../util/map.h" #include "../../../util/debug.h" +#include "util/sample.h" #if defined(__x86_64__) diff --git a/tools/perf/arch/x86/util/unwind-libdw.c b/tools/perf/arch/x86/util/unwind-libdw.c index eea2bf87232b2..ef71e8bf80bf5 100644 --- a/tools/perf/arch/x86/util/unwind-libdw.c +++ b/tools/perf/arch/x86/util/unwind-libdw.c @@ -2,7 +2,7 @@ #include #include "../../../util/unwind-libdw.h" #include "../../../util/perf_regs.h" -#include "../../../util/event.h" +#include "util/sample.h" bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) { diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c index 17672790f1231..4561bda0ce6ad 100644 --- a/tools/perf/bench/inject-buildid.c +++ b/tools/perf/bench/inject-buildid.c @@ -19,10 +19,10 @@ #include "util/data.h" #include "util/stat.h" #include "util/debug.h" -#include "util/event.h" #include "util/symbol.h" #include "util/session.h" #include "util/build-id.h" +#include "util/sample.h" #include "util/synthetic-events.h" #define MMAP_DEV_MAJOR 8 diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 923fb8316fdae..dedd612eae5e0 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -20,6 +20,7 @@ #include "util/symbol.h" #include "util/pmu.h" #include "util/pmu-hybrid.h" +#include "util/sample.h" #include "util/string2.h" #include diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c index 84352d55347d5..99aa72e425e4d 100644 --- a/tools/perf/tests/dlfilter-test.c +++ b/tools/perf/tests/dlfilter-test.c @@ -33,6 +33,7 @@ #include "archinsn.h" #include "dlfilter.h" #include "tests.h" +#include "util/sample.h" #define MAP_START 0x400000 diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 8322fc2295fa0..6377906c13183 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -10,6 +10,7 @@ #include "thread_map.h" #include "tests.h" #include "util/mmap.h" +#include "util/sample.h" #include #include #include diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index a7b2800652e4c..888df8eca9812 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -14,6 +14,7 @@ #include "util/mmap.h" #include #include +#include "util/sample.h" #ifndef O_DIRECTORY #define O_DIRECTORY 00200000 diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index d62e31595ab21..202f0a9a6796b 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -8,6 +8,7 @@ #include "evlist.h" #include "header.h" #include "debug.h" +#include "util/sample.h" static int process_event(struct evlist **pevlist, union perf_event *event) { diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 7aa946aa886de..d82539e2ae648 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -11,6 +11,7 @@ #include "record.h" #include "tests.h" #include "util/mmap.h" +#include "util/sample.h" static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) { diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index c3aaa1ddff29f..efcd71c2738af 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -20,6 +20,7 @@ #include "tsc.h" #include "mmap.h" #include "tests.h" +#include "util/sample.h" /* * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. Just diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 9cd6fec375eeb..4d7493fa01059 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -13,6 +13,7 @@ #include "util/evlist.h" #include "util/cpumap.h" #include "util/mmap.h" +#include "util/sample.h" #include "util/thread_map.h" #include #include diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 87f565c7f650d..b3bd14b025a89 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -19,6 +19,7 @@ #include "record.h" #include "tests.h" #include "util/mmap.h" +#include "util/sample.h" #include "pmu.h" static int spin_sleep(void) diff --git a/tools/perf/util/amd-sample-raw.c b/tools/perf/util/amd-sample-raw.c index 2383058686444..b0e70ce9d87a4 100644 --- a/tools/perf/util/amd-sample-raw.c +++ b/tools/perf/util/amd-sample-raw.c @@ -16,6 +16,7 @@ #include "evlist.h" #include "sample-raw.h" #include "pmu-events/pmu-events.h" +#include "util/sample.h" static u32 cpu_family, cpu_model, ibs_fetch_type, ibs_op_type; static bool zen4_ibs_extensions; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 46ada5ec3f9a2..265d20cc126b1 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -59,6 +59,7 @@ #include #include "symbol/kallsyms.h" #include +#include "util/sample.h" /* * Make a group from 'leader' to 'last', requiring that the events were not diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index 94f36a187fe73..d6017c9b1872d 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -10,7 +10,7 @@ #include #include #include "util/map_symbol.h" -#include "event.h" +#include "util/sample.h" struct branch_flags { union { diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 9e0aee276df8e..c65cdaf6975ed 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -34,6 +34,7 @@ #include #include "util.h" #include "clockid.h" +#include "util/sample.h" #define pr_N(n, fmt, ...) \ eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 65495f6945b4d..8b71ac1af81be 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -15,6 +15,7 @@ struct dso; struct machine; struct perf_event_attr; +struct perf_sample; #ifdef __LP64__ /* @@ -42,61 +43,6 @@ struct perf_event_attr; /* perf sample has 16 bits size limit */ #define PERF_SAMPLE_MAX_SIZE (1 << 16) -/* number of register is bound by the number of bits in regs_dump::mask (64) */ -#define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64)) - -struct regs_dump { - u64 abi; - u64 mask; - u64 *regs; - - /* Cached values/mask filled by first register access. */ - u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE]; - u64 cache_mask; -}; - -struct stack_dump { - u16 offset; - u64 size; - char *data; -}; - -struct sample_read_value { - u64 value; - u64 id; /* only if PERF_FORMAT_ID */ - u64 lost; /* only if PERF_FORMAT_LOST */ -}; - -struct sample_read { - u64 time_enabled; - u64 time_running; - union { - struct { - u64 nr; - struct sample_read_value *values; - } group; - struct sample_read_value one; - }; -}; - -static inline size_t sample_read_value_size(u64 read_format) -{ - /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ - if (read_format & PERF_FORMAT_LOST) - return sizeof(struct sample_read_value); - else - return offsetof(struct sample_read_value, lost); -} - -static inline struct sample_read_value * -next_sample_read_value(struct sample_read_value *v, u64 read_format) -{ - return (void *)v + sample_read_value_size(read_format); -} - -#define sample_read_group__for_each(v, nr, rf) \ - for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++) - struct ip_callchain { u64 nr; u64 ips[]; @@ -138,52 +84,6 @@ enum { PERF_IP_FLAG_VMENTRY |\ PERF_IP_FLAG_VMEXIT) -#define MAX_INSN 16 - -struct aux_sample { - u64 size; - void *data; -}; - -struct perf_sample { - u64 ip; - u32 pid, tid; - u64 time; - u64 addr; - u64 id; - u64 stream_id; - u64 period; - u64 weight; - u64 transaction; - u64 insn_cnt; - u64 cyc_cnt; - u32 cpu; - u32 raw_size; - u64 data_src; - u64 phys_addr; - u64 data_page_size; - u64 code_page_size; - u64 cgroup; - u32 flags; - u32 machine_pid; - u32 vcpu; - u16 insn_len; - u8 cpumode; - u16 misc; - u16 ins_lat; - u16 p_stage_cyc; - bool no_hw_idx; /* No hw_idx collected in branch_stack */ - char insn[MAX_INSN]; - void *raw_data; - struct ip_callchain *callchain; - struct branch_stack *branch_stack; - struct regs_dump user_regs; - struct regs_dump intr_regs; - struct stack_dump user_stack; - struct sample_read read; - struct aux_sample aux_sample; -}; - #define PERF_MEM_DATA_SRC_NONE \ (PERF_MEM_S(OP, NA) |\ PERF_MEM_S(LVL, NA) |\ @@ -342,15 +242,6 @@ struct perf_synth_intel_iflag_chg { u64 branch_ip; /* If via_branch */ }; -/* - * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get - * 8-byte alignment. - */ -static inline void *perf_sample__synth_ptr(struct perf_sample *sample) -{ - return sample->raw_data - 4; -} - static inline void *perf_synth__raw_data(void *p) { return p + 4; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6612b00949e70..112850d629cb8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -29,6 +29,7 @@ #include "util/evsel_fprintf.h" #include "util/evlist-hybrid.h" #include "util/pmu.h" +#include "util/sample.h" #include #include #include diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c index 1376077183f72..22308dd930101 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c @@ -18,6 +18,7 @@ #include "intel-pt-insn-decoder.h" #include "dump-insn.h" +#include "util/sample.h" #if INTEL_PT_INSN_BUF_SZ < MAX_INSN_SIZE || INTEL_PT_INSN_BUF_SZ > MAX_INSN #error Instruction buffer size too small diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 872dd3d387821..57a567ee2ceaa 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -2,7 +2,7 @@ #include #include #include "perf_regs.h" -#include "event.h" +#include "util/sample.h" int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, char **new_op __maybe_unused) diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index f3fdad28a852c..6fe478b0b61b3 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -163,6 +163,7 @@ #include "s390-cpumsf-kernel.h" #include "s390-cpumcf-kernel.h" #include "config.h" +#include "util/sample.h" struct s390_cpumsf { struct auxtrace auxtrace; diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 9a631d97471c3..c10b891dbad6b 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -28,6 +28,7 @@ #include "sample-raw.h" #include "s390-cpumcf-kernel.h" #include "pmu-events/pmu-events.h" +#include "util/sample.h" static size_t ctrset_size(struct cf_ctrset_entry *set) { diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h new file mode 100644 index 0000000000000..60ec79d4eea4f --- /dev/null +++ b/tools/perf/util/sample.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_SAMPLE_H +#define __PERF_SAMPLE_H + +#include +#include + +/* number of register is bound by the number of bits in regs_dump::mask (64) */ +#define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64)) + +struct regs_dump { + u64 abi; + u64 mask; + u64 *regs; + + /* Cached values/mask filled by first register access. */ + u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE]; + u64 cache_mask; +}; + +struct stack_dump { + u16 offset; + u64 size; + char *data; +}; + +struct sample_read_value { + u64 value; + u64 id; /* only if PERF_FORMAT_ID */ + u64 lost; /* only if PERF_FORMAT_LOST */ +}; + +struct sample_read { + u64 time_enabled; + u64 time_running; + union { + struct { + u64 nr; + struct sample_read_value *values; + } group; + struct sample_read_value one; + }; +}; + +static inline size_t sample_read_value_size(u64 read_format) +{ + /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ + if (read_format & PERF_FORMAT_LOST) + return sizeof(struct sample_read_value); + else + return offsetof(struct sample_read_value, lost); +} + +static inline struct sample_read_value *next_sample_read_value(struct sample_read_value *v, u64 read_format) +{ + return (void *)v + sample_read_value_size(read_format); +} + +#define sample_read_group__for_each(v, nr, rf) \ + for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++) + +#define MAX_INSN 16 + +struct aux_sample { + u64 size; + void *data; +}; + +struct perf_sample { + u64 ip; + u32 pid, tid; + u64 time; + u64 addr; + u64 id; + u64 stream_id; + u64 period; + u64 weight; + u64 transaction; + u64 insn_cnt; + u64 cyc_cnt; + u32 cpu; + u32 raw_size; + u64 data_src; + u64 phys_addr; + u64 data_page_size; + u64 code_page_size; + u64 cgroup; + u32 flags; + u32 machine_pid; + u32 vcpu; + u16 insn_len; + u8 cpumode; + u16 misc; + u16 ins_lat; + u16 p_stage_cyc; + bool no_hw_idx; /* No hw_idx collected in branch_stack */ + char insn[MAX_INSN]; + void *raw_data; + struct ip_callchain *callchain; + struct branch_stack *branch_stack; + struct regs_dump user_regs; + struct regs_dump intr_regs; + struct stack_dump user_stack; + struct sample_read read; + struct aux_sample aux_sample; +}; + +/* + * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get + * 8-byte alignment. + */ +static inline void *perf_sample__synth_ptr(struct perf_sample *sample) +{ + return sample->raw_data - 4; +} + +#endif /* __PERF_SAMPLE_H */ diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 7172ca05265f3..636a010d929b9 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -12,9 +12,9 @@ #include "debug.h" #include "trace-event.h" -#include "event.h" #include "evsel.h" #include +#include "util/sample.h" struct scripting_context *scripting_context; -- GitLab From 628d69995e66343266475e6afc76192f5878b605 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 16:49:58 -0300 Subject: [PATCH 0236/1480] perf kwork: Remove includes not needed in kwork.h Leave just some forward declarations for pointers, move the includes to where they are really needed. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kwork.c | 6 ++++++ tools/perf/util/bpf_kwork.c | 3 +++ tools/perf/util/kwork.h | 12 ++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c index fb8c63656ad89..4ffbf5908070d 100644 --- a/tools/perf/builtin-kwork.c +++ b/tools/perf/builtin-kwork.c @@ -6,10 +6,15 @@ */ #include "builtin.h" +#include "perf.h" #include "util/data.h" +#include "util/evlist.h" +#include "util/evsel.h" +#include "util/header.h" #include "util/kwork.h" #include "util/debug.h" +#include "util/session.h" #include "util/symbol.h" #include "util/thread.h" #include "util/string2.h" @@ -21,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/tools/perf/util/bpf_kwork.c b/tools/perf/util/bpf_kwork.c index b629dd679d3fa..6eb2c78fd7f4a 100644 --- a/tools/perf/util/bpf_kwork.c +++ b/tools/perf/util/bpf_kwork.c @@ -7,15 +7,18 @@ #include #include +#include #include #include #include #include "util/debug.h" +#include "util/evsel.h" #include "util/kwork.h" #include +#include #include "util/bpf_skel/kwork_trace.skel.h" diff --git a/tools/perf/util/kwork.h b/tools/perf/util/kwork.h index 320c0a6d2e086..53b7327550b86 100644 --- a/tools/perf/util/kwork.h +++ b/tools/perf/util/kwork.h @@ -1,16 +1,16 @@ #ifndef PERF_UTIL_KWORK_H #define PERF_UTIL_KWORK_H -#include "perf.h" - #include "util/tool.h" -#include "util/event.h" -#include "util/evlist.h" -#include "util/session.h" #include "util/time-utils.h" -#include #include +#include +#include +#include + +struct perf_sample; +struct perf_session; enum kwork_class_type { KWORK_CLASS_IRQ, -- GitLab From 7e5c6f2c1aa2daa0d8aca657377450529f381fe6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 16:54:46 -0300 Subject: [PATCH 0237/1480] perf machine: Move machine__resolve() from event.h Its a machine method, so move it to machine.h, this way some places that were using event.h just to get this prototype may stop doing so and speed up building and disentanble the header dependency graph. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 3 --- tools/perf/util/machine.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 8b71ac1af81be..ea5bd1f62b0fe 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,9 +337,6 @@ int perf_event__process(struct perf_tool *tool, struct addr_location; -int machine__resolve(struct machine *machine, struct addr_location *al, - struct perf_sample *sample); - void addr_location__put(struct addr_location *al); struct thread; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 74935dfaa9375..6267c1d6f2321 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -305,4 +305,7 @@ int machine__create_extra_kernel_map(struct machine *machine, int machine__map_x86_64_entry_trampolines(struct machine *machine, struct dso *kernel); +int machine__resolve(struct machine *machine, struct addr_location *al, + struct perf_sample *sample); + #endif /* __PERF_MACHINE_H */ -- GitLab From d1e633e4cdc0d06cec82d4772c025f13c3b25a6c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 16:54:46 -0300 Subject: [PATCH 0238/1480] perf symbol: Move addr_location__put() from event.h Its a addr_location method, so move it to symbol.h, where 'struct addr_location' is, this way some places that were using event.h just to get this prototype may stop doing so and speed up building and disentanble the header dependency graph. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 3 --- tools/perf/util/symbol.h | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index ea5bd1f62b0fe..bc6c1e2206cf6 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -336,9 +336,6 @@ int perf_event__process(struct perf_tool *tool, struct machine *machine); struct addr_location; - -void addr_location__put(struct addr_location *al); - struct thread; bool is_bts_event(struct perf_event_attr *attr); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 0b893dcc8ea68..e297de14184c5 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -132,6 +132,8 @@ struct addr_location { s32 socket; }; +void addr_location__put(struct addr_location *al); + int dso__load(struct dso *dso, struct map *map); int dso__load_vmlinux(struct dso *dso, struct map *map, const char *vmlinux, bool vmlinux_allocated); -- GitLab From cde5671268faf6419026ebd5e0f1783b3a84cf39 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 16:54:46 -0300 Subject: [PATCH 0239/1480] perf thread: Move thread__resolve() from event.h Its a thread method, so move it to thread.h, this way some places that were using event.h just to get this prototype may stop doing so and speed up building and disentanble the header dependency graph. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 5 ----- tools/perf/util/thread.h | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index bc6c1e2206cf6..6663a676eadcf 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -335,13 +335,8 @@ int perf_event__process(struct perf_tool *tool, struct perf_sample *sample, struct machine *machine); -struct addr_location; -struct thread; - bool is_bts_event(struct perf_event_attr *attr); bool sample_addr_correlates_sym(struct perf_event_attr *attr); -void thread__resolve(struct thread *thread, struct addr_location *al, - struct perf_sample *sample); const char *perf_event__name(unsigned int id); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 241f300d7d6ef..395c626699a9c 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -158,4 +158,7 @@ static inline bool thread__is_filtered(struct thread *thread) void thread__free_stitch_list(struct thread *thread); +void thread__resolve(struct thread *thread, struct addr_location *al, + struct perf_sample *sample); + #endif /* __PERF_THREAD_H */ -- GitLab From fd8d5a3b076c033f5589186ac49d76e74b39f97f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 17:02:57 -0300 Subject: [PATCH 0240/1480] perf tests: Add missing event.h include It uses things like perf_event__name() but were not including event.h, where its prototype lives, fix it. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/perf-record.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 6377906c13183..e68ca62297566 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -5,6 +5,7 @@ #include #include "debug.h" +#include "event.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index d82539e2ae648..1c4feec1adff1 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -5,6 +5,7 @@ #include #include +#include "event.h" #include "evlist.h" #include "evsel.h" #include "debug.h" -- GitLab From 606f70ab7f5ace535514a5fa6f9ad62ae6e515eb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 17:42:52 -0300 Subject: [PATCH 0241/1480] perf mmap: Remove several unneeded includes from util/mmap.h Those headers are not needed in util/mmap.h, remove them. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/mmap.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index cd4ccec7f3617..f944c3cd5efa0 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -2,18 +2,13 @@ #define __PERF_MMAP_H 1 #include -#include -#include #include -#include #include #include -#include #ifdef HAVE_AIO_SUPPORT #include #endif #include "auxtrace.h" -#include "event.h" #include "util/compress.h" struct aiocb; -- GitLab From 2e5a738abc69601a4ea4a3544ec29cab9189eaae Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Oct 2022 17:44:07 -0300 Subject: [PATCH 0242/1480] perf evlist: Add missing util/event.h header Needed to get the event_attr_init() and perf_event_paranoid() prototypes that were being obtained indirectly, by sheer luck. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 112850d629cb8..fbf3192bced97 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -24,6 +24,7 @@ #include "../perf.h" #include "asm/bug.h" #include "bpf-event.h" +#include "util/event.h" #include "util/string2.h" #include "util/perf_api_probe.h" #include "util/evsel_fprintf.h" -- GitLab From 146edff3d7ed135269dae8abef3219083c45b21e Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 12 Oct 2022 18:12:05 -0700 Subject: [PATCH 0243/1480] perf test: Parse events workaround for dash/minus Skip an event configuration for event names with a dash/minus in them. Events with a dash/minus in their name cause parsing issues as legacy encoding of events would use a dash/minus as a separator. The parser separates events with dashes into prefixes and suffixes and then recombines them. Unfortunately if an event has part of its name that matches a legacy token then the recombining fails. This is seen for branch-brs where branch is a legacy token. branch-brs was introduced to sysfs in: https://lore.kernel.org/all/20220322221517.2510440-5-eranian@google.com/ The failure is shown below as well as the workaround to use a config where the dash/minus isn't treated specially: ``` $ perf stat -e branch-brs true event syntax error: 'branch-brs' \___ parser error $ perf stat -e cpu/branch-brs/ true Performance counter stats for 'true': 46,179 cpu/branch-brs/ ``` Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20221013011205.3151391-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/parse-events.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 459afdb256a1c..3440dd2616b06 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2237,6 +2237,19 @@ static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest pr_debug("Test PMU event failed for '%s'", name); ret = combine_test_results(ret, test_ret); } + /* + * Names containing '-' are recognized as prefixes and suffixes + * due to '-' being a legacy PMU separator. This fails when the + * prefix or suffix collides with an existing legacy token. For + * example, branch-brs has a prefix (branch) that collides with + * a PE_NAME_CACHE_TYPE token causing a parse error as a suffix + * isn't expected after this. As event names in the config + * slashes are allowed a '-' in the name we check this works + * above. + */ + if (strchr(ent->d_name, '-')) + continue; + snprintf(name, sizeof(name), "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name); e.name = name; e.check = test__checkevent_pmu_events_mix; -- GitLab From 005ef2b41b119caf65ac611109ce7ae68d857b46 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 28 Oct 2022 11:01:25 -0700 Subject: [PATCH 0244/1480] perf lock contention: Fix memory sanitizer issue The msan reported a use-of-uninitialized-value warning for the struct lock_contention_data in lock_contention_read(). While it'd be filled by bpf_map_lookup_elem(), let's just initialize it to silence the warning. ==12524==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x562b0f16b1cd in lock_contention_read util/bpf_lock_contention.c:139:7 #1 0x562b0ef65ec6 in __cmd_contention builtin-lock.c:1737:3 #2 0x562b0ef65ec6 in cmd_lock builtin-lock.c:1992:8 #3 0x562b0ee7f50b in run_builtin perf.c:322:11 #4 0x562b0ee7efc1 in handle_internal_command perf.c:376:8 #5 0x562b0ee7e1e9 in run_argv perf.c:420:2 #6 0x562b0ee7e1e9 in main perf.c:550:3 #7 0x7f065f10e632 in __libc_start_main (/usr/lib64/libc.so.6+0x61632) #8 0x562b0edf2fa9 in _start (perf+0xfa9) SUMMARY: MemorySanitizer: use-of-uninitialized-value (perf+0xe15160) in lock_contention_read Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221028180128.3311491-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_lock_contention.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index fc4d613cb979a..06466da792e41 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -110,7 +110,7 @@ int lock_contention_read(struct lock_contention *con) { int fd, stack; s32 prev_key, key; - struct lock_contention_data data; + struct lock_contention_data data = {}; struct lock_stat *st; struct machine *machine = con->machine; u64 stack_trace[con->max_stack]; -- GitLab From 0a277b6226703812ba90543d5bb49476e03f816e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 28 Oct 2022 11:01:26 -0700 Subject: [PATCH 0245/1480] perf lock contention: Check --max-stack option The --max-stack option is used to allocate the BPF stack map and stack trace array in the userspace. Check the value properly before using. Practically it cannot be greater than the sysctl_perf_event_max_stack. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221028180128.3311491-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 66520712a1675..6f79175365a80 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -24,6 +24,7 @@ #include "util/data.h" #include "util/string2.h" #include "util/map.h" +#include "util/util.h" #include #include @@ -1858,6 +1859,29 @@ static int parse_map_entry(const struct option *opt, const char *str, return 0; } +static int parse_max_stack(const struct option *opt, const char *str, + int unset __maybe_unused) +{ + unsigned long *len = (unsigned long *)opt->value; + long val; + char *endptr; + + errno = 0; + val = strtol(str, &endptr, 0); + if (*endptr != '\0' || errno != 0) { + pr_err("invalid max stack depth: %s\n", str); + return -1; + } + + if (val < 0 || val > sysctl__max_stack()) { + pr_err("invalid max stack depth: %ld\n", val); + return -1; + } + + *len = val; + return 0; +} + int cmd_lock(int argc, const char **argv) { const struct option lock_options[] = { @@ -1913,9 +1937,9 @@ int cmd_lock(int argc, const char **argv) "Trace on existing thread id (exclusive to --pid)"), OPT_CALLBACK(0, "map-nr-entries", &bpf_map_entries, "num", "Max number of BPF map entries", parse_map_entry), - OPT_INTEGER(0, "max-stack", &max_stack_depth, - "Set the maximum stack depth when collecting lock contention, " - "Default: " __stringify(CONTENTION_STACK_DEPTH)), + OPT_CALLBACK(0, "max-stack", &max_stack_depth, "num", + "Set the maximum stack depth when collecting lopck contention, " + "Default: " __stringify(CONTENTION_STACK_DEPTH), parse_max_stack), OPT_INTEGER(0, "stack-skip", &stack_skip, "Set the number of stack depth to skip when finding a lock caller, " "Default: " __stringify(CONTENTION_STACK_SKIP)), -- GitLab From 9e9c5f3cf912c3e068b6c24d77f6f07ac242395b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 28 Oct 2022 11:01:27 -0700 Subject: [PATCH 0246/1480] perf lock contention: Avoid variable length arrays The msan also warns about the use of VLA for stack_trace variable. We can dynamically allocate instead. While at it, simplify the error handle a bit (and fix bugs). Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221028180128.3311491-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_lock_contention.c | 41 ++++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 06466da792e41..0deec1178778e 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -108,28 +108,36 @@ int lock_contention_stop(void) int lock_contention_read(struct lock_contention *con) { - int fd, stack; + int fd, stack, err = 0; s32 prev_key, key; struct lock_contention_data data = {}; - struct lock_stat *st; + struct lock_stat *st = NULL; struct machine *machine = con->machine; - u64 stack_trace[con->max_stack]; + u64 *stack_trace; + size_t stack_size = con->max_stack * sizeof(*stack_trace); fd = bpf_map__fd(skel->maps.lock_stat); stack = bpf_map__fd(skel->maps.stacks); con->lost = skel->bss->lost; + stack_trace = zalloc(stack_size); + if (stack_trace == NULL) + return -1; + prev_key = 0; while (!bpf_map_get_next_key(fd, &prev_key, &key)) { struct map *kmap; struct symbol *sym; int idx = 0; + /* to handle errors in the loop body */ + err = -1; + bpf_map_lookup_elem(fd, &key, &data); st = zalloc(sizeof(*st)); if (st == NULL) - return -1; + break; st->nr_contended = data.count; st->wait_time_total = data.total_time; @@ -163,25 +171,32 @@ int lock_contention_read(struct lock_contention *con) st->name = strdup(sym->name); if (ret < 0 || st->name == NULL) - return -1; + break; } else if (asprintf(&st->name, "%#lx", (unsigned long)st->addr) < 0) { - free(st); - return -1; + break; } if (verbose) { - st->callstack = memdup(stack_trace, sizeof(stack_trace)); - if (st->callstack == NULL) { - free(st); - return -1; - } + st->callstack = memdup(stack_trace, stack_size); + if (st->callstack == NULL) + break; } hlist_add_head(&st->hash_entry, con->result); prev_key = key; + + /* we're fine now, reset the values */ + st = NULL; + err = 0; } - return 0; + free(stack_trace); + if (st) { + free(st->name); + free(st); + } + + return err; } int lock_contention_finish(void) -- GitLab From c940fa276b5a4210255e0cb9766f06e38443303a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 28 Oct 2022 11:01:28 -0700 Subject: [PATCH 0247/1480] perf lock contention: Increase default stack skip to 4 In most configurations, it works well with skipping 4 entries by default. If some systems still have 3 BPF internal stack frames, the next frame should be in a lock function which will be skipped later when it tries to find a caller. So increasing to 4 won't affect such systems too. With --stack-skip=0, I can see something like this: 24 49.84 us 7.41 us 2.08 us mutex bpf_prog_e1b85959d520446c_contention_begin+0x12e 0xffffffffc045040e bpf_prog_e1b85959d520446c_contention_begin+0x12e 0xffffffffc045040e bpf_prog_e1b85959d520446c_contention_begin+0x12e 0xffffffff82ea2071 bpf_trace_run2+0x51 0xffffffff82de775b __bpf_trace_contention_begin+0xb 0xffffffff82c02045 __mutex_lock+0x245 0xffffffff82c019e3 __mutex_lock_slowpath+0x13 0xffffffff82c019c0 mutex_lock+0x20 0xffffffff830a083c kernfs_iop_permission+0x2c Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221028180128.3311491-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/lock-contention.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/lock-contention.h b/tools/perf/util/lock-contention.h index b8cb8830b7bc5..e3c061b1795ba 100644 --- a/tools/perf/util/lock-contention.h +++ b/tools/perf/util/lock-contention.h @@ -91,7 +91,7 @@ struct thread_stat { * Number of stack trace entries to skip when finding callers. * The first few entries belong to the locking implementation itself. */ -#define CONTENTION_STACK_SKIP 3 +#define CONTENTION_STACK_SKIP 4 /* * flags for lock:contention_begin -- GitLab From 969864efae78eb51b0baa1d14b2dfe08151b5874 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Tue, 25 Oct 2022 23:41:24 +0530 Subject: [PATCH 0248/1480] i2c: amd-mp2: use msix/msi if the hardware supports Use msix or msi interrupts if the hardware supports it. Else, fallback to legacy interrupts. Co-developed-by: Basavaraj Natikar Signed-off-by: Basavaraj Natikar Signed-off-by: Raju Rangoju Acked-by: Shyam Sundar S K Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-amd-mp2-pci.c | 30 +++++++++++++++++++--------- drivers/i2c/busses/i2c-amd-mp2.h | 1 + 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index f57077a7448d1..1431653009496 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -288,7 +288,7 @@ static void amd_mp2_clear_reg(struct amd_mp2_dev *privdata) static int amd_mp2_pci_init(struct amd_mp2_dev *privdata, struct pci_dev *pci_dev) { - int rc; + int irq_flag = 0, rc; pci_set_drvdata(pci_dev, privdata); @@ -311,17 +311,29 @@ static int amd_mp2_pci_init(struct amd_mp2_dev *privdata, if (rc) goto err_dma_mask; - /* Set up intx irq */ + /* request and enable interrupt */ writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); - pci_intx(pci_dev, 1); - rc = devm_request_irq(&pci_dev->dev, pci_dev->irq, amd_mp2_irq_isr, - IRQF_SHARED, dev_name(&pci_dev->dev), privdata); - if (rc) - pci_err(pci_dev, "Failure requesting irq %i: %d\n", - pci_dev->irq, rc); + rc = pci_alloc_irq_vectors(pci_dev, 1, 1, PCI_IRQ_ALL_TYPES); + if (rc < 0) { + dev_err(&pci_dev->dev, "Failed to allocate single IRQ err=%d\n", rc); + goto err_dma_mask; + } + + privdata->dev_irq = pci_irq_vector(pci_dev, 0); + if (!pci_dev->msix_enabled && !pci_dev->msi_enabled) + irq_flag = IRQF_SHARED; + + rc = devm_request_irq(&pci_dev->dev, privdata->dev_irq, + amd_mp2_irq_isr, irq_flag, dev_name(&pci_dev->dev), privdata); + if (rc) { + pci_err(pci_dev, "Failure requesting irq %i: %d\n", privdata->dev_irq, rc); + goto free_irq_vectors; + } return rc; +free_irq_vectors: + free_irq(privdata->dev_irq, privdata); err_dma_mask: pci_clear_master(pci_dev); err_pci_enable: @@ -364,7 +376,7 @@ static void amd_mp2_pci_remove(struct pci_dev *pci_dev) pm_runtime_forbid(&pci_dev->dev); pm_runtime_get_noresume(&pci_dev->dev); - pci_intx(pci_dev, 0); + free_irq(privdata->dev_irq, privdata); pci_clear_master(pci_dev); amd_mp2_clear_reg(privdata); diff --git a/drivers/i2c/busses/i2c-amd-mp2.h b/drivers/i2c/busses/i2c-amd-mp2.h index ddecd0c886560..018a42de8b1e3 100644 --- a/drivers/i2c/busses/i2c-amd-mp2.h +++ b/drivers/i2c/busses/i2c-amd-mp2.h @@ -183,6 +183,7 @@ struct amd_mp2_dev { struct mutex c2p_lock; u8 c2p_lock_busid; unsigned int probed; + int dev_irq; }; /* PCIe communication driver */ -- GitLab From bb2617f0f2abbd8c622b2401e5e4984a4eef895b Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Sun, 9 Oct 2022 12:16:30 +0200 Subject: [PATCH 0249/1480] dt-bindings: i2c: update bindings for mt7986 soc Add i2c compatible for MT7986 SOC. Signed-off-by: Frank Wunderlich Reviewed-by: AngeloGioacchino Del Regno Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml index 4e730fb7be567..421563bf576cd 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml @@ -23,6 +23,7 @@ properties: - const: mediatek,mt6577-i2c - const: mediatek,mt6589-i2c - const: mediatek,mt7622-i2c + - const: mediatek,mt7986-i2c - const: mediatek,mt8168-i2c - const: mediatek,mt8173-i2c - const: mediatek,mt8183-i2c -- GitLab From e0b7afc0eba88e8270860a573fe4ea28fe2d467c Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Sun, 9 Oct 2022 12:16:31 +0200 Subject: [PATCH 0250/1480] i2c: mediatek: add mt7986 support Add i2c support for MT7986 SoC. Signed-off-by: Frank Wunderlich Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index fc7bfd98156ba..d80e59340d97a 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -431,6 +431,19 @@ static const struct mtk_i2c_compatible mt8168_compat = { .max_dma_support = 33, }; +static const struct mtk_i2c_compatible mt7986_compat = { + .quirks = &mt7622_i2c_quirks, + .regs = mt_i2c_regs_v1, + .pmic_i2c = 0, + .dcm = 1, + .auto_restart = 1, + .aux_len_reg = 1, + .timing_adjust = 0, + .dma_sync = 1, + .ltiming_adjust = 0, + .max_dma_support = 32, +}; + static const struct mtk_i2c_compatible mt8173_compat = { .regs = mt_i2c_regs_v1, .pmic_i2c = 0, @@ -503,6 +516,7 @@ static const struct of_device_id mtk_i2c_of_match[] = { { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat }, { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat }, { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat }, + { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat }, { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat }, { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat }, -- GitLab From a826b6e9e467ed378a2c50c4a03cb863ab681198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 8 Oct 2022 14:59:23 +0200 Subject: [PATCH 0251/1480] i2c: npcm7xx: Group bank 0/1 registers together for readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unlabelled registers NPCM_I2CCTL4 to NPCM_I2CSCLHT overlap with the bank 1 registers below, and they are accessed after selecting bank 0, so they clearly belong to bank 0. Move them together with the other bank 0 registers, and move the unrelated definition of npcm_i2caddr down to keep the banked registers in one piece. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Tali Perry Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-npcm7xx.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 0c365b57d9572..9a7a2d0bf5765 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -106,7 +106,7 @@ enum i2c_addr { #define NPCM_I2CCST3 0x19 #define I2C_VER 0x1F -/*BANK0 regs*/ +/* BANK 0 regs */ #define NPCM_I2CADDR3 0x10 #define NPCM_I2CADDR7 0x11 #define NPCM_I2CADDR4 0x12 @@ -115,6 +115,20 @@ enum i2c_addr { #define NPCM_I2CADDR9 0x15 #define NPCM_I2CADDR6 0x16 #define NPCM_I2CADDR10 0x17 +#define NPCM_I2CCTL4 0x1A +#define NPCM_I2CCTL5 0x1B +#define NPCM_I2CSCLLT 0x1C /* SCL Low Time */ +#define NPCM_I2CFIF_CTL 0x1D /* FIFO Control */ +#define NPCM_I2CSCLHT 0x1E /* SCL High Time */ + +/* BANK 1 regs */ +#define NPCM_I2CFIF_CTS 0x10 /* Both FIFOs Control and Status */ +#define NPCM_I2CTXF_CTL 0x12 /* Tx-FIFO Control */ +#define NPCM_I2CT_OUT 0x14 /* Bus T.O. */ +#define NPCM_I2CPEC 0x16 /* PEC Data */ +#define NPCM_I2CTXF_STS 0x1A /* Tx-FIFO Status */ +#define NPCM_I2CRXF_STS 0x1C /* Rx-FIFO Status */ +#define NPCM_I2CRXF_CTL 0x1E /* Rx-FIFO Control */ #if IS_ENABLED(CONFIG_I2C_SLAVE) /* @@ -131,21 +145,6 @@ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = { }; #endif -#define NPCM_I2CCTL4 0x1A -#define NPCM_I2CCTL5 0x1B -#define NPCM_I2CSCLLT 0x1C /* SCL Low Time */ -#define NPCM_I2CFIF_CTL 0x1D /* FIFO Control */ -#define NPCM_I2CSCLHT 0x1E /* SCL High Time */ - -/* BANK 1 regs */ -#define NPCM_I2CFIF_CTS 0x10 /* Both FIFOs Control and Status */ -#define NPCM_I2CTXF_CTL 0x12 /* Tx-FIFO Control */ -#define NPCM_I2CT_OUT 0x14 /* Bus T.O. */ -#define NPCM_I2CPEC 0x16 /* PEC Data */ -#define NPCM_I2CTXF_STS 0x1A /* Tx-FIFO Status */ -#define NPCM_I2CRXF_STS 0x1C /* Rx-FIFO Status */ -#define NPCM_I2CRXF_CTL 0x1E /* Rx-FIFO Control */ - /* NPCM_I2CST reg fields */ #define NPCM_I2CST_XMIT BIT(0) #define NPCM_I2CST_MASTER BIT(1) -- GitLab From 3ca8217dc450f7a50f90d2ad97787e38088af8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 8 Oct 2022 14:59:24 +0200 Subject: [PATCH 0252/1480] i2c: npcm7xx: Annotate register field definitions with longer names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make the code easier to understand, add longer names to the definitions of register fields. These longer names are based on source code published by DELL/AESS for WPCM450, but should apply just as well to NPCM7xx and NPCM8xx. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Tali Perry Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-npcm7xx.c | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 9a7a2d0bf5765..bbc7359e67f74 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -146,50 +146,50 @@ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = { #endif /* NPCM_I2CST reg fields */ -#define NPCM_I2CST_XMIT BIT(0) -#define NPCM_I2CST_MASTER BIT(1) -#define NPCM_I2CST_NMATCH BIT(2) -#define NPCM_I2CST_STASTR BIT(3) -#define NPCM_I2CST_NEGACK BIT(4) -#define NPCM_I2CST_BER BIT(5) -#define NPCM_I2CST_SDAST BIT(6) -#define NPCM_I2CST_SLVSTP BIT(7) +#define NPCM_I2CST_XMIT BIT(0) /* Transmit mode */ +#define NPCM_I2CST_MASTER BIT(1) /* Master mode */ +#define NPCM_I2CST_NMATCH BIT(2) /* New match */ +#define NPCM_I2CST_STASTR BIT(3) /* Stall after start */ +#define NPCM_I2CST_NEGACK BIT(4) /* Negative ACK */ +#define NPCM_I2CST_BER BIT(5) /* Bus error */ +#define NPCM_I2CST_SDAST BIT(6) /* SDA status */ +#define NPCM_I2CST_SLVSTP BIT(7) /* Slave stop */ /* NPCM_I2CCST reg fields */ -#define NPCM_I2CCST_BUSY BIT(0) -#define NPCM_I2CCST_BB BIT(1) -#define NPCM_I2CCST_MATCH BIT(2) -#define NPCM_I2CCST_GCMATCH BIT(3) -#define NPCM_I2CCST_TSDA BIT(4) -#define NPCM_I2CCST_TGSCL BIT(5) -#define NPCM_I2CCST_MATCHAF BIT(6) -#define NPCM_I2CCST_ARPMATCH BIT(7) +#define NPCM_I2CCST_BUSY BIT(0) /* Busy */ +#define NPCM_I2CCST_BB BIT(1) /* Bus busy */ +#define NPCM_I2CCST_MATCH BIT(2) /* Address match */ +#define NPCM_I2CCST_GCMATCH BIT(3) /* Global call match */ +#define NPCM_I2CCST_TSDA BIT(4) /* Test SDA line */ +#define NPCM_I2CCST_TGSCL BIT(5) /* Toggle SCL line */ +#define NPCM_I2CCST_MATCHAF BIT(6) /* Match address field */ +#define NPCM_I2CCST_ARPMATCH BIT(7) /* ARP address match */ /* NPCM_I2CCTL1 reg fields */ -#define NPCM_I2CCTL1_START BIT(0) -#define NPCM_I2CCTL1_STOP BIT(1) -#define NPCM_I2CCTL1_INTEN BIT(2) +#define NPCM_I2CCTL1_START BIT(0) /* Generate start condition */ +#define NPCM_I2CCTL1_STOP BIT(1) /* Generate stop condition */ +#define NPCM_I2CCTL1_INTEN BIT(2) /* Interrupt enable */ #define NPCM_I2CCTL1_EOBINTE BIT(3) #define NPCM_I2CCTL1_ACK BIT(4) -#define NPCM_I2CCTL1_GCMEN BIT(5) -#define NPCM_I2CCTL1_NMINTE BIT(6) -#define NPCM_I2CCTL1_STASTRE BIT(7) +#define NPCM_I2CCTL1_GCMEN BIT(5) /* Global call match enable */ +#define NPCM_I2CCTL1_NMINTE BIT(6) /* New match interrupt enable */ +#define NPCM_I2CCTL1_STASTRE BIT(7) /* Stall after start enable */ /* RW1S fields (inside a RW reg): */ #define NPCM_I2CCTL1_RWS \ (NPCM_I2CCTL1_START | NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK) /* npcm_i2caddr reg fields */ -#define NPCM_I2CADDR_A GENMASK(6, 0) -#define NPCM_I2CADDR_SAEN BIT(7) +#define NPCM_I2CADDR_A GENMASK(6, 0) /* Address */ +#define NPCM_I2CADDR_SAEN BIT(7) /* Slave address enable */ /* NPCM_I2CCTL2 reg fields */ -#define I2CCTL2_ENABLE BIT(0) -#define I2CCTL2_SCLFRQ6_0 GENMASK(7, 1) +#define I2CCTL2_ENABLE BIT(0) /* Module enable */ +#define I2CCTL2_SCLFRQ6_0 GENMASK(7, 1) /* Bits 0:6 of frequency divisor */ /* NPCM_I2CCTL3 reg fields */ -#define I2CCTL3_SCLFRQ8_7 GENMASK(1, 0) -#define I2CCTL3_ARPMEN BIT(2) +#define I2CCTL3_SCLFRQ8_7 GENMASK(1, 0) /* Bits 7:8 of frequency divisor */ +#define I2CCTL3_ARPMEN BIT(2) /* ARP match enable */ #define I2CCTL3_IDL_START BIT(3) #define I2CCTL3_400K_MODE BIT(4) #define I2CCTL3_BNK_SEL BIT(5) -- GitLab From d780a47c2de9a761bb3d754a24e76495b3f0d55f Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 5 Oct 2022 18:13:45 +0100 Subject: [PATCH 0253/1480] serial: sifive: select by default if SOC_SIFIVE With the aim of dropping direct selects of drivers from Kconfig.socs, default the SiFive serial drivers to the value of SOC_SIFIVE. Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20221005171348.167476-3-conor@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 434f83168546c..94457b54125b6 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -958,6 +958,7 @@ config SERIAL_OMAP_CONSOLE config SERIAL_SIFIVE tristate "SiFive UART support" depends on OF + default SOC_SIFIVE select SERIAL_CORE help Select this option if you are building a kernel for a device that @@ -967,6 +968,7 @@ config SERIAL_SIFIVE config SERIAL_SIFIVE_CONSOLE bool "Console on SiFive UART" depends on SERIAL_SIFIVE=y + default SOC_SIFIVE select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON help -- GitLab From f58a16043a2154661aafe8287cea24e6ae51a9d9 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 5 Oct 2022 18:13:46 +0100 Subject: [PATCH 0254/1480] serial: sifive: select by default if SOC_CANAAN With the aim of dropping direct selects of drivers from Kconfig.socs, default the SiFive serial drivers to enabled if SOC_CANAAN. Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20221005171348.167476-4-conor@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 94457b54125b6..c55b947f3cdbb 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -958,7 +958,7 @@ config SERIAL_OMAP_CONSOLE config SERIAL_SIFIVE tristate "SiFive UART support" depends on OF - default SOC_SIFIVE + default SOC_SIFIVE || SOC_CANAAN select SERIAL_CORE help Select this option if you are building a kernel for a device that @@ -968,7 +968,7 @@ config SERIAL_SIFIVE config SERIAL_SIFIVE_CONSOLE bool "Console on SiFive UART" depends on SERIAL_SIFIVE=y - default SOC_SIFIVE + default SOC_SIFIVE || SOC_CANAAN select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON help -- GitLab From 72da688b457d738b943016dabc603efb1be5f4e1 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 6 Oct 2022 07:20:52 +0200 Subject: [PATCH 0255/1480] tty: evh_bytechan: Replace NO_IRQ by 0 NO_IRQ is used to check the return of irq_of_parse_and_map(). On some architecture NO_IRQ is 0, on other architectures it is -1. irq_of_parse_and_map() returns 0 on error, independent of NO_IRQ. So use 0 instead of using NO_IRQ. Reviewed-by: Jiri Slaby Acked-by: Laurentiu Tudor Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/23f608ca57e7e19bc7060d3e563de383e0b2b337.1665033575.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ehv_bytechan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 19d32cb6af84e..8595483f46977 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -118,7 +118,7 @@ static int find_console_handle(void) return 0; stdout_irq = irq_of_parse_and_map(np, 0); - if (stdout_irq == NO_IRQ) { + if (!stdout_irq) { pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np); return 0; } @@ -696,7 +696,7 @@ static int ehv_bc_tty_probe(struct platform_device *pdev) bc->rx_irq = irq_of_parse_and_map(np, 0); bc->tx_irq = irq_of_parse_and_map(np, 1); - if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) { + if (!bc->rx_irq || !bc->tx_irq) { dev_err(&pdev->dev, "no 'interrupts' property in %pOFn node\n", np); ret = -ENODEV; -- GitLab From e5c3ddd394a409021377b5454a5bd1efa1ba8447 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 31 Oct 2022 21:54:10 +0100 Subject: [PATCH 0256/1480] staging: r8188eu: use ether_addr_equal for address comparison We can use ether_addr_equal instead of memcmp in update_recvframe_phyinfo_88e for comparing the incoming frame's destination address with our local address. Both struct ieee80211_hdr and struct eeprom_priv's mac_addr component are 2-byte aligned. Suggested-by: Joe Perches Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221031205412.124871-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c index f01ae71bcdb11..10bb2e6029846 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c @@ -126,8 +126,8 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && - (!memcmp(ieee80211_get_DA(hdr), - myid(&padapter->eeprompriv), ETH_ALEN)); + ether_addr_equal(ieee80211_get_DA(hdr), + myid(&padapter->eeprompriv)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ieee80211_is_beacon(fc); if (pkt_info.bPacketBeacon) { -- GitLab From 97cc476fc6fbfabb989d508df09208c4a598e149 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 31 Oct 2022 21:54:11 +0100 Subject: [PATCH 0257/1480] staging: r8188eu: use hdr->frame_control instead of fc We can remove the fc variable in update_recvframe_phyinfo_88e and use hdr->frame_control instead. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221031205412.124871-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c index 10bb2e6029846..4e9d8c8285c4f 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c @@ -114,13 +114,12 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat struct hal_data_8188e *pHalData = &padapter->haldata; struct phy_info *pPHYInfo = &pattrib->phy_info; u8 *wlanhdr = precvframe->rx_data; - __le16 fc = *(__le16 *)wlanhdr; struct odm_per_pkt_info pkt_info; u8 *sa = NULL; struct sta_priv *pstapriv; struct sta_info *psta; - pkt_info.bPacketMatchBSSID = ((!ieee80211_is_ctl(fc)) && + pkt_info.bPacketMatchBSSID = ((!ieee80211_is_ctl(hdr->frame_control)) && !pattrib->icv_err && !pattrib->crc_err && !memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); @@ -129,7 +128,8 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat ether_addr_equal(ieee80211_get_DA(hdr), myid(&padapter->eeprompriv)); - pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ieee80211_is_beacon(fc); + pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && + ieee80211_is_beacon(hdr->frame_control); if (pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) sa = padapter->mlmepriv.cur_network.network.MacAddress; -- GitLab From aa69ca7d6d6cd2ed2209b4b6c102f2fec3e97012 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 31 Oct 2022 21:54:12 +0100 Subject: [PATCH 0258/1480] staging: r8188eu: use ieee80211_get_SA Use ieee80211_get_SA in update_recvframe_phyinfo_88e instead of the driver-specific get_sa function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221031205412.124871-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c index 4e9d8c8285c4f..9a61eef8550bd 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c @@ -135,7 +135,7 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat sa = padapter->mlmepriv.cur_network.network.MacAddress; /* to do Ad-hoc */ } else { - sa = get_sa(wlanhdr); + sa = ieee80211_get_SA(hdr); } pstapriv = &padapter->stapriv; -- GitLab From 3032eb4690d5d5bac28d0e92cc501962a42ca4be Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Mon, 31 Oct 2022 16:37:43 +0100 Subject: [PATCH 0259/1480] staging: r8188eu: replace ternary operator with min, max, abs macros Replace some ternary operators with the min(), max() or abs() macros to improve readability. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221031153743.8801-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_xmit.c | 3 +-- drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 2 +- drivers/staging/r8188eu/hal/odm_RTL8188E.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c index 4f82204283282..bd6c1a401c590 100644 --- a/drivers/staging/r8188eu/core/rtw_xmit.c +++ b/drivers/staging/r8188eu/core/rtw_xmit.c @@ -476,8 +476,7 @@ static uint rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) { uint len; - len = rtw_remainder_len(pfile); - len = (rlen > len) ? len : rlen; + len = min(rtw_remainder_len(pfile), rlen); if (rmem) skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len); diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c index 60cdfcf80daad..622f95d3f2edf 100644 --- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c @@ -583,7 +583,7 @@ static bool phy_SimularityCompare_8188E( tmp2 = resulta[c2][i]; } - diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); + diff = abs(tmp1 - tmp2); if (diff > MAX_TOLERANCE) { if ((i == 2 || i == 6) && !sim_bitmap) { diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c index dd9c8291f025d..f3f4074d43167 100644 --- a/drivers/staging/r8188eu/hal/odm_RTL8188E.c +++ b/drivers/staging/r8188eu/hal/odm_RTL8188E.c @@ -199,7 +199,7 @@ static void odm_HWAntDiv(struct odm_dm_struct *dm_odm) Aux_RSSI = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ? (dm_fat_tbl->AuxAnt_Sum[i] / dm_fat_tbl->AuxAnt_Cnt[i]) : 0; TargetAnt = (Main_RSSI >= Aux_RSSI) ? MAIN_ANT : AUX_ANT; /* 2 Select MaxRSSI for DIG */ - LocalMaxRSSI = (Main_RSSI > Aux_RSSI) ? Main_RSSI : Aux_RSSI; + LocalMaxRSSI = max(Main_RSSI, Aux_RSSI); if ((LocalMaxRSSI > AntDivMaxRSSI) && (LocalMaxRSSI < 40)) AntDivMaxRSSI = LocalMaxRSSI; if (LocalMaxRSSI > MaxRSSI) @@ -211,7 +211,7 @@ static void odm_HWAntDiv(struct odm_dm_struct *dm_odm) else if ((dm_fat_tbl->RxIdleAnt == AUX_ANT) && (Aux_RSSI == 0)) Aux_RSSI = Main_RSSI; - LocalMinRSSI = (Main_RSSI > Aux_RSSI) ? Aux_RSSI : Main_RSSI; + LocalMinRSSI = min(Main_RSSI, Aux_RSSI); if (LocalMinRSSI < MinRSSI) { MinRSSI = LocalMinRSSI; RxIdleAnt = TargetAnt; -- GitLab From a653e32aaddb11cc4f159558c4cf7dfa2c5a0222 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 31 Oct 2022 21:51:41 +0100 Subject: [PATCH 0260/1480] staging: r8188eu: use ether_addr_equal in OnAction Use ether_addr_equal to compare two mac addresses in OnAction. Both struct ieee80211_mgmt and struct eeprom_priv's mac_addr component are 2-byte aligned. Suggested-by: Joe Perches Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221031205140.124682-1-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index e985fc5fc575e..6679d4037d6bd 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3823,7 +3823,7 @@ static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) + if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da)) return; switch (mgmt->u.action.category) { -- GitLab From 3b45e2e139c1e71b17a97ae887ba1caadd8e8ad2 Mon Sep 17 00:00:00 2001 From: Tanjuate Brunostar Date: Tue, 1 Nov 2022 09:55:33 +0000 Subject: [PATCH 0261/1480] staging: vt6655: change variable name wTimeStampOff Remove the use of Hungarian notation, which is not used in the Linux kernel. Signed-off-by: Tanjuate Brunostar Link: https://lore.kernel.org/r/Y2DtFRdhCiyNF2kF@elroy-temp-vm.gaiao0uenmiufjlowqgp5yxwdh.gvxx.internal.cloudapp.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 5bdb5176772c0..baa3f6f1508f7 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -54,7 +54,7 @@ */ #define CRITICAL_PACKET_LEN 256 -static const unsigned short wTimeStampOff[2][MAX_RATE] = { +static const unsigned short time_stamp_off[2][MAX_RATE] = { {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */ {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */ }; @@ -142,7 +142,7 @@ s_uFillDataHead( static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { - return cpu_to_le16(wTimeStampOff[priv->preamble_type % 2] + return cpu_to_le16(time_stamp_off[priv->preamble_type % 2] [rate % MAX_RATE]); } -- GitLab From 3cbb8d0d6d42958c146624a102d1a0e59a820b65 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Nov 2022 09:01:11 +0100 Subject: [PATCH 0262/1480] staging: octeon: cvmx_ptr_to_phys() should return physaddr_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 32-bit without physical address extensions (e.g. sh-allmodconfig): drivers/staging/octeon/ethernet-mem.c: In function ‘cvm_oct_free_hw_memory’: ./arch/sh/include/asm/io.h:239:32: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] 239 | #define phys_to_virt(address) ((void *)(address)) | ^ drivers/staging/octeon/ethernet-mem.c:123:18: note: in expansion of macro ‘phys_to_virt’ 123 | fpa = (char *)phys_to_virt(cvmx_ptr_to_phys(fpa)); | ^~~~~~~~~~~~ Fix this by making cvmx_ptr_to_phys() return physaddr_t instead of uint64_t. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20221101080111.750748-1-geert@linux-m68k.org Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/octeon/cvmx.h | 4 ++-- drivers/staging/octeon/octeon-stubs.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 25854abc95f8a..72e775bf31e60 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -154,13 +154,13 @@ static inline uint64_t cvmx_build_bits(uint64_t high_bit, /** * Convert a memory pointer (void*) into a hardware compatible - * memory address (uint64_t). Octeon hardware widgets don't + * memory address (phys_addr_t). Octeon hardware widgets don't * understand logical addresses. * * @ptr: C style memory pointer * Returns Hardware physical address */ -static inline uint64_t cvmx_ptr_to_phys(void *ptr) +static inline phys_addr_t cvmx_ptr_to_phys(void *ptr) { if (sizeof(void *) == 8) { /* diff --git a/drivers/staging/octeon/octeon-stubs.h b/drivers/staging/octeon/octeon-stubs.h index 3f8e5713b8a85..7a02e59e283fb 100644 --- a/drivers/staging/octeon/octeon-stubs.h +++ b/drivers/staging/octeon/octeon-stubs.h @@ -1212,7 +1212,7 @@ static inline void *cvmx_phys_to_ptr(uint64_t physical_address) return (void *)(uintptr_t)(physical_address); } -static inline uint64_t cvmx_ptr_to_phys(void *ptr) +static inline phys_addr_t cvmx_ptr_to_phys(void *ptr) { return (unsigned long)ptr; } -- GitLab From dba2628c8ec5c2821103090a6ba946eab9da0c1f Mon Sep 17 00:00:00 2001 From: Gabhyun Kim Date: Tue, 1 Nov 2022 15:26:36 +0900 Subject: [PATCH 0263/1480] staging: rtl8192e: Remove line breaks to match coding style Remove redundant line break in function definition to correct coding style. Signed-off-by: Gabhyun Kim Link: https://lore.kernel.org/r/20221101062636.GA3257@ubuntu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_softmac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 1a3ca3e57623a..1253de4818053 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -148,8 +148,7 @@ static void init_mgmt_queue(struct rtllib_device *ieee) } -u8 -MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) +u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) { u16 i; u8 QueryRate = 0; -- GitLab From 8b550eb637b483866f8d4662fffc9518ad9e7eca Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Mon, 31 Oct 2022 23:25:39 +0530 Subject: [PATCH 0264/1480] staging: rtl8192u: remove unnecessary function implementation This driver is a single standalone driver and does not have any loading dependencies on another associated drivers. The build results in one single .ko object. The current implementation of the function ieee80211_tkip_null simply returns back to the caller without any useful instruction executions. It does not lead to auto-loading of any other associated modules as the initial design implementation appears to be. Hence the call to ieee80211_tkip_null() and its implementation is unnecessary and should be removed. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/6f5a4313fc21365bf733c25385aef79554ffb253.1667237959.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 3 --- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c | 6 ------ drivers/staging/rtl8192u/ieee80211/ieee80211_module.c | 3 --- 3 files changed, 12 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 9cd4b18967459..00c07455cbb3b 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -232,8 +232,6 @@ struct cb_desc { #define ieee80211_ccmp_null ieee80211_ccmp_null_rsl -#define ieee80211_tkip_null ieee80211_tkip_null_rsl - #define free_ieee80211 free_ieee80211_rsl #define alloc_ieee80211 alloc_ieee80211_rsl @@ -2256,7 +2254,6 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); /* ieee80211_crypt_ccmp&tkip&wep.c */ -void ieee80211_tkip_null(void); int ieee80211_crypto_init(void); void ieee80211_crypto_deinit(void); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index 7b120b8cb9824..9bfd24ad46b69 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -716,9 +716,3 @@ void ieee80211_crypto_tkip_exit(void) { ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); } - -void ieee80211_tkip_null(void) -{ -// printk("============>%s()\n", __func__); - return; -} diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index b94fe9b449b6c..3f93939bc4ee0 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -159,9 +159,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv) ieee->last_packet_time[i] = 0; } -/* These function were added to load crypte module autoly */ - ieee80211_tkip_null(); - return dev; failed: -- GitLab From 1a6d64701922b2ff05b240dc0d69f3feda5e2690 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Tue, 1 Nov 2022 20:14:57 +0100 Subject: [PATCH 0265/1480] staging: r8188eu: remove extern from function prototypes Declaring function prototypes extern is redundant and triggers checkpatch warnings. Remove all extern from function prototypes. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221101191458.8619-2-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/r8188eu/include/osdep_service.h | 2 +- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 4 ++-- drivers/staging/r8188eu/include/sta_info.h | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h index ec2631455f08c..f8ed04f32cae3 100644 --- a/drivers/staging/r8188eu/include/osdep_service.h +++ b/drivers/staging/r8188eu/include/osdep_service.h @@ -66,7 +66,7 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)); } -extern int RTW_STATUS_CODE(int error_code); +int RTW_STATUS_CODE(int error_code); void *rtw_malloc2d(int h, int w, int size); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index ce5b57e23e53b..e234a3b9af6fa 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -388,7 +388,7 @@ struct mlme_ext_priv { void init_mlme_ext_priv(struct adapter *adapter); int init_hw_mlme_ext(struct adapter *padapter); void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); -extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); +struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); unsigned char networktype_to_raid(unsigned char network_type); u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int len); @@ -483,7 +483,7 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *addr, int cam_idx); void beacon_timing_control(struct adapter *padapter); -extern u8 set_tx_beacon_cmd(struct adapter *padapter); +u8 set_tx_beacon_cmd(struct adapter *padapter); unsigned int setup_beacon_frame(struct adapter *padapter, unsigned char *beacon_frame); void update_mgnt_tx_rate(struct adapter *padapter, u8 rate); diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h index f76e086b5701f..55ea5edc29141 100644 --- a/drivers/staging/r8188eu/include/sta_info.h +++ b/drivers/staging/r8188eu/include/sta_info.h @@ -295,19 +295,19 @@ static inline u32 wifi_mac_hash(u8 *mac) return x; } -extern int _rtw_init_sta_priv(struct sta_priv *pstapriv); -extern void _rtw_free_sta_priv(struct sta_priv *pstapriv); +int _rtw_init_sta_priv(struct sta_priv *pstapriv); +void _rtw_free_sta_priv(struct sta_priv *pstapriv); #define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int off); -extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr); -extern u32 rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); -extern void rtw_free_all_stainfo(struct adapter *adapt); -extern struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr); -extern u32 rtw_init_bcmc_stainfo(struct adapter *adapt); -extern struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter); -extern u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr); +struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr); +u32 rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); +void rtw_free_all_stainfo(struct adapter *adapt); +struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr); +u32 rtw_init_bcmc_stainfo(struct adapter *adapt); +struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter); +u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr); #endif /* _STA_INFO_H_ */ -- GitLab From 29626f3c07d09b79d6510d1915c106e51ba85022 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Tue, 1 Nov 2022 20:14:58 +0100 Subject: [PATCH 0266/1480] staging: r8188eu: convert rtw_free_stainfo() to void The function rtw_free_stainfo() returns always _SUCCESS and none of its callers uses the return value. We can safely make the function void. Yet another tiny step towards getting rid of _FAIL / _SUCCESS. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221101191458.8619-3-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_sta_mgt.c | 8 ++------ drivers/staging/r8188eu/include/sta_info.h | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c index 51324e708697f..b4aee86230991 100644 --- a/drivers/staging/r8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/r8188eu/core/rtw_sta_mgt.c @@ -242,7 +242,7 @@ exit: } /* using pstapriv->sta_hash_lock to protect */ -u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) +void rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) { int i; struct __queue *pfree_sta_queue; @@ -252,7 +252,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) struct sta_priv *pstapriv = &padapter->stapriv; if (!psta) - goto exit; + return; pfree_sta_queue = &pstapriv->free_sta_queue; @@ -356,10 +356,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) spin_lock_bh(&pfree_sta_queue->lock); list_add_tail(&psta->list, get_list_head(pfree_sta_queue)); spin_unlock_bh(&pfree_sta_queue->lock); - -exit: - - return _SUCCESS; } /* free all stainfo which in sta_hash[all] */ diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h index 55ea5edc29141..e42f4b4c6e247 100644 --- a/drivers/staging/r8188eu/include/sta_info.h +++ b/drivers/staging/r8188eu/include/sta_info.h @@ -303,7 +303,7 @@ int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int off); struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr); -u32 rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); +void rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); void rtw_free_all_stainfo(struct adapter *adapt); struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr); u32 rtw_init_bcmc_stainfo(struct adapter *adapt); -- GitLab From 72cdc5aec2913bef5dd62eb75cadad8bff27fd8e Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:18:10 +0530 Subject: [PATCH 0267/1480] staging: wlan-ng: Remove unused struct wlan_ie_ssid references Pointer reference to struct wlan_ie_ssid is added as a member variable to 5 different structures. However, these references are never used. Remove such unused struct references. The cleanup also renders the struct useless; so remove it as well. Issue identified as part of coccicheck based code analysis. Suggested-by: Dan Carpenter Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/6e39ef59d01d65a1e179f6aecfbb0d68b81fa257.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 1ef30d3f3159e..dcff56d184985 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -225,13 +225,6 @@ struct wlan_ie { u8 len; } __packed; -/*-- Service Set Identity (SSID) -----------------*/ -struct wlan_ie_ssid { - u8 eid; - u8 len; - u8 ssid[1]; /* may be zero, ptrs may overlap */ -} __packed; - /*-- Supported Rates -----------------------------*/ struct wlan_ie_supp_rates { u8 eid; @@ -319,7 +312,6 @@ struct wlan_fr_beacon { u16 *bcn_int; u16 *cap_info; /*-- info elements ----------*/ - struct wlan_ie_ssid *ssid; struct wlan_ie_supp_rates *supp_rates; struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; @@ -372,7 +364,6 @@ struct wlan_fr_assocreq { u16 *cap_info; u16 *listen_int; /*-- info elements ----------*/ - struct wlan_ie_ssid *ssid; struct wlan_ie_supp_rates *supp_rates; }; @@ -407,7 +398,6 @@ struct wlan_fr_reassocreq { u16 *listen_int; u8 *curr_ap; /*-- info elements ----------*/ - struct wlan_ie_ssid *ssid; struct wlan_ie_supp_rates *supp_rates; }; @@ -439,7 +429,6 @@ struct wlan_fr_probereq { void *priv; /*-- fixed fields -----------*/ /*-- info elements ----------*/ - struct wlan_ie_ssid *ssid; struct wlan_ie_supp_rates *supp_rates; }; @@ -457,7 +446,6 @@ struct wlan_fr_proberesp { u16 *bcn_int; u16 *cap_info; /*-- info elements ----------*/ - struct wlan_ie_ssid *ssid; struct wlan_ie_supp_rates *supp_rates; struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; -- GitLab From 2a899064b60ad1ede8a3990bd512e859b15896d5 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:18:35 +0530 Subject: [PATCH 0268/1480] staging: wlan-ng: Remove unused struct wlan_ie_supp_rates references Pointer reference to struct wlan_ie_supp_rates is added as a member variable to 7 different structures. However, these references are never used. Remove such unused struct references. The cleanup also renders the struct useless; so remove it as well. Issue identified as part of coccicheck based code analysis. Suggested-by: Dan Carpenter Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/370feb1f300896af66fa1c443d3ad19dc8934be3.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index dcff56d184985..536794bdd1f00 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -225,13 +225,6 @@ struct wlan_ie { u8 len; } __packed; -/*-- Supported Rates -----------------------------*/ -struct wlan_ie_supp_rates { - u8 eid; - u8 len; - u8 rates[1]; /* had better be at LEAST one! */ -} __packed; - /*-- FH Parameter Set ----------------------------*/ struct wlan_ie_fh_parms { u8 eid; @@ -312,7 +305,6 @@ struct wlan_fr_beacon { u16 *bcn_int; u16 *cap_info; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; struct wlan_ie_cf_parms *cf_parms; @@ -364,7 +356,6 @@ struct wlan_fr_assocreq { u16 *cap_info; u16 *listen_int; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; }; @@ -381,7 +372,6 @@ struct wlan_fr_assocresp { u16 *status; u16 *aid; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; }; @@ -398,7 +388,6 @@ struct wlan_fr_reassocreq { u16 *listen_int; u8 *curr_ap; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; }; @@ -415,7 +404,6 @@ struct wlan_fr_reassocresp { u16 *status; u16 *aid; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; }; @@ -429,7 +417,6 @@ struct wlan_fr_probereq { void *priv; /*-- fixed fields -----------*/ /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; }; @@ -446,7 +433,6 @@ struct wlan_fr_proberesp { u16 *bcn_int; u16 *cap_info; /*-- info elements ----------*/ - struct wlan_ie_supp_rates *supp_rates; struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; struct wlan_ie_cf_parms *cf_parms; -- GitLab From a5f994fc062971aa801eda9e8af214e785e32aff Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:19:05 +0530 Subject: [PATCH 0269/1480] staging: wlan-ng: Remove unused struct wlan_ie_tim references Pointer reference to struct wlan_ie_tim is added as a member variable of a structure; However, this references is never used. Remove such unused struct reference. The cleanup also renders the struct useless; so remove it as well. Issue identified as part of coccicheck based code analysis. Suggested-by: Dan Carpenter Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/36834007587a2e0ef7a782f5919f3a4c756b7840.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 536794bdd1f00..d95ffe0097e94 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -253,16 +253,6 @@ struct wlan_ie_cf_parms { u16 cfp_durremaining; } __packed; -/*-- TIM ------------------------------------------*/ -struct wlan_ie_tim { - u8 eid; - u8 len; - u8 dtim_cnt; - u8 dtim_period; - u8 bitmap_ctl; - u8 virt_bm[1]; -} __packed; - /*-- IBSS Parameter Set ---------------------------*/ struct wlan_ie_ibss_parms { u8 eid; @@ -309,8 +299,6 @@ struct wlan_fr_beacon { struct wlan_ie_ds_parms *ds_parms; struct wlan_ie_cf_parms *cf_parms; struct wlan_ie_ibss_parms *ibss_parms; - struct wlan_ie_tim *tim; - }; /*-- IBSS ATIM ------------------------------------*/ -- GitLab From a2c896ab66f2c65cf6eeba140b97200a47d0450e Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:19:30 +0530 Subject: [PATCH 0270/1480] staging: wlan-ng: Remove unused struct wlan_ie_ibss_parms references Pointer reference to struct wlan_ie_ibss_parms is added as a member variable to 2 structures; However, these references are never used. Remove such unused struct references. The cleanup also renders the struct useless; so remove it as well. Issue identified as part of coccicheck based code analysis. Suggested-by: Dan Carpenter Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/e53084cdd3ca3ffea6a32393f6f28c7b7650d1a4.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index d95ffe0097e94..816b25641f5a5 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -253,13 +253,6 @@ struct wlan_ie_cf_parms { u16 cfp_durremaining; } __packed; -/*-- IBSS Parameter Set ---------------------------*/ -struct wlan_ie_ibss_parms { - u8 eid; - u8 len; - u16 atim_win; -} __packed; - /*-- Challenge Text ------------------------------*/ struct wlan_ie_challenge { u8 eid; @@ -298,7 +291,6 @@ struct wlan_fr_beacon { struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; struct wlan_ie_cf_parms *cf_parms; - struct wlan_ie_ibss_parms *ibss_parms; }; /*-- IBSS ATIM ------------------------------------*/ @@ -424,7 +416,6 @@ struct wlan_fr_proberesp { struct wlan_ie_fh_parms *fh_parms; struct wlan_ie_ds_parms *ds_parms; struct wlan_ie_cf_parms *cf_parms; - struct wlan_ie_ibss_parms *ibss_parms; }; /*-- Authentication -------------------------------*/ -- GitLab From 5d2366684f9331dc91449b7b866f172d7641ecf3 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:19:54 +0530 Subject: [PATCH 0271/1480] staging: wlan-ng: Remove unused struct p80211macarray definition struct p80211macarray is defined but is never used. Remove the unused struct declaration. Issue identified as part of coccicheck based code analysis. Suggested-by: Dan Carpenter Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/b42eff9b8f73542bc9015948e5e4684416982e1b.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211types.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index 6486612a8f31b..b2ed969604133 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -231,12 +231,6 @@ struct p80211pstr32 { u8 data[MAXLEN_PSTR32]; } __packed; -/* MAC address array */ -struct p80211macarray { - u32 cnt; - u8 data[1][MAXLEN_PSTR6]; -} __packed; - /* prototype template */ struct p80211item { u32 did; -- GitLab From 49af5dd7209ea2242a3c55e0b180f7ff7913fa3b Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:20:13 +0530 Subject: [PATCH 0272/1480] staging: wlan-ng: Remove unused function declarations Several functions are declared but are not implemented or used in any part of the code. Remove such unimplemented function declarations. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/09e2af8d702e33c15ed9f655b0a1190b4e8bec86.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 816b25641f5a5..da824bc363655 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -449,26 +449,4 @@ struct wlan_fr_deauthen { /*-- info elements ----------*/ }; - -void wlan_mgmt_encode_beacon(struct wlan_fr_beacon *f); -void wlan_mgmt_decode_beacon(struct wlan_fr_beacon *f); -void wlan_mgmt_encode_disassoc(struct wlan_fr_disassoc *f); -void wlan_mgmt_decode_disassoc(struct wlan_fr_disassoc *f); -void wlan_mgmt_encode_assocreq(struct wlan_fr_assocreq *f); -void wlan_mgmt_decode_assocreq(struct wlan_fr_assocreq *f); -void wlan_mgmt_encode_assocresp(struct wlan_fr_assocresp *f); -void wlan_mgmt_decode_assocresp(struct wlan_fr_assocresp *f); -void wlan_mgmt_encode_reassocreq(struct wlan_fr_reassocreq *f); -void wlan_mgmt_decode_reassocreq(struct wlan_fr_reassocreq *f); -void wlan_mgmt_encode_reassocresp(struct wlan_fr_reassocresp *f); -void wlan_mgmt_decode_reassocresp(struct wlan_fr_reassocresp *f); -void wlan_mgmt_encode_probereq(struct wlan_fr_probereq *f); -void wlan_mgmt_decode_probereq(struct wlan_fr_probereq *f); -void wlan_mgmt_encode_proberesp(struct wlan_fr_proberesp *f); -void wlan_mgmt_decode_proberesp(struct wlan_fr_proberesp *f); -void wlan_mgmt_encode_authen(struct wlan_fr_authen *f); -void wlan_mgmt_decode_authen(struct wlan_fr_authen *f); -void wlan_mgmt_encode_deauthen(struct wlan_fr_deauthen *f); -void wlan_mgmt_decode_deauthen(struct wlan_fr_deauthen *f); - #endif /* _P80211MGMT_H */ -- GitLab From d911a624cfb40e356b98f135d52914b30214fd7f Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 1 Nov 2022 19:20:40 +0530 Subject: [PATCH 0273/1480] staging: wlan-ng: Remove unused structure definitions Remove structure definitions that are never used in the code. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/74a79ea400ec26624e445692f3353424fb6fc29e.1667308828.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211mgmt.h | 232 --------------------------- 1 file changed, 232 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index da824bc363655..fc23fae5651b9 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -217,236 +217,4 @@ #define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6) #define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7) -/*-- Information Element Types --------------------*/ -/* prototype structure, all IEs start with these members */ - -struct wlan_ie { - u8 eid; - u8 len; -} __packed; - -/*-- FH Parameter Set ----------------------------*/ -struct wlan_ie_fh_parms { - u8 eid; - u8 len; - u16 dwell; - u8 hopset; - u8 hoppattern; - u8 hopindex; -} __packed; - -/*-- DS Parameter Set ----------------------------*/ -struct wlan_ie_ds_parms { - u8 eid; - u8 len; - u8 curr_ch; -} __packed; - -/*-- CF Parameter Set ----------------------------*/ - -struct wlan_ie_cf_parms { - u8 eid; - u8 len; - u8 cfp_cnt; - u8 cfp_period; - u16 cfp_maxdur; - u16 cfp_durremaining; -} __packed; - -/*-- Challenge Text ------------------------------*/ -struct wlan_ie_challenge { - u8 eid; - u8 len; - u8 challenge[1]; -} __packed; - -/*-------------------------------------------------*/ -/* Frame Types */ - -/* prototype structure, all mgmt frame types will start with these members */ -struct wlan_fr_mgmt { - u16 type; - u16 len; /* DOES NOT include CRC !!!! */ - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - /*-- info elements ----------*/ -}; - -/*-- Beacon ---------------------------------------*/ -struct wlan_fr_beacon { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u64 *ts; - u16 *bcn_int; - u16 *cap_info; - /*-- info elements ----------*/ - struct wlan_ie_fh_parms *fh_parms; - struct wlan_ie_ds_parms *ds_parms; - struct wlan_ie_cf_parms *cf_parms; -}; - -/*-- IBSS ATIM ------------------------------------*/ -struct wlan_fr_ibssatim { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - - /*-- fixed fields -----------*/ - /*-- info elements ----------*/ - - /* this frame type has a null body */ - -}; - -/*-- Disassociation -------------------------------*/ -struct wlan_fr_disassoc { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *reason; - - /*-- info elements ----------*/ - -}; - -/*-- Association Request --------------------------*/ -struct wlan_fr_assocreq { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *cap_info; - u16 *listen_int; - /*-- info elements ----------*/ - -}; - -/*-- Association Response -------------------------*/ -struct wlan_fr_assocresp { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *cap_info; - u16 *status; - u16 *aid; - /*-- info elements ----------*/ - -}; - -/*-- Reassociation Request ------------------------*/ -struct wlan_fr_reassocreq { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *cap_info; - u16 *listen_int; - u8 *curr_ap; - /*-- info elements ----------*/ - -}; - -/*-- Reassociation Response -----------------------*/ -struct wlan_fr_reassocresp { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *cap_info; - u16 *status; - u16 *aid; - /*-- info elements ----------*/ - -}; - -/*-- Probe Request --------------------------------*/ -struct wlan_fr_probereq { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - /*-- info elements ----------*/ - -}; - -/*-- Probe Response -------------------------------*/ -struct wlan_fr_proberesp { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u64 *ts; - u16 *bcn_int; - u16 *cap_info; - /*-- info elements ----------*/ - struct wlan_ie_fh_parms *fh_parms; - struct wlan_ie_ds_parms *ds_parms; - struct wlan_ie_cf_parms *cf_parms; -}; - -/*-- Authentication -------------------------------*/ -struct wlan_fr_authen { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *auth_alg; - u16 *auth_seq; - u16 *status; - /*-- info elements ----------*/ - struct wlan_ie_challenge *challenge; - -}; - -/*-- Deauthenication -----------------------------*/ -struct wlan_fr_deauthen { - u16 type; - u16 len; - u8 *buf; - struct p80211_hdr *hdr; - /* used for target specific data, skb in Linux */ - void *priv; - /*-- fixed fields -----------*/ - u16 *reason; - - /*-- info elements ----------*/ - -}; #endif /* _P80211MGMT_H */ -- GitLab From a37068715956111af1d49105d9e41b4cc8f69ea0 Mon Sep 17 00:00:00 2001 From: Phillip Potter Date: Wed, 2 Nov 2022 00:36:13 +0000 Subject: [PATCH 0274/1480] staging: r8188eu: convert rtw_setdatarate_cmd to correct error semantics Convert rtw_setdatarate_cmd function to use proper error return codes rather than _SUCCESS and _FAIL, and a simpler 'return 0;' style. For now, wrap rtw_enqueue_cmd call and return -EPERM if it fails, as converting this function makes more sense later on due to its large number of callers. Also change rtw_wx_set_rate function to pass through the proper error code rather than just 0 or -1. Signed-off-by: Phillip Potter Link: https://lore.kernel.org/r/20221102003613.971-1-phil@philpotter.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_cmd.c | 18 +++++++----------- drivers/staging/r8188eu/include/rtw_cmd.h | 2 +- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 7 ++----- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c index fdc0c71e28a45..19b2f73d481db 100644 --- a/drivers/staging/r8188eu/core/rtw_cmd.c +++ b/drivers/staging/r8188eu/core/rtw_cmd.c @@ -340,33 +340,29 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, return res; } -u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) +int rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) { struct cmd_obj *ph2c; struct setdatarate_parm *pbsetdataratepara; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - u8 res = _SUCCESS; ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } + if (!ph2c) + return -ENOMEM; pbsetdataratepara = kzalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); if (!pbsetdataratepara) { kfree(ph2c); - res = _FAIL; - goto exit; + return -ENOMEM; } init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); pbsetdataratepara->mac_id = 5; memcpy(pbsetdataratepara->datarates, rateset, NumRates); - res = rtw_enqueue_cmd(pcmdpriv, ph2c); -exit: + if (rtw_enqueue_cmd(pcmdpriv, ph2c) == _FAIL) + return -EPERM; - return res; + return 0; } void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index a740a9a101d88..c330a4435b31a 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -727,7 +727,7 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork); u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue); u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); -u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); +int rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset, u8 *pval); diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c index f3b3d74685390..dda48a2a6d0c1 100644 --- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -1340,7 +1340,7 @@ static int rtw_wx_set_rate(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - int i, ret = 0; + int i; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); u8 datarates[NumRates]; u32 target_rate = wrqu->bitrate.value; @@ -1408,10 +1408,7 @@ set_rate: } } - if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) - ret = -1; - - return ret; + return rtw_setdatarate_cmd(padapter, datarates); } static int rtw_wx_get_rate(struct net_device *dev, -- GitLab From a072f249b1b3a457196c83df622e3aa376b1f8df Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 1 Nov 2022 14:16:52 +0000 Subject: [PATCH 0275/1480] dt-bindings: i2c: mv64xxx: Add F1C100s compatible string The I2C controller IP used in the Allwinner F1C100s series of SoCs is compatible with the ones used in the other Allwinner SoCs. Add an F1C100s specific compatible string to the list of existing names. Signed-off-by: Andre Przywara Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml index 93c164aa00daf..984fc1ed3ec6a 100644 --- a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml @@ -19,6 +19,7 @@ properties: - const: allwinner,sun6i-a31-i2c - items: - enum: + - allwinner,suniv-f1c100s-i2c - allwinner,sun8i-a23-i2c - allwinner,sun8i-a83t-i2c - allwinner,sun8i-v536-i2c -- GitLab From 52951ea193ad3b77c433497425a1049520fd6f22 Mon Sep 17 00:00:00 2001 From: Weilong Chen Date: Tue, 1 Nov 2022 16:07:27 +0800 Subject: [PATCH 0276/1480] i2c: hisi: Add initial device tree support The HiSilicon I2C controller can be used on embedded platform, which boot from devicetree. Signed-off-by: Weilong Chen Acked-by: Yicong Yang Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-hisi.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index e50f9603d189e..a7bfddf08fa7b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -673,7 +673,7 @@ config I2C_HIGHLANDER config I2C_HISI tristate "HiSilicon I2C controller" - depends on (ARM64 && ACPI) || COMPILE_TEST + depends on ARM64 || COMPILE_TEST help Say Y here if you want to have Hisilicon I2C controller support available on the Kunpeng Server. diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c index 76c3d8f6fc3c6..bcc97e4fcb654 100644 --- a/drivers/i2c/busses/i2c-hisi.c +++ b/drivers/i2c/busses/i2c-hisi.c @@ -489,11 +489,18 @@ static const struct acpi_device_id hisi_i2c_acpi_ids[] = { }; MODULE_DEVICE_TABLE(acpi, hisi_i2c_acpi_ids); +static const struct of_device_id hisi_i2c_dts_ids[] = { + { .compatible = "hisilicon,ascend910-i2c", }, + { } +}; +MODULE_DEVICE_TABLE(of, hisi_i2c_dts_ids); + static struct platform_driver hisi_i2c_driver = { .probe = hisi_i2c_probe, .driver = { .name = "hisi-i2c", .acpi_match_table = hisi_i2c_acpi_ids, + .of_match_table = hisi_i2c_dts_ids, }, }; module_platform_driver(hisi_i2c_driver); -- GitLab From e77f7ba726cc0c9b1c62b295d2aac42c3a18ebd1 Mon Sep 17 00:00:00 2001 From: Weilong Chen Date: Tue, 1 Nov 2022 16:07:28 +0800 Subject: [PATCH 0277/1480] dt-bindings: i2c: add entry for hisilicon,ascend910-i2c Add the new compatible for HiSilicon i2c. Signed-off-by: Weilong Chen Reviewed-by: Rob Herring Reviewed-by: Yicong Yang Signed-off-by: Wolfram Sang --- .../bindings/i2c/hisilicon,ascend910-i2c.yaml | 73 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml diff --git a/Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml b/Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml new file mode 100644 index 0000000000000..7d7a8de7bcd89 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/hisilicon,ascend910-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon common I2C controller + +maintainers: + - Yicong Yang + +description: + The HiSilicon common I2C controller can be used for many different + types of SoC such as Huawei Ascend AI series chips. + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +properties: + compatible: + const: hisilicon,ascend910-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + default: 400000 + + i2c-sda-falling-time-ns: + default: 343 + + i2c-scl-falling-time-ns: + default: 203 + + i2c-sda-hold-time-ns: + default: 830 + + i2c-scl-rising-time-ns: + default: 365 + + i2c-digital-filter-width-ns: + default: 0 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + + i2c@38b0000 { + compatible = "hisilicon,ascend910-i2c"; + reg = <0x38b0000 0x10000>; + interrupts = ; + i2c-sda-falling-time-ns = <56>; + i2c-scl-falling-time-ns = <56>; + i2c-sda-hold-time-ns = <56>; + i2c-scl-rising-time-ns = <56>; + i2c-digital-filter; + i2c-digital-filter-width-ns = <0x0>; + clocks = <&alg_clk>; + clock-frequency = <400000>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 379945f82a643..1d09b36b9b9c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9214,6 +9214,7 @@ M: Yicong Yang L: linux-i2c@vger.kernel.org S: Maintained W: https://www.hisilicon.com +F: Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml F: drivers/i2c/busses/i2c-hisi.c HISILICON LPC BUS DRIVER -- GitLab From 5fd8c2d3de3dd3cc6d36a0c7a08e44cd5bf173e6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 22 Oct 2022 11:29:48 -0700 Subject: [PATCH 0278/1480] tty: Move sysctl setup into "core" tty logic In preparation for adding another sysctl to the tty subsystem, move the tty setup code into the "core" tty code, which contains tty_init() itself. Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221022182949.2684794-1-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty.h | 2 +- drivers/tty/tty_io.c | 34 ++++++++++++++++++++++++++++++++-- drivers/tty/tty_ldisc.c | 38 +------------------------------------- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 1c08c9b67b16c..f45cd683c02ea 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -93,7 +93,7 @@ void tty_ldisc_release(struct tty_struct *tty); int __must_check tty_ldisc_init(struct tty_struct *tty); void tty_ldisc_deinit(struct tty_struct *tty); -void tty_sysctl_init(void); +extern int tty_ldisc_autoload; /* tty_audit.c */ #ifdef CONFIG_AUDIT diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index de06c3c2ff70a..fe77a3d41326d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3572,13 +3572,44 @@ void console_sysfs_notify(void) sysfs_notify(&consdev->kobj, NULL, "active"); } +static struct ctl_table tty_table[] = { + { + .procname = "ldisc_autoload", + .data = &tty_ldisc_autoload, + .maxlen = sizeof(tty_ldisc_autoload), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, + { } +}; + +static struct ctl_table tty_dir_table[] = { + { + .procname = "tty", + .mode = 0555, + .child = tty_table, + }, + { } +}; + +static struct ctl_table tty_root_table[] = { + { + .procname = "dev", + .mode = 0555, + .child = tty_dir_table, + }, + { } +}; + /* * Ok, now we can initialize the rest of the tty devices and can count * on memory allocations, interrupts etc.. */ int __init tty_init(void) { - tty_sysctl_init(); + register_sysctl_table(tty_root_table); cdev_init(&tty_cdev, &tty_fops); if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) @@ -3600,4 +3631,3 @@ int __init tty_init(void) #endif return 0; } - diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 776d8a62f77cc..e758f44729e7e 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -117,7 +117,7 @@ static void put_ldops(struct tty_ldisc_ops *ldops) raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); } -static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD); +int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD); /** * tty_ldisc_get - take a reference to an ldisc @@ -817,39 +817,3 @@ void tty_ldisc_deinit(struct tty_struct *tty) tty_ldisc_put(tty->ldisc); tty->ldisc = NULL; } - -static struct ctl_table tty_table[] = { - { - .procname = "ldisc_autoload", - .data = &tty_ldisc_autoload, - .maxlen = sizeof(tty_ldisc_autoload), - .mode = 0644, - .proc_handler = proc_dointvec, - .extra1 = SYSCTL_ZERO, - .extra2 = SYSCTL_ONE, - }, - { } -}; - -static struct ctl_table tty_dir_table[] = { - { - .procname = "tty", - .mode = 0555, - .child = tty_table, - }, - { } -}; - -static struct ctl_table tty_root_table[] = { - { - .procname = "dev", - .mode = 0555, - .child = tty_dir_table, - }, - { } -}; - -void tty_sysctl_init(void) -{ - register_sysctl_table(tty_root_table); -} -- GitLab From 83efeeeb3d04b22aaed1df99bc70a48fe9d22c4d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 22 Oct 2022 11:29:49 -0700 Subject: [PATCH 0279/1480] tty: Allow TIOCSTI to be disabled TIOCSTI continues its long history of being used in privilege escalation attacks[1]. Prior attempts to provide a mechanism to disable this have devolved into discussions around creating full-blown LSMs to provide arbitrary ioctl filtering, which is hugely over-engineered -- only TIOCSTI is being used this way. 3 years ago OpenBSD entirely removed TIOCSTI[2], Android has had it filtered for longer[3], and the tools that had historically used TIOCSTI either do not need it, are not commonly built with it, or have had its use removed. Provide a simple CONFIG and global sysctl to disable this for the system builders who have wanted this functionality for literally decades now, much like the ldisc_autoload CONFIG and sysctl. [1] https://lore.kernel.org/linux-hardening/Y0m9l52AKmw6Yxi1@hostpad [2] https://undeadly.org/cgi?action=article;sid=20170701132619 [3] https://lore.kernel.org/lkml/CAFJ0LnFGRuEEn1tCLhoki8ZyWrKfktbF+rwwN7WzyC_kBFoQVA@mail.gmail.com/ Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Simon Brand Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221022182949.2684794-2-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/Kconfig | 19 +++++++++++++++++++ drivers/tty/tty_io.c | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index cc30ff93e2e47..d35fc068da74e 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -149,6 +149,25 @@ config LEGACY_PTY_COUNT When not in use, each legacy PTY occupies 12 bytes on 32-bit architectures and 24 bytes on 64-bit architectures. +config LEGACY_TIOCSTI + bool "Allow legacy TIOCSTI usage" + default y + help + Historically the kernel has allowed TIOCSTI, which will push + characters into a controlling TTY. This continues to be used + as a malicious privilege escalation mechanism, and provides no + meaningful real-world utility any more. Its use is considered + a dangerous legacy operation, and can be disabled on most + systems. + + Say 'Y here only if you have confirmed that your system's + userspace depends on this functionality to continue operating + normally. + + This functionality can be changed at runtime with the + dev.tty.legacy_tiocsti sysctl. This configuration option sets + the default value of the sysctl. + config LDISC_AUTOLOAD bool "Automatically load TTY Line Disciplines" default y diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fe77a3d41326d..a6a16cf986b72 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2268,11 +2268,15 @@ static int tty_fasync(int fd, struct file *filp, int on) * * Called functions take tty_ldiscs_lock * * current->signal->tty check is safe without locks */ +static bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); static int tiocsti(struct tty_struct *tty, char __user *p) { char ch, mbz = 0; struct tty_ldisc *ld; + if (!tty_legacy_tiocsti) + return -EIO; + if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ch, p)) @@ -3573,6 +3577,13 @@ void console_sysfs_notify(void) } static struct ctl_table tty_table[] = { + { + .procname = "legacy_tiocsti", + .data = &tty_legacy_tiocsti, + .maxlen = sizeof(tty_legacy_tiocsti), + .mode = 0644, + .proc_handler = proc_dobool, + }, { .procname = "ldisc_autoload", .data = &tty_ldisc_autoload, -- GitLab From 8275b48b278096edc1e3ea5aa9cf946a10022f79 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 4 Oct 2022 12:49:25 +0200 Subject: [PATCH 0280/1480] tty: serial: introduce transmit helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many serial drivers do the same thing: * send x_char if set * keep sending from the xmit circular buffer until either - the loop reaches the end of the xmit buffer - TX is stopped - HW fifo is full * check for pending characters and: - wake up tty writers to fill for more data into xmit buffer - stop TX if there is nothing in the xmit buffer The only differences are: * how to write the character to the HW fifo * the check of the end condition: - is the HW fifo full? - is limit of the written characters reached? So unify the above into two helpers: * uart_port_tx_limited() -- it performs the above taking the written characters limit into account, and * uart_port_tx() -- the same as above, except it only checks the HW readiness, not the characters limit. The HW specific operations (as stated as "differences" above) are passed as arguments to the macros. They are: * tx_ready -- returns true if HW can accept more data. * put_char -- write a character to the device. * tx_done -- when the write loop is done, perform arbitrary action before potential invocation of ops->stop_tx() happens. Note that the above are macros. This means the code is generated in place and the above 3 arguments are "inlined". I.e. no added penalty by generating call instructions for every single character. Nor any indirect calls. (As in some previous versions of this patchset.) Reviewed-by: Ilpo Järvinen Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221004104927.14361-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/serial/driver.rst | 3 + include/linux/serial_core.h | 80 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/Documentation/driver-api/serial/driver.rst b/Documentation/driver-api/serial/driver.rst index 23c6b956cd90d..98d268555dcc9 100644 --- a/Documentation/driver-api/serial/driver.rst +++ b/Documentation/driver-api/serial/driver.rst @@ -78,6 +78,9 @@ Other functions uart_get_lsr_info uart_handle_dcd_change uart_handle_cts_change uart_try_toggle_sysrq uart_get_console +.. kernel-doc:: include/linux/serial_core.h + :identifiers: uart_port_tx_limited uart_port_tx + Other notes ----------- diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index d657f2a42a7b8..dbbc4408bb19a 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -664,6 +664,86 @@ struct uart_driver { void uart_write_wakeup(struct uart_port *port); +#define __uart_port_tx(uport, ch, tx_ready, put_char, tx_done, for_test, \ + for_post) \ +({ \ + struct uart_port *__port = (uport); \ + struct circ_buf *xmit = &__port->state->xmit; \ + unsigned int pending; \ + \ + for (; (for_test) && (tx_ready); (for_post), __port->icount.tx++) { \ + if (__port->x_char) { \ + (ch) = __port->x_char; \ + (put_char); \ + __port->x_char = 0; \ + continue; \ + } \ + \ + if (uart_circ_empty(xmit) || uart_tx_stopped(__port)) \ + break; \ + \ + (ch) = xmit->buf[xmit->tail]; \ + (put_char); \ + xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE; \ + } \ + \ + (tx_done); \ + \ + pending = uart_circ_chars_pending(xmit); \ + if (pending < WAKEUP_CHARS) { \ + uart_write_wakeup(__port); \ + \ + if (pending == 0) \ + __port->ops->stop_tx(__port); \ + } \ + \ + pending; \ +}) + +/** + * uart_port_tx_limited -- transmit helper for uart_port with count limiting + * @port: uart port + * @ch: variable to store a character to be written to the HW + * @count: a limit of characters to send + * @tx_ready: can HW accept more data function + * @put_char: function to write a character + * @tx_done: function to call after the loop is done + * + * This helper transmits characters from the xmit buffer to the hardware using + * @put_char(). It does so until @count characters are sent and while @tx_ready + * evaluates to true. + * + * Returns: the number of characters in the xmit buffer when done. + * + * The expression in macro parameters shall be designed as follows: + * * **tx_ready:** should evaluate to true if the HW can accept more data to + * be sent. This parameter can be %true, which means the HW is always ready. + * * **put_char:** shall write @ch to the device of @port. + * * **tx_done:** when the write loop is done, this can perform arbitrary + * action before potential invocation of ops->stop_tx() happens. If the + * driver does not need to do anything, use e.g. ({}). + * + * For all of them, @port->lock is held, interrupts are locally disabled and + * the expressions must not sleep. + */ +#define uart_port_tx_limited(port, ch, count, tx_ready, put_char, tx_done) ({ \ + unsigned int __count = (count); \ + __uart_port_tx(port, ch, tx_ready, put_char, tx_done, __count, \ + __count--); \ +}) + +/** + * uart_port_tx -- transmit helper for uart_port + * @port: uart port + * @ch: variable to store a character to be written to the HW + * @tx_ready: can HW accept more data function + * @put_char: function to write a character + * + * See uart_port_tx_limited() for more details. + */ +#define uart_port_tx(port, ch, tx_ready, put_char) \ + __uart_port_tx(port, ch, tx_ready, put_char, ({}), true, ({})) + /* * Baud rate helpers. */ -- GitLab From 2d141e683e9ac7041c0350bb7b5e31f5f02ddbe3 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 4 Oct 2022 12:49:26 +0200 Subject: [PATCH 0281/1480] tty: serial: use uart_port_tx() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit uart_port_tx() is a new helper to send characters to the device. Use it in these drivers. Cc: Tobias Klauser Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: Vladimir Zapolskiy Cc: Liviu Dudau Cc: Sudeep Holla Cc: Lorenzo Pieralisi Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: "Andreas Färber" Cc: Manivannan Sadhasivam Reviewed-by: Ilpo Järvinen Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221004104927.14361-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 29 ++++------------------ drivers/tty/serial/atmel_serial.c | 28 +++++---------------- drivers/tty/serial/fsl_lpuart.c | 30 ++++------------------- drivers/tty/serial/lantiq.c | 36 +++------------------------ drivers/tty/serial/lpc32xx_hs.c | 33 +++---------------------- drivers/tty/serial/mcf.c | 34 ++++++-------------------- drivers/tty/serial/mpc52xx_uart.c | 39 +++--------------------------- drivers/tty/serial/mps2-uart.c | 26 +++----------------- drivers/tty/serial/mxs-auart.c | 32 ++++++------------------ drivers/tty/serial/owl-uart.c | 32 +++--------------------- drivers/tty/serial/sa1100.c | 34 +++----------------------- drivers/tty/serial/vt8500_serial.c | 30 +++-------------------- 12 files changed, 60 insertions(+), 323 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 82f2790de28d1..316074bb23e9f 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -247,31 +247,12 @@ static void altera_uart_rx_chars(struct uart_port *port) static void altera_uart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - - if (port->x_char) { - /* Send special char - probably flow control */ - altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG); - port->x_char = 0; - port->icount.tx++; - return; - } - - while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & - ALTERA_UART_STATUS_TRDY_MSK) { - if (xmit->head == xmit->tail) - break; - altera_uart_writel(port, xmit->buf[xmit->tail], - ALTERA_UART_TXDATA_REG); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - altera_uart_stop_tx(port); + uart_port_tx(port, ch, + altera_uart_readl(port, ALTERA_UART_STATUS_REG) & + ALTERA_UART_STATUS_TRDY_MSK, + altera_uart_writel(port, ch, ALTERA_UART_TXDATA_REG)); } static irqreturn_t altera_uart_interrupt(int irq, void *data) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index bd07f79a2df91..a6b4d30c5888d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -824,30 +824,14 @@ static void atmel_rx_chars(struct uart_port *port) */ static void atmel_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + bool pending; + u8 ch; - if (port->x_char && - (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) { - atmel_uart_write_char(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - return; - - while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) { - atmel_uart_write_char(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (!uart_circ_empty(xmit)) { + pending = uart_port_tx(port, ch, + atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY, + atmel_uart_write_char(port, ch)); + if (pending) { /* we still have characters to transmit, so we should continue * transmitting them when TX is ready, regardless of * mode or duplexity diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 67fa113f77d47..d811eda1844e7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -742,32 +742,12 @@ static int lpuart32_poll_get_char(struct uart_port *port) static inline void lpuart_transmit_buffer(struct lpuart_port *sport) { - struct circ_buf *xmit = &sport->port.state->xmit; - - if (sport->port.x_char) { - writeb(sport->port.x_char, sport->port.membase + UARTDR); - sport->port.icount.tx++; - sport->port.x_char = 0; - return; - } - - if (lpuart_stopped_or_empty(&sport->port)) { - lpuart_stop_tx(&sport->port); - return; - } - - while (!uart_circ_empty(xmit) && - (readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) { - writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&sport->port); + struct uart_port *port = &sport->port; + u8 ch; - if (uart_circ_empty(xmit)) - lpuart_stop_tx(&sport->port); + uart_port_tx(port, ch, + readb(port->membase + UARTTCFIFO) < sport->txfifo_size, + writeb(ch, port->membase + UARTDR)); } static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index c892f3c7d1abc..a58e9277dfad8 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -95,7 +95,6 @@ #define ASCFSTAT_TXFFLMASK 0x3F00 #define ASCFSTAT_TXFREEMASK 0x3F000000 -static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; @@ -151,9 +150,12 @@ lqasc_start_tx(struct uart_port *port) { unsigned long flags; struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + u8 ch; spin_lock_irqsave(<q_port->lock, flags); - lqasc_tx_chars(port); + uart_port_tx(port, ch, + lqasc_tx_ready(port), + writeb(ch, port->membase + LTQ_ASC_TBUF)); spin_unlock_irqrestore(<q_port->lock, flags); return; } @@ -226,36 +228,6 @@ lqasc_rx_chars(struct uart_port *port) return 0; } -static void -lqasc_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit = &port->state->xmit; - if (uart_tx_stopped(port)) { - lqasc_stop_tx(port); - return; - } - - while (lqasc_tx_ready(port)) { - if (port->x_char) { - writeb(port->x_char, port->membase + LTQ_ASC_TBUF); - port->icount.tx++; - port->x_char = 0; - continue; - } - - if (uart_circ_empty(xmit)) - break; - - writeb(port->state->xmit.buf[port->state->xmit.tail], - port->membase + LTQ_ASC_TBUF); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); -} - static irqreturn_t lqasc_tx_int(int irq, void *_port) { diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index ed47f47683383..b38fe4728c264 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -276,8 +276,6 @@ static void __serial_lpc32xx_rx(struct uart_port *port) tty_flip_buffer_push(tport); } -static void serial_lpc32xx_stop_tx(struct uart_port *port); - static bool serial_lpc32xx_tx_ready(struct uart_port *port) { u32 level = readl(LPC32XX_HSUART_LEVEL(port->membase)); @@ -287,34 +285,11 @@ static bool serial_lpc32xx_tx_ready(struct uart_port *port) static void __serial_lpc32xx_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - - if (port->x_char) { - writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase)); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto exit_tx; - - /* Transfer data */ - while (serial_lpc32xx_tx_ready(port)) { - writel((u32) xmit->buf[xmit->tail], - LPC32XX_HSUART_FIFO(port->membase)); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; -exit_tx: - if (uart_circ_empty(xmit)) - serial_lpc32xx_stop_tx(port); + uart_port_tx(port, ch, + serial_lpc32xx_tx_ready(port), + writel(ch, LPC32XX_HSUART_FIFO(port->membase))); } static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index b1cd9a76dd93b..3239babe12a4e 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -327,34 +327,16 @@ static void mcf_rx_chars(struct mcf_uart *pp) static void mcf_tx_chars(struct mcf_uart *pp) { struct uart_port *port = &pp->port; - struct circ_buf *xmit = &port->state->xmit; - - if (port->x_char) { - /* Send special char - probably flow control */ - writeb(port->x_char, port->membase + MCFUART_UTB); - port->x_char = 0; - port->icount.tx++; - return; - } - - while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) { - if (uart_circ_empty(xmit)) - break; - writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1); - port->icount.tx++; - } + bool pending; + u8 ch; - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + pending = uart_port_tx(port, ch, + readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY, + writeb(ch, port->membase + MCFUART_UTB)); - if (uart_circ_empty(xmit)) { - mcf_stop_tx(port); - /* Disable TX to negate RTS automatically */ - if (port->rs485.flags & SER_RS485_ENABLED) - writeb(MCFUART_UCR_TXDISABLE, - port->membase + MCFUART_UCR); - } + /* Disable TX to negate RTS automatically */ + if (!pending && (port->rs485.flags & SER_RS485_ENABLED)) + writeb(MCFUART_UCR_TXDISABLE, port->membase + MCFUART_UCR); } /****************************************************************************/ diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 73362d4bc45d3..384ca195e3d5d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1428,42 +1428,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) static inline bool mpc52xx_uart_int_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - - /* Process out of band chars */ - if (port->x_char) { - psc_ops->write_char(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return true; - } - - /* Nothing to do ? */ - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mpc52xx_uart_stop_tx(port); - return false; - } - - /* Send chars */ - while (psc_ops->raw_tx_rdy(port)) { - psc_ops->write_char(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - /* Wake up */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - /* Maybe we're done after all */ - if (uart_circ_empty(xmit)) { - mpc52xx_uart_stop_tx(port); - return false; - } + u8 ch; - return true; + return uart_port_tx(port, ch, + psc_ops->raw_tx_rdy(port), + psc_ops->write_char(port, ch)); } static irqreturn_t diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index 2e3e6cf168178..860d161fa5948 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -129,29 +129,11 @@ static void mps2_uart_stop_tx(struct uart_port *port) static void mps2_uart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - - while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) { - if (port->x_char) { - mps2_uart_write8(port, port->x_char, UARTn_DATA); - port->x_char = 0; - port->icount.tx++; - continue; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - break; - - mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA); - xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE; - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - mps2_uart_stop_tx(port); + uart_port_tx(port, ch, + mps2_uart_tx_empty(port), + mps2_uart_write8(port, ch, UARTn_DATA)); } static void mps2_uart_start_tx(struct uart_port *port) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index d21a4f3ef2fe6..ef6e7bb6105ca 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -569,6 +569,8 @@ static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size) static void mxs_auart_tx_chars(struct mxs_auart_port *s) { struct circ_buf *xmit = &s->port.state->xmit; + bool pending; + u8 ch; if (auart_dma_enabled(s)) { u32 i = 0; @@ -603,31 +605,13 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s) return; } - - while (!(mxs_read(s, REG_STAT) & AUART_STAT_TXFF)) { - if (s->port.x_char) { - s->port.icount.tx++; - mxs_write(s->port.x_char, s, REG_DATA); - s->port.x_char = 0; - continue; - } - if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { - s->port.icount.tx++; - mxs_write(xmit->buf[xmit->tail], s, REG_DATA); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - } else - break; - } - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&s->port); - - if (uart_circ_empty(&(s->port.state->xmit))) - mxs_clr(AUART_INTR_TXIEN, s, REG_INTR); - else + pending = uart_port_tx(&s->port, ch, + !(mxs_read(s, REG_STAT) & AUART_STAT_TXFF), + mxs_write(ch, s, REG_DATA)); + if (pending) mxs_set(AUART_INTR_TXIEN, s, REG_INTR); - - if (uart_tx_stopped(&s->port)) - mxs_auart_stop_tx(&s->port); + else + mxs_clr(AUART_INTR_TXIEN, s, REG_INTR); } static void mxs_auart_rx_char(struct mxs_auart_port *s) diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index fde39cc1145db..e99970a9437ff 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -181,35 +181,11 @@ static void owl_uart_start_tx(struct uart_port *port) static void owl_uart_send_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - unsigned int ch; - - if (port->x_char) { - while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) - cpu_relax(); - owl_uart_write(port, port->x_char, OWL_UART_TXDAT); - port->icount.tx++; - port->x_char = 0; - } - - if (uart_tx_stopped(port)) - return; - - while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) { - if (uart_circ_empty(xmit)) - break; + u8 ch; - ch = xmit->buf[xmit->tail]; - owl_uart_write(port, ch, OWL_UART_TXDAT); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - owl_uart_stop_tx(port); + uart_port_tx(port, ch, + !(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU), + owl_uart_write(port, ch, OWL_UART_TXDAT)); } static void owl_uart_receive_chars(struct uart_port *port) diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index dd9e3253cab44..55107bbc00ceb 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -228,14 +228,7 @@ sa1100_rx_chars(struct sa1100_port *sport) static void sa1100_tx_chars(struct sa1100_port *sport) { - struct circ_buf *xmit = &sport->port.state->xmit; - - if (sport->port.x_char) { - UART_PUT_CHAR(sport, sport->port.x_char); - sport->port.icount.tx++; - sport->port.x_char = 0; - return; - } + u8 ch; /* * Check the modem control lines before @@ -243,28 +236,9 @@ static void sa1100_tx_chars(struct sa1100_port *sport) */ sa1100_mctrl_check(sport); - if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { - sa1100_stop_tx(&sport->port); - return; - } - - /* - * Tried using FIFO (not checking TNF) for fifo fill: - * still had the '4 bytes repeated' problem. - */ - while (UART_GET_UTSR1(sport) & UTSR1_TNF) { - UART_PUT_CHAR(sport, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&sport->port); - - if (uart_circ_empty(xmit)) - sa1100_stop_tx(&sport->port); + uart_port_tx(&sport->port, ch, + UART_GET_UTSR1(sport) & UTSR1_TNF, + UART_PUT_CHAR(sport, ch)); } static irqreturn_t sa1100_int(int irq, void *dev_id) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 10fbdb09965f3..deedb65131606 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -196,33 +196,11 @@ static unsigned int vt8500_tx_empty(struct uart_port *port) static void handle_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; + u8 ch; - if (port->x_char) { - writeb(port->x_char, port->membase + VT8500_TXFIFO); - port->icount.tx++; - port->x_char = 0; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - vt8500_stop_tx(port); - return; - } - - while (vt8500_tx_empty(port)) { - if (uart_circ_empty(xmit)) - break; - - writeb(xmit->buf[xmit->tail], port->membase + VT8500_TXFIFO); - - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - vt8500_stop_tx(port); + uart_port_tx(port, ch, + vt8500_tx_empty(port), + writeb(ch, port->membase + VT8500_TXFIFO)); } static void vt8500_start_tx(struct uart_port *port) -- GitLab From d11cc8c3c4b65e00e01f20a920c5fa412415204a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 4 Oct 2022 12:49:27 +0200 Subject: [PATCH 0282/1480] tty: serial: use uart_port_tx_limited() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit uart_port_tx_limited() is a new helper to send characters to the device. Use it in these drivers. mux.c also needs to define tx_done(). But I'm not sure if the driver really wants to wait for all the characters to dismiss from the HW fifo at this code point. Hence I marked this as FIXME. Cc: Russell King Cc: Florian Fainelli Cc: bcm-kernel-feedback-list@broadcom.com Cc: "Pali Rohár" Cc: Kevin Cernekee Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Orson Zhai Cc: Baolin Wang Cc: Chunyan Zhang Cc: Patrice Chotard Cc: linux-riscv@lists.infradead.org Reviewed-by: Ilpo Järvinen Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221004104927.14361-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/21285.c | 32 +++---------------- drivers/tty/serial/altera_jtaguart.c | 36 ++++----------------- drivers/tty/serial/amba-pl010.c | 32 +++---------------- drivers/tty/serial/apbuart.c | 34 +++----------------- drivers/tty/serial/bcm63xx_uart.c | 47 ++++++--------------------- drivers/tty/serial/mux.c | 45 ++++++++------------------ drivers/tty/serial/mvebu-uart.c | 38 +++------------------- drivers/tty/serial/omap-serial.c | 32 +++---------------- drivers/tty/serial/pxa.c | 33 +++---------------- drivers/tty/serial/rp2.c | 31 ++++-------------- drivers/tty/serial/serial_txx9.c | 32 +++---------------- drivers/tty/serial/sifive.c | 31 +++--------------- drivers/tty/serial/sprd_serial.c | 33 +++---------------- drivers/tty/serial/st-asc.c | 48 +++------------------------- 14 files changed, 85 insertions(+), 419 deletions(-) diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index c7d34823f7155..185462fd959c6 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -154,35 +154,13 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) { struct uart_port *port = dev_id; - struct circ_buf *xmit = &port->state->xmit; - int count = 256; - - if (port->x_char) { - *CSR_UARTDR = port->x_char; - port->icount.tx++; - port->x_char = 0; - goto out; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - serial21285_stop_tx(port); - goto out; - } - - do { - *CSR_UARTDR = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0 && !(*CSR_UARTFLG & 0x20)); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - serial21285_stop_tx(port); + uart_port_tx_limited(port, ch, 256, + !(*CSR_UARTFLG & 0x20), + *CSR_UARTDR = ch, + ({})); - out: return IRQ_HANDLED; } diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index c2d154d78e545..aa49553fac584 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -146,37 +146,15 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) { struct uart_port *port = &pp->port; - struct circ_buf *xmit = &port->state->xmit; - unsigned int pending, count; - - if (port->x_char) { - /* Send special char - probably flow control */ - writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG); - port->x_char = 0; - port->icount.tx++; - return; - } + unsigned int count; + u8 ch; - pending = uart_circ_chars_pending(xmit); - if (pending > 0) { - count = altera_jtaguart_tx_space(port, NULL); - if (count > pending) - count = pending; - if (count > 0) { - pending -= count; - while (count--) { - writel(xmit->buf[xmit->tail], - port->membase + ALTERA_JTAGUART_DATA_REG); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - if (pending < WAKEUP_CHARS) - uart_write_wakeup(port); - } - } + count = altera_jtaguart_tx_space(port, NULL); - if (pending == 0) - altera_jtaguart_stop_tx(port); + uart_port_tx_limited(port, ch, count, + true, + writel(ch, port->membase + ALTERA_JTAGUART_DATA_REG), + ({})); } static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index af27fb8ec1451..a98fae2ca422d 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -164,34 +164,12 @@ static void pl010_rx_chars(struct uart_port *port) static void pl010_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - int count; + u8 ch; - if (port->x_char) { - writel(port->x_char, port->membase + UART01x_DR); - port->icount.tx++; - port->x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - pl010_stop_tx(port); - return; - } - - count = port->fifosize >> 1; - do { - writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - pl010_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize >> 1, + true, + writel(ch, port->membase + UART01x_DR), + ({})); } static void pl010_modem_status(struct uart_amba_port *uap) diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 450f4edfda0f0..915ee4b0d5949 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -122,36 +122,12 @@ static void apbuart_rx_chars(struct uart_port *port) static void apbuart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - int count; - - if (port->x_char) { - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - apbuart_stop_tx(port); - return; - } - - /* amba: fill FIFO */ - count = port->fifosize >> 1; - do { - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - apbuart_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize >> 1, + true, + UART_PUT_CHAR(port, ch), + ({})); } static irqreturn_t apbuart_int(int irq, void *dev_id) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 5d9737c2d1f2c..62bc7244dc67f 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -303,53 +303,24 @@ static void bcm_uart_do_rx(struct uart_port *port) */ static void bcm_uart_do_tx(struct uart_port *port) { - struct circ_buf *xmit; - unsigned int val, max_count; - - if (port->x_char) { - bcm_uart_writel(port, port->x_char, UART_FIFO_REG); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_tx_stopped(port)) { - bcm_uart_stop_tx(port); - return; - } - - xmit = &port->state->xmit; - if (uart_circ_empty(xmit)) - goto txq_empty; + unsigned int val; + bool pending; + u8 ch; val = bcm_uart_readl(port, UART_MCTL_REG); val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; - max_count = port->fifosize - val; - - while (max_count--) { - unsigned int c; - c = xmit->buf[xmit->tail]; - bcm_uart_writel(port, c, UART_FIFO_REG); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - goto txq_empty; - return; + pending = uart_port_tx_limited(port, ch, port->fifosize - val, + true, + bcm_uart_writel(port, ch, UART_FIFO_REG), + ({})); + if (pending) + return; -txq_empty: /* nothing to send, disable transmit interrupt */ val = bcm_uart_readl(port, UART_IR_REG); val &= ~UART_TX_INT_MASK; bcm_uart_writel(port, val, UART_IR_REG); - return; } /* diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index ed0e763f622a8..85ce1e9af44ae 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -171,6 +171,13 @@ static void mux_break_ctl(struct uart_port *port, int break_state) { } +static void mux_tx_done(struct uart_port *port) +{ + /* FIXME js: really needs to wait? */ + while (UART_GET_FIFO_CNT(port)) + udelay(1); +} + /** * mux_write - Write chars to the mux fifo. * @port: Ptr to the uart_port. @@ -180,39 +187,13 @@ static void mux_break_ctl(struct uart_port *port, int break_state) */ static void mux_write(struct uart_port *port) { - int count; - struct circ_buf *xmit = &port->state->xmit; - - if(port->x_char) { - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return; - } - - if(uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mux_stop_tx(port); - return; - } - - count = (port->fifosize) - UART_GET_FIFO_CNT(port); - do { - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if(uart_circ_empty(xmit)) - break; - - } while(--count > 0); - - while(UART_GET_FIFO_CNT(port)) - udelay(1); - - if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - mux_stop_tx(port); + uart_port_tx_limited(port, ch, + port->fifosize - UART_GET_FIFO_CNT(port), + true, + UART_PUT_CHAR(port, ch), + mux_tx_done(port)); } /** diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index ba16e1da6bd3e..7b566404cb331 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -335,40 +335,12 @@ ignore_char: static void mvebu_uart_tx_chars(struct uart_port *port, unsigned int status) { - struct circ_buf *xmit = &port->state->xmit; - unsigned int count; - unsigned int st; - - if (port->x_char) { - writel(port->x_char, port->membase + UART_TSH(port)); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mvebu_uart_stop_tx(port); - return; - } - - for (count = 0; count < port->fifosize; count++) { - writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port)); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - - if (uart_circ_empty(xmit)) - break; - - st = readl(port->membase + UART_STAT); - if (st & STAT_TX_FIFO_FUL) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - mvebu_uart_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize, + !(readl(port->membase + UART_STAT) & STAT_TX_FIFO_FUL), + writel(ch, port->membase + UART_TSH(port)), + ({})); } static irqreturn_t mvebu_uart_isr(int irq, void *dev_id) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 7d0d2718ef595..82d35dbbfa6cb 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -347,34 +347,12 @@ static void serial_omap_put_char(struct uart_omap_port *up, unsigned char ch) static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) { - struct circ_buf *xmit = &up->port.state->xmit; - int count; + u8 ch; - if (up->port.x_char) { - serial_omap_put_char(up, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_omap_stop_tx(&up->port); - return; - } - count = up->port.fifosize / 4; - do { - serial_omap_put_char(up, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - if (uart_circ_empty(xmit)) - serial_omap_stop_tx(&up->port); + uart_port_tx_limited(&up->port, ch, up->port.fifosize / 4, + true, + serial_omap_put_char(up, ch), + ({})); } static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 2d25231fad847..444fa4b654aca 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -174,35 +174,12 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) static void transmit_chars(struct uart_pxa_port *up) { - struct circ_buf *xmit = &up->port.state->xmit; - int count; + u8 ch; - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_pxa_stop_tx(&up->port); - return; - } - - count = up->port.fifosize / 2; - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - - if (uart_circ_empty(xmit)) - serial_pxa_stop_tx(&up->port); + uart_port_tx_limited(&up->port, ch, up->port.fifosize / 2, + true, + serial_out(up, UART_TX, ch), + ({})); } static void serial_pxa_start_tx(struct uart_port *port) diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index b81afb06f1f40..749b873a5d99b 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -427,32 +427,13 @@ static void rp2_rx_chars(struct rp2_uart_port *up) static void rp2_tx_chars(struct rp2_uart_port *up) { - u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); - struct circ_buf *xmit = &up->port.state->xmit; + u8 ch; - if (uart_tx_stopped(&up->port)) { - rp2_uart_stop_tx(&up->port); - return; - } - - for (; max_tx != 0; max_tx--) { - if (up->port.x_char) { - writeb(up->port.x_char, up->base + RP2_DATA_BYTE); - up->port.x_char = 0; - up->port.icount.tx++; - continue; - } - if (uart_circ_empty(xmit)) { - rp2_uart_stop_tx(&up->port); - break; - } - writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); + uart_port_tx_limited(&up->port, ch, + FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT), + true, + writeb(ch, up->base + RP2_DATA_BYTE), + ({})); } static void rp2_ch_interrupt(struct rp2_uart_port *up) diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index e12f1dc18c38b..eab387b01e36f 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -321,34 +321,12 @@ receive_chars(struct uart_port *up, unsigned int *status) static inline void transmit_chars(struct uart_port *up) { - struct circ_buf *xmit = &up->state->xmit; - int count; + u8 ch; - if (up->x_char) { - sio_out(up, TXX9_SITFIFO, up->x_char); - up->icount.tx++; - up->x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(up)) { - serial_txx9_stop_tx(up); - return; - } - - count = TXX9_SIO_TX_FIFO; - do { - sio_out(up, TXX9_SITFIFO, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(up); - - if (uart_circ_empty(xmit)) - serial_txx9_stop_tx(up); + uart_port_tx_limited(up, ch, TXX9_SIO_TX_FIFO, + true, + sio_out(up, TXX9_SITFIFO, ch), + ({})); } static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 7fb6760b5c37a..1f565a216e748 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -288,33 +288,12 @@ static void __ssp_transmit_char(struct sifive_serial_port *ssp, int ch) */ static void __ssp_transmit_chars(struct sifive_serial_port *ssp) { - struct circ_buf *xmit = &ssp->port.state->xmit; - int count; - - if (ssp->port.x_char) { - __ssp_transmit_char(ssp, ssp->port.x_char); - ssp->port.icount.tx++; - ssp->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&ssp->port)) { - sifive_serial_stop_tx(&ssp->port); - return; - } - count = SIFIVE_TX_FIFO_DEPTH; - do { - __ssp_transmit_char(ssp, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - ssp->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&ssp->port); + u8 ch; - if (uart_circ_empty(xmit)) - sifive_serial_stop_tx(&ssp->port); + uart_port_tx_limited(&ssp->port, ch, SIFIVE_TX_FIFO_DEPTH, + true, + __ssp_transmit_char(ssp, ch), + ({})); } /** diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 342a879676315..3f34f7bb77002 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -626,35 +626,12 @@ static inline void sprd_rx(struct uart_port *port) static inline void sprd_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - int count; - - if (port->x_char) { - serial_out(port, SPRD_TXD, port->x_char); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - sprd_stop_tx(port); - return; - } - - count = THLD_TX_EMPTY; - do { - serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - sprd_stop_tx(port); + uart_port_tx_limited(port, ch, THLD_TX_EMPTY, + true, + serial_out(port, SPRD_TXD, ch), + ({})); } /* this handles the interrupt from one port */ diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index fcecea689a0dd..5215e6910f686 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -237,50 +237,12 @@ static inline unsigned asc_hw_txroom(struct uart_port *port) */ static void asc_transmit_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - int txroom; - unsigned char c; - - txroom = asc_hw_txroom(port); - - if ((txroom != 0) && port->x_char) { - c = port->x_char; - port->x_char = 0; - asc_out(port, ASC_TXBUF, c); - port->icount.tx++; - txroom = asc_hw_txroom(port); - } - - if (uart_tx_stopped(port)) { - /* - * We should try and stop the hardware here, but I - * don't think the ASC has any way to do that. - */ - asc_disable_tx_interrupts(port); - return; - } - - if (uart_circ_empty(xmit)) { - asc_disable_tx_interrupts(port); - return; - } - - if (txroom == 0) - return; - - do { - c = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - asc_out(port, ASC_TXBUF, c); - port->icount.tx++; - txroom--; - } while ((txroom > 0) && (!uart_circ_empty(xmit))); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; - if (uart_circ_empty(xmit)) - asc_disable_tx_interrupts(port); + uart_port_tx_limited(port, ch, asc_hw_txroom(port), + true, + asc_out(port, ASC_TXBUF, ch), + ({})); } static void asc_receive_chars(struct uart_port *port) -- GitLab From 35781d8356a2eecaa6074ceeb80ee22e252fcdae Mon Sep 17 00:00:00 2001 From: Aniket Randive Date: Fri, 7 Oct 2022 11:53:00 +0530 Subject: [PATCH 0283/1480] tty: serial: qcom-geni-serial: Add support for Hibernation feature Added changes to support the hibernation feature for serial UART. Added support for freeze, restore and thaw callbacks to put the device into hibernation. Signed-off-by: Aniket Randive Link: https://lore.kernel.org/r/1665123780-20557-1-git-send-email-quic_arandive@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 83b66b73303af..b487823f0e617 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -924,6 +924,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) false, true, true); geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); geni_se_select_mode(&port->se, GENI_SE_FIFO); + qcom_geni_serial_start_rx(uport); port->setup = true; return 0; @@ -1547,9 +1548,43 @@ static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev) return ret; } +static int qcom_geni_serial_sys_hib_resume(struct device *dev) +{ + int ret = 0; + struct uart_port *uport; + struct qcom_geni_private_data *private_data; + struct qcom_geni_serial_port *port = dev_get_drvdata(dev); + + uport = &port->uport; + private_data = uport->private_data; + + if (uart_console(uport)) { + geni_icc_set_tag(&port->se, 0x7); + geni_icc_set_bw(&port->se); + ret = uart_resume_port(private_data->drv, uport); + /* + * For hibernation usecase clients for + * console UART won't call port setup during restore, + * hence call port setup for console uart. + */ + qcom_geni_serial_port_setup(uport); + } else { + /* + * Peripheral register settings are lost during hibernation. + * Update setup flag such that port setup happens again + * during next session. Clients of HS-UART will close and + * open the port during hibernation. + */ + port->setup = false; + } + return ret; +} + static const struct dev_pm_ops qcom_geni_serial_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend, qcom_geni_serial_sys_resume) + .restore = qcom_geni_serial_sys_hib_resume, + .thaw = qcom_geni_serial_sys_hib_resume, }; static const struct of_device_id qcom_geni_serial_match_table[] = { -- GitLab From 801954d1210a89b767176e1e34cf5976f41ca6d3 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 16 Oct 2022 10:02:00 +0200 Subject: [PATCH 0284/1480] serial: 8250: 8250_omap: Support native RS485 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent TI Sitara SoCs such as AM64/AM65 have gained the ability to automatically assert RTS when data is transmitted, obviating the need to emulate this functionality in software. The feature is controlled through new DIR_EN and DIR_POL bits in the Mode Definition Register 3. For details see page 8783 and 8890 of the AM65 TRM: https://www.ti.com/lit/ug/spruid7e/spruid7e.pdf Cc: Ilpo Järvinen Cc: Su Bao Cheng Cc: Vignesh Raghavendra Cc: Jan Kiszka Cc: Bin Liu Tested-by: Zeng Chao Reviewed-by: Ilpo Järvinen Signed-off-by: Lukas Wunner Link: https://lore.kernel.org/r/e9f25f5c9200a35d3162973c2b45d6b892cc9bf2.1665906869.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 85 ++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 41b8c6b27136a..1c8a48fdc8f24 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -44,6 +44,7 @@ #define UART_HAS_EFR2 BIT(4) #define UART_HAS_RHR_IT_DIS BIT(5) #define UART_RX_TIMEOUT_QUIRK BIT(6) +#define UART_HAS_NATIVE_RS485 BIT(7) #define OMAP_UART_FCR_RX_TRIG 6 #define OMAP_UART_FCR_TX_TRIG 4 @@ -101,6 +102,11 @@ #define UART_OMAP_IER2 0x1B #define UART_OMAP_IER2_RHR_IT_DIS BIT(2) +/* Mode Definition Register 3 */ +#define UART_OMAP_MDR3 0x20 +#define UART_OMAP_MDR3_DIR_POL BIT(3) +#define UART_OMAP_MDR3_DIR_EN BIT(4) + /* Enhanced features register 2 */ #define UART_OMAP_EFR2 0x23 #define UART_OMAP_EFR2_TIMEOUT_BEHAVE BIT(6) @@ -112,6 +118,7 @@ struct omap8250_priv { int line; u8 habit; u8 mdr1; + u8 mdr3; u8 efr; u8 scr; u8 wer; @@ -343,7 +350,10 @@ static void omap8250_restore_regs(struct uart_8250_port *up) up->port.ops->set_mctrl(&up->port, up->port.mctrl); - if (up->port.rs485.flags & SER_RS485_ENABLED) + serial_out(up, UART_OMAP_MDR3, priv->mdr3); + + if (up->port.rs485.flags & SER_RS485_ENABLED && + up->port.rs485_config == serial8250_em485_config) serial8250_em485_stop_tx(up); } @@ -792,6 +802,74 @@ static void omap_8250_unthrottle(struct uart_port *port) pm_runtime_put_autosuspend(port->dev); } +static int omap8250_rs485_config(struct uart_port *port, + struct ktermios *termios, + struct serial_rs485 *rs485) +{ + struct omap8250_priv *priv = port->private_data; + struct uart_8250_port *up = up_to_u8250p(port); + u32 fixed_delay_rts_before_send = 0; + u32 fixed_delay_rts_after_send = 0; + unsigned int baud; + + /* + * There is a fixed delay of 3 bit clock cycles after the TX shift + * register is going empty to allow time for the stop bit to transition + * through the transceiver before direction is changed to receive. + * + * Additionally there appears to be a 1 bit clock delay between writing + * to the THR register and transmission of the start bit, per page 8783 + * of the AM65 TRM: https://www.ti.com/lit/ug/spruid7e/spruid7e.pdf + */ + if (priv->quot) { + if (priv->mdr1 & UART_OMAP_MDR1_16X_MODE) + baud = port->uartclk / (16 * priv->quot); + else + baud = port->uartclk / (13 * priv->quot); + + fixed_delay_rts_after_send = 3 * MSEC_PER_SEC / baud; + fixed_delay_rts_before_send = 1 * MSEC_PER_SEC / baud; + } + + /* + * Fall back to RS485 software emulation if the UART is missing + * hardware support, if the device tree specifies an mctrl_gpio + * (indicates that RTS is unavailable due to a pinmux conflict) + * or if the requested delays exceed the fixed hardware delays. + */ + if (!(priv->habit & UART_HAS_NATIVE_RS485) || + mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS) || + rs485->delay_rts_after_send > fixed_delay_rts_after_send || + rs485->delay_rts_before_send > fixed_delay_rts_before_send) { + priv->mdr3 &= ~UART_OMAP_MDR3_DIR_EN; + serial_out(up, UART_OMAP_MDR3, priv->mdr3); + + port->rs485_config = serial8250_em485_config; + return serial8250_em485_config(port, termios, rs485); + } + + rs485->delay_rts_after_send = fixed_delay_rts_after_send; + rs485->delay_rts_before_send = fixed_delay_rts_before_send; + + if (rs485->flags & SER_RS485_ENABLED) + priv->mdr3 |= UART_OMAP_MDR3_DIR_EN; + else + priv->mdr3 &= ~UART_OMAP_MDR3_DIR_EN; + + /* + * Retain same polarity semantics as RS485 software emulation, + * i.e. SER_RS485_RTS_ON_SEND means driving RTS low on send. + */ + if (rs485->flags & SER_RS485_RTS_ON_SEND) + priv->mdr3 &= ~UART_OMAP_MDR3_DIR_POL; + else + priv->mdr3 |= UART_OMAP_MDR3_DIR_POL; + + serial_out(up, UART_OMAP_MDR3, priv->mdr3); + + return 0; +} + #ifdef CONFIG_SERIAL_8250_DMA static int omap_8250_rx_dma(struct uart_8250_port *p); @@ -1241,7 +1319,7 @@ static struct omap8250_dma_params am33xx_dma = { static struct omap8250_platdata am654_platdata = { .dma_params = &am654_dma, .habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS | - UART_RX_TIMEOUT_QUIRK, + UART_RX_TIMEOUT_QUIRK | UART_HAS_NATIVE_RS485, }; static struct omap8250_platdata am33xx_platdata = { @@ -1334,7 +1412,8 @@ static int omap8250_probe(struct platform_device *pdev) up.port.shutdown = omap_8250_shutdown; up.port.throttle = omap_8250_throttle; up.port.unthrottle = omap_8250_unthrottle; - up.port.rs485_config = serial8250_em485_config; + up.port.rs485_config = omap8250_rs485_config; + /* same rs485_supported for software emulation and native RS485 */ up.port.rs485_supported = serial8250_em485_supported; up.rs485_start_tx = serial8250_em485_start_tx; up.rs485_stop_tx = serial8250_em485_stop_tx; -- GitLab From f4000a06f40f6008c9cd8092c30ed3ffb62a1587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:08 +0300 Subject: [PATCH 0285/1480] serial: dz: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-2-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/dz.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 829b452daee9d..6b7ed7f2f3cac 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -279,9 +279,8 @@ static inline void dz_transmit_chars(struct dz_mux *mux) * so we go one char at a time) :-< */ tmp = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1); dz_out(dport, DZ_TDR, tmp); - dport->port.icount.tx++; + uart_xmit_advance(&dport->port, 1); if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS) uart_write_wakeup(&dport->port); -- GitLab From 20b01af85291b8e25133ab22399f2de6bbad861e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:09 +0300 Subject: [PATCH 0286/1480] serial: men_z135_uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-3-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/men_z135_uart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 3690f5cf0f434..d2502aaa3e8c7 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -352,11 +352,8 @@ static void men_z135_handle_tx(struct men_z135_port *uart) n = min(n, s); memcpy_toio(port->membase + MEN_Z135_TX_RAM, &xmit->buf[xmit->tail], n); - xmit->tail = (xmit->tail + n) & (UART_XMIT_SIZE - 1); - iowrite32(n & 0x3ff, port->membase + MEN_Z135_TX_CTRL); - - port->icount.tx += n; + uart_xmit_advance(port, n); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); -- GitLab From 1fcff75f3932bdc5ef923bbe8e973d1f3ed59096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:10 +0300 Subject: [PATCH 0287/1480] serial: msm: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-4-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 7dd19a2815794..2b2e0f74b75a0 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -464,12 +464,9 @@ static void msm_complete_tx_dma(void *args) } count = dma->count - state.residue; - port->icount.tx += count; + uart_xmit_advance(port, count); dma->count = 0; - xmit->tail += count; - xmit->tail &= UART_XMIT_SIZE - 1; - /* Restore "Tx FIFO below watermark" interrupt */ msm_port->imr |= MSM_UART_IMR_TXLEV; msm_write(port, msm_port->imr, MSM_UART_IMR); @@ -866,13 +863,11 @@ static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count) else num_chars = 1; - for (i = 0; i < num_chars; i++) { + for (i = 0; i < num_chars; i++) buf[i] = xmit->buf[xmit->tail + i]; - port->icount.tx++; - } iowrite32_rep(tf, buf, 1); - xmit->tail = (xmit->tail + num_chars) & (UART_XMIT_SIZE - 1); + uart_xmit_advance(port, num_chars); tf_pointer += num_chars; } -- GitLab From a5c9611ddc51b846dd699c3ce2a6bcbfa544ef20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:11 +0300 Subject: [PATCH 0288/1480] serial: pch_uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Andy Shevchenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-5-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index c59ce78865799..c76719c0f453a 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -738,15 +738,12 @@ static void pch_dma_tx_complete(void *arg) { struct eg20t_port *priv = arg; struct uart_port *port = &priv->port; - struct circ_buf *xmit = &port->state->xmit; struct scatterlist *sg = priv->sg_tx_p; int i; - for (i = 0; i < priv->nent; i++, sg++) { - xmit->tail += sg_dma_len(sg); - port->icount.tx += sg_dma_len(sg); - } - xmit->tail &= UART_XMIT_SIZE - 1; + for (i = 0; i < priv->nent; i++, sg++) + uart_xmit_advance(port, sg_dma_len(sg)); + async_tx_ack(priv->desc_tx); dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE); priv->tx_dma_use = 0; @@ -843,8 +840,7 @@ static unsigned int handle_tx(struct eg20t_port *priv) while (!uart_tx_stopped(port) && !uart_circ_empty(xmit) && fifo_size) { iowrite8(xmit->buf[xmit->tail], priv->membase + PCH_UART_THR); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); fifo_size--; tx_empty = 0; } -- GitLab From a2a74303b3085109b27160a49e61d4d067acfae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:12 +0300 Subject: [PATCH 0289/1480] serial: sc16is7xx: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Andy Shevchenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-6-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 524921360ca78..39f92eb1e6989 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -686,13 +686,10 @@ static void sc16is7xx_handle_tx(struct uart_port *port) } to_send = (to_send > txlen) ? txlen : to_send; - /* Add data to send */ - port->icount.tx += to_send; - /* Convert to linear buffer */ for (i = 0; i < to_send; ++i) { s->buf[i] = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart_xmit_advance(port, 1); } sc16is7xx_fifo_write(port, to_send); -- GitLab From fc59f80b087447a198274e8b3adf2b8ddcecb561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:13 +0300 Subject: [PATCH 0290/1480] serial: 8250_bcm7271: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-7-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_bcm7271.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index fa8ccf204d860..062177b64d21f 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -425,9 +425,7 @@ static int brcmuart_tx_dma(struct uart_8250_port *p) priv->dma.tx_err = 0; memcpy(priv->tx_buf, &xmit->buf[xmit->tail], tx_size); - xmit->tail += tx_size; - xmit->tail &= UART_XMIT_SIZE - 1; - p->port.icount.tx += tx_size; + uart_xmit_advance(&p->port, tx_size); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&p->port); -- GitLab From 051ef7c8d81ff25b843afb661776e0a77a4f9374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:14 +0300 Subject: [PATCH 0291/1480] serial: 8250: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Andy Shevchenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-8-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index fe8662cd94024..b94e60e753265 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1842,8 +1842,7 @@ void serial8250_tx_chars(struct uart_8250_port *up) */ serial_in(up, UART_SCR); } - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_empty(xmit)) break; if ((up->capabilities & UART_CAP_HFIFO) && -- GitLab From 71a67573d0ede98f9c5f6466da6f6a7d7663498b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:15 +0300 Subject: [PATCH 0292/1480] serial: pl011: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-9-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 5cdced39eafdb..6d8552506091c 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -677,8 +677,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) * Now we know that DMA will fire, so advance the ring buffer * with the stuff we just dispatched. */ - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); - uap->port.icount.tx += count; + uart_xmit_advance(&uap->port, count); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); -- GitLab From d29d947c14d1704d567db3025a293c4ee54cd90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:16 +0300 Subject: [PATCH 0293/1480] serial: ar933x: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-10-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ar933x_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 925484a42c821..4c3d04c6826a9 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -425,8 +425,7 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) ar933x_uart_putc(up, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); } while (--count > 0); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From 8a8dee2cdbb3d147430684d408127e5c9e910fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:17 +0300 Subject: [PATCH 0294/1480] serial: arc: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-11-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/arc_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 2a65ea2660e10..748e8b1cf4f7f 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -166,8 +166,7 @@ static void arc_serial_tx_chars(struct uart_port *port) sent = 1; } else if (!uart_circ_empty(xmit)) { ch = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); while (!(UART_GET_STATUS(port) & TXEMPTY)) cpu_relax(); UART_SET_DATA(port, ch); -- GitLab From add147a4591e20732c3f51ed63414d9e89757e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:18 +0300 Subject: [PATCH 0295/1480] serial: atmel: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Claudiu Beznea Acked-By: Richard GENOUD Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-12-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a6b4d30c5888d..4ca04676c4066 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -859,10 +859,7 @@ static void atmel_complete_tx_dma(void *arg) if (chan) dmaengine_terminate_all(chan); - xmit->tail += atmel_port->tx_len; - xmit->tail &= UART_XMIT_SIZE - 1; - - port->icount.tx += atmel_port->tx_len; + uart_xmit_advance(port, atmel_port->tx_len); spin_lock_irq(&atmel_port->lock_tx); async_tx_ack(atmel_port->desc_tx); @@ -1455,11 +1452,7 @@ static void atmel_tx_pdc(struct uart_port *port) /* nothing left to transmit? */ if (atmel_uart_readl(port, ATMEL_PDC_TCR)) return; - - xmit->tail += pdc->ofs; - xmit->tail &= UART_XMIT_SIZE - 1; - - port->icount.tx += pdc->ofs; + uart_xmit_advance(port, pdc->ofs); pdc->ofs = 0; /* more to transmit - setup next transfer */ -- GitLab From 4146765cae90bac4643e2225a49670da3749311f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:19 +0300 Subject: [PATCH 0296/1480] serial: clps711x: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-13-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 404b43a5ae33f..e190dce58f462 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -166,8 +166,7 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id) u32 sysflg = 0; writew(xmit->buf[xmit->tail], port->membase + UARTDR_OFFSET); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); if (sysflg & SYSFLG_UTXFF) -- GitLab From f8097f0caaf2188e8e4e552116cbd8d5f7746f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:20 +0300 Subject: [PATCH 0297/1480] serial: cpm_uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-14-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index b4369ed45ae2d..5565f302cb212 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -684,8 +684,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); while (count < pinfo->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); count++; if (xmit->head == xmit->tail) break; -- GitLab From cb867f542e2a895e9f2bdcd846f1241b51e3cc2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:21 +0300 Subject: [PATCH 0298/1480] serial: digicolor: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Acked-by: Baruch Siach Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-15-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/digicolor-usart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index 0c0a62346f231..ed197705f7eea 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -202,8 +202,7 @@ static void digicolor_uart_tx(struct uart_port *port) while (!uart_circ_empty(xmit)) { writeb(xmit->buf[xmit->tail], port->membase + UA_EMI_REC); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (digicolor_uart_tx_full(port)) break; -- GitLab From 7840a92a3e7d7f78bdc16b75c62101bc240bfa93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:22 +0300 Subject: [PATCH 0299/1480] serial: linflexuart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-16-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_linflexuart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index 84e8153e54200..6fc21b6684e6f 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -178,8 +178,7 @@ static inline void linflex_transmit_buffer(struct uart_port *sport) while (!uart_circ_empty(xmit)) { linflex_put_char(sport, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->icount.tx++; + uart_xmit_advance(sport, 1); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From cacf7f689b9b783d1efaf4b545d8038ee6edc73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:23 +0300 Subject: [PATCH 0300/1480] serial: fsl_lpuart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-17-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index d811eda1844e7..849ef313b824e 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -535,9 +535,7 @@ static void lpuart_dma_tx_complete(void *arg) dma_unmap_sg(chan->device->dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); - xmit->tail = (xmit->tail + sport->dma_tx_bytes) & (UART_XMIT_SIZE - 1); - - sport->port.icount.tx += sport->dma_tx_bytes; + uart_xmit_advance(&sport->port, sport->dma_tx_bytes); sport->dma_tx_in_progress = false; spin_unlock_irqrestore(&sport->port.lock, flags); @@ -772,8 +770,7 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) txcnt &= UARTWATER_COUNT_MASK; while (!uart_circ_empty(xmit) && (txcnt < sport->txfifo_size)) { lpuart32_write(&sport->port, xmit->buf[xmit->tail], UARTDATA); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; + uart_xmit_advance(&sport->port, 1); txcnt = lpuart32_read(&sport->port, UARTWATER); txcnt = txcnt >> UARTWATER_TXCNT_OFF; txcnt &= UARTWATER_COUNT_MASK; -- GitLab From 26e8f1d9a88144b35b35ce3b9df2d437d8cb2ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:24 +0300 Subject: [PATCH 0301/1480] serial: imx: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Uwe Kleine-König Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-18-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 05b432dc7a85c..a7548d0a1aeee 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -563,8 +563,7 @@ static inline void imx_uart_transmit_buffer(struct imx_port *sport) /* send xmit->buf[xmit->tail] * out the port here */ imx_uart_writel(sport, xmit->buf[xmit->tail], URTX0); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; + uart_xmit_advance(&sport->port, 1); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -590,9 +589,7 @@ static void imx_uart_dma_tx_callback(void *data) ucr1 &= ~UCR1_TXDMAEN; imx_uart_writel(sport, ucr1, UCR1); - /* update the stat */ - xmit->tail = (xmit->tail + sport->tx_bytes) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx += sport->tx_bytes; + uart_xmit_advance(&sport->port, sport->tx_bytes); dev_dbg(sport->port.dev, "we finish the TX DMA.\n"); -- GitLab From daf63432f4626e4cf97dac0cf12c7969617ff1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:25 +0300 Subject: [PATCH 0302/1480] serial: ip22zilog: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-19-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ip22zilog.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index dd0a8915ce4ff..b1f27e1681358 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -409,8 +409,7 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, ZSDELAY(); ZS_WSYNC(channel); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); @@ -609,8 +608,7 @@ static void ip22zilog_start_tx(struct uart_port *port) ZSDELAY(); ZS_WSYNC(channel); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); -- GitLab From 53c3d62f46872fd7bb177a9181291e58edcc3cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:26 +0300 Subject: [PATCH 0303/1480] serial: liteuart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Acked-by: Gabriel Somlo Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-20-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/liteuart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index 4c0604325ee91..062812fe1b092 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -136,8 +136,7 @@ static void liteuart_start_tx(struct uart_port *port) } else if (!uart_circ_empty(xmit)) { while (xmit->head != xmit->tail) { ch = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); liteuart_putchar(port, ch); } } -- GitLab From 502b13cc5aa2c9b2b2a802a7d473734439dc09b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:27 +0300 Subject: [PATCH 0304/1480] serial: max3100: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-21-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max3100.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index c69602f356fdc..bb74f23251fe4 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -292,9 +292,7 @@ static void max3100_work(struct work_struct *w) } else if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { tx = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & - (UART_XMIT_SIZE - 1); - s->port.icount.tx++; + uart_xmit_advance(&s->port, 1); } if (tx != 0xffff) { max3100_calc_parity(s, &tx); -- GitLab From d41727dbdfcbb25bf6e30ddcbe330bb9e7b9fcbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:28 +0300 Subject: [PATCH 0305/1480] serial: max310x: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Andy Shevchenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-22-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index fbf6e2b3161c5..4eb24e3407f80 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -787,10 +787,7 @@ static void max310x_handle_tx(struct uart_port *port) } else { max310x_batch_write(port, xmit->buf + xmit->tail, to_send); } - - /* Add data to send */ - port->icount.tx += to_send; - xmit->tail = (xmit->tail + to_send) & (UART_XMIT_SIZE - 1); + uart_xmit_advance(port, to_send); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From 681ef4219bee73139c713226d90bd068d0bd9b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:29 +0300 Subject: [PATCH 0306/1480] serial: meson: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Acked-by: Martin Blumenstingl Acked-by: Neil Armstrong Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-23-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 056243c12836c..74110017988a8 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -162,8 +162,7 @@ static void meson_uart_start_tx(struct uart_port *port) ch = xmit->buf[xmit->tail]; writel(ch, port->membase + AML_UART_WFIFO); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } if (!uart_circ_empty(xmit)) { -- GitLab From 5c664457a9373394eab65f1459ad55c36e147c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:30 +0300 Subject: [PATCH 0307/1480] serial: milbeaut_usio: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-24-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/milbeaut_usio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index c15e0d84dc7e3..44988a2941b8d 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -98,8 +98,7 @@ static void mlb_usio_tx_chars(struct uart_port *port) do { writew(xmit->buf[xmit->tail], port->membase + MLB_USIO_REG_DR); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_empty(xmit)) break; -- GitLab From 269599fa886f63dc425857f4672e1d0c8df2a5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:31 +0300 Subject: [PATCH 0308/1480] serial: mvebu-uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Pali Rohár Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-25-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 7b566404cb331..31f739c7a08bf 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -223,8 +223,7 @@ static void mvebu_uart_start_tx(struct uart_port *port) if (IS_EXTENDED(port) && !uart_circ_empty(xmit)) { writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port)); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } ctl = readl(port->membase + UART_INTR(port)); -- GitLab From 98fdebeebbad98393d691aaa092e3c7889e5cbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:32 +0300 Subject: [PATCH 0309/1480] serial: pic32: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-26-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pic32_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 2beada66c8245..52d026865a327 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -376,8 +376,7 @@ static void pic32_uart_do_tx(struct uart_port *port) pic32_uart_writel(sport, PIC32_UART_TX, c); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_empty(xmit)) break; if (--max_count == 0) -- GitLab From b31b07a7d21a10f5068b92563c8037a8c2b15f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:33 +0300 Subject: [PATCH 0310/1480] serial: pmac_zilog: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-27-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pmac_zilog.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index fe2e4ec423f79..13668ffdb1e7d 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -410,8 +410,7 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) write_zsdata(uap, xmit->buf[xmit->tail]); zssync(uap); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uap->port.icount.tx++; + uart_xmit_advance(&uap->port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); @@ -627,8 +626,7 @@ static void pmz_start_tx(struct uart_port *port) return; write_zsdata(uap, xmit->buf[xmit->tail]); zssync(uap); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); -- GitLab From 3d4d838423a56a3c18174d194508e728ce9fe6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:34 +0300 Subject: [PATCH 0311/1480] serial: rda: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-28-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/rda-uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c index 0e387e2144fa2..be5c842b5ba95 100644 --- a/drivers/tty/serial/rda-uart.c +++ b/drivers/tty/serial/rda-uart.c @@ -353,8 +353,7 @@ static void rda_uart_send_chars(struct uart_port *port) ch = xmit->buf[xmit->tail]; rda_uart_write(port, ch, RDA_UART_RXTX_BUFFER); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From ec04d75fe4386c7e5eafb72367e962f56694d490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:35 +0300 Subject: [PATCH 0312/1480] serial: samsung_tty: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Sam Protsenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-29-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 77d1363029f55..7e34361a1085a 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -288,7 +288,6 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_dma *dma = ourport->dma; - struct circ_buf *xmit = &port->state->xmit; struct dma_tx_state state; int count; @@ -316,8 +315,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) DMA_TO_DEVICE); async_tx_ack(dma->tx_desc); count = dma->tx_bytes_requested - state.residue; - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); - port->icount.tx += count; + uart_xmit_advance(port, count); } ourport->tx_enabled = 0; @@ -351,8 +349,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args) spin_lock_irqsave(&port->lock, flags); - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); - port->icount.tx += count; + uart_xmit_advance(port, count); ourport->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -916,8 +913,7 @@ static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport) break; wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); count--; } -- GitLab From 10b459d2c3da954286e1fcc3ce33ec42d0ea5126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:36 +0300 Subject: [PATCH 0313/1480] serial: sb1250-duart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-30-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sb1250-duart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index c5d2b6cdcb4a1..de56f383964e6 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -399,8 +399,7 @@ static void sbd_transmit_chars(struct sbd_port *sport) /* Send char. */ if (!stop_tx) { write_sbdchn(sport, R_DUART_TX_HOLD, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; + uart_xmit_advance(&sport->port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); -- GitLab From 3ea03c021dcceac88bbb38f7b67bc08d23c80c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:37 +0300 Subject: [PATCH 0314/1480] serial: sccnxp: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-31-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sccnxp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index dd98509f52e5a..7df6878226340 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -468,8 +468,7 @@ static void sccnxp_handle_tx(struct uart_port *port) break; sccnxp_port_write(port, SCCNXP_THR_REG, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From b7e2647671a2e7eb8d5dd1cb73464d7d760f6139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:38 +0300 Subject: [PATCH 0315/1480] serial: tegra: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Thierry Reding Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-32-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index b7170cb9a544f..4304e3f9307dd 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -496,8 +496,7 @@ static void tegra_uart_fill_tx_fifo(struct tegra_uart_port *tup, int max_bytes) break; } tegra_uart_write(tup, xmit->buf[xmit->tail], UART_TX); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - tup->uport.icount.tx++; + uart_xmit_advance(&tup->uport, 1); } } -- GitLab From e234ef0ef1dec33384968c695f0c2c751b0621ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:39 +0300 Subject: [PATCH 0316/1480] serial: sh-sci: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-33-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 62f773286d44b..a92a897803570 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1181,10 +1181,7 @@ static void sci_dma_tx_complete(void *arg) spin_lock_irqsave(&port->lock, flags); - xmit->tail += s->tx_dma_len; - xmit->tail &= UART_XMIT_SIZE - 1; - - port->icount.tx += s->tx_dma_len; + uart_xmit_advance(port, s->tx_dma_len); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); -- GitLab From b92df54ccf7355256e4eebe2f36dc2b83808e9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:40 +0300 Subject: [PATCH 0317/1480] serial: sprd: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Reviewed-by: Baolin Wang Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-34-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 3f34f7bb77002..492a3bdab5ba2 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -206,7 +206,6 @@ static void sprd_stop_tx_dma(struct uart_port *port) { struct sprd_uart_port *sp = container_of(port, struct sprd_uart_port, port); - struct circ_buf *xmit = &port->state->xmit; struct dma_tx_state state; u32 trans_len; @@ -215,8 +214,7 @@ static void sprd_stop_tx_dma(struct uart_port *port) dmaengine_tx_status(sp->tx_dma.chn, sp->tx_dma.cookie, &state); if (state.residue) { trans_len = state.residue - sp->tx_dma.phys_addr; - xmit->tail = (xmit->tail + trans_len) & (UART_XMIT_SIZE - 1); - port->icount.tx += trans_len; + uart_xmit_advance(port, trans_len); dma_unmap_single(port->dev, sp->tx_dma.phys_addr, sp->tx_dma.trans_len, DMA_TO_DEVICE); } @@ -253,8 +251,7 @@ static void sprd_complete_tx_dma(void *data) dma_unmap_single(port->dev, sp->tx_dma.phys_addr, sp->tx_dma.trans_len, DMA_TO_DEVICE); - xmit->tail = (xmit->tail + sp->tx_dma.trans_len) & (UART_XMIT_SIZE - 1); - port->icount.tx += sp->tx_dma.trans_len; + uart_xmit_advance(port, sp->tx_dma.trans_len); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); -- GitLab From 29d8c07b49578cc58f48fdea361c1f419515076c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:41 +0300 Subject: [PATCH 0318/1480] serial: stm32: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-35-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index dfdbcf092facc..24def72b25653 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -596,8 +596,7 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port) if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) break; writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } /* rely on TXE irq (mask or unmask) for sending remaining data */ @@ -673,8 +672,8 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT); - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); - port->icount.tx += count; + uart_xmit_advance(port, count); + return; fallback_err: -- GitLab From c5fd4b7d7e58e20b05b5d24eddab70567ec7a724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:42 +0300 Subject: [PATCH 0319/1480] serial: sunhv: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-36-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunhv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 1938ba5e98c0e..16c746a632587 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -47,8 +47,7 @@ static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit if (status != HV_EOK) break; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } } @@ -63,8 +62,7 @@ static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) status = sun4v_con_write(ra, len, &sent); if (status != HV_EOK) break; - xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1); - port->icount.tx += sent; + uart_xmit_advance(port, sent); } } -- GitLab From 54ffabbe2203817d1d70ceb97407a4382633d2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:43 +0300 Subject: [PATCH 0320/1480] serial: sunplus-uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-37-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunplus-uart.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/sunplus-uart.c b/drivers/tty/serial/sunplus-uart.c index 7afe61a0e72e4..727942c43c454 100644 --- a/drivers/tty/serial/sunplus-uart.c +++ b/drivers/tty/serial/sunplus-uart.c @@ -216,9 +216,7 @@ static void transmit_chars(struct uart_port *port) do { sp_uart_put_char(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE; - port->icount.tx++; - + uart_xmit_advance(port, 1); if (uart_circ_empty(xmit)) break; } while (sunplus_tx_buf_not_full(port)); -- GitLab From 5aaae464d6de0913a962d4f9412986a528b0acf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:44 +0300 Subject: [PATCH 0321/1480] serial: sunsab: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-38-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsab.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 99608b2a2b74f..94db67f21abf2 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -266,8 +266,7 @@ static void transmit_chars(struct uart_sunsab_port *up, for (i = 0; i < up->port.fifosize; i++) { writeb(xmit->buf[xmit->tail], &up->regs->w.xfifo[i]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); if (uart_circ_empty(xmit)) break; } @@ -453,8 +452,7 @@ static void sunsab_start_tx(struct uart_port *port) for (i = 0; i < up->port.fifosize; i++) { writeb(xmit->buf[xmit->tail], &up->regs->w.xfifo[i]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); if (uart_circ_empty(xmit)) break; } -- GitLab From 7f20ab70940e121c9af3f4ca013f38c762ef19e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:45 +0300 Subject: [PATCH 0322/1480] serial: sunsu: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-39-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 9ea7e567540d6..fed052a0b9310 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -417,8 +417,7 @@ static void transmit_chars(struct uart_sunsu_port *up) count = up->port.fifosize; do { serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); if (uart_circ_empty(xmit)) break; } while (--count > 0); -- GitLab From 81eb6227afea551fbfcb7958bdfcd70b6e5419f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:46 +0300 Subject: [PATCH 0323/1480] serial: sunzilog: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-40-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunzilog.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 87425290687d5..ccb809216e941 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -508,8 +508,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ZSDELAY(); ZS_WSYNC(channel); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + uart_xmit_advance(&up->port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); @@ -709,8 +708,7 @@ static void sunzilog_start_tx(struct uart_port *port) ZSDELAY(); ZS_WSYNC(channel); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); -- GitLab From b421cbb2f33c7692aa209ce2781647919a1265b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:47 +0300 Subject: [PATCH 0324/1480] serial: timbuart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-41-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/timbuart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index bb19ed012def7..0859394a78cdf 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -101,8 +101,7 @@ static void timbuart_tx_chars(struct uart_port *port) !uart_circ_empty(xmit)) { iowrite8(xmit->buf[xmit->tail], port->membase + TIMBUART_TXFIFO); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } dev_dbg(port->dev, -- GitLab From 852322ff4f2be566b0165a1f9c2adfcc0a86f8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:48 +0300 Subject: [PATCH 0325/1480] serial: uartlite: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-42-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index eca41ac5477cb..94584e54ebbed 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -203,8 +203,7 @@ static int ulite_transmit(struct uart_port *port, int stat) return 0; uart_out32(xmit->buf[xmit->tail], ULITE_TX, port); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); - port->icount.tx++; + uart_xmit_advance(port, 1); /* wake up */ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -- GitLab From 41e804c4dec667e64c9204e13862cf634df794a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:49 +0300 Subject: [PATCH 0326/1480] serial: ucc_uart: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-43-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ucc_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 82cf14dd3d433..b09b6496ee3eb 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -372,8 +372,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); while (count < qe_port->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); count++; if (xmit->head == xmit->tail) break; -- GitLab From edc62b17ed9f6db3de3521793e4689e15aad4625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:50 +0300 Subject: [PATCH 0327/1480] serial: xuartps: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-44-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 2eff7cff57c48..01d8027e64fda 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -326,9 +326,7 @@ static void cdns_uart_handle_tx(void *dev_id) !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)) { writel(xmit->buf[xmit->tail], port->membase + CDNS_UART_FIFO); - - port->icount.tx++; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart_xmit_advance(port, 1); numbytes--; } -- GitLab From c2087b37d10404220d06f4503ef165ab7835b246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:11:51 +0300 Subject: [PATCH 0328/1480] serial: zs: Use uart_xmit_advance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of the new uart_xmit_advance() helper. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019091151.6692-45-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/zs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 688db7d8b7488..730c648e32ff3 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c @@ -623,8 +623,7 @@ static void zs_raw_transmit_chars(struct zs_port *zport) /* Send char. */ write_zsdata(zport, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - zport->port.icount.tx++; + uart_xmit_advance(&zport->port, 1); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&zport->port); -- GitLab From 109a951a9f1fd8a34ebd1896cbbd5d5cede880a7 Mon Sep 17 00:00:00 2001 From: Kartik Date: Tue, 18 Oct 2022 20:28:06 +0530 Subject: [PATCH 0329/1480] serial: tegra: Read DMA status before terminating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read the DMA status before terminating the DMA, as doing so deletes the DMA desc. Also, to get the correct transfer status information, pause the DMA using dmaengine_pause() before reading the DMA status. Fixes: e9ea096dd225 ("serial: tegra: add serial driver") Reviewed-by: Jon Hunter Reviewed-by: Ilpo Järvinen Acked-by: Thierry Reding Signed-off-by: Akhil R Signed-off-by: Kartik Link: https://lore.kernel.org/r/1666105086-17326-1-git-send-email-kkartik@nvidia.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 4304e3f9307dd..e5b9773db5e36 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -618,8 +618,9 @@ static void tegra_uart_stop_tx(struct uart_port *u) if (tup->tx_in_progress != TEGRA_UART_TX_DMA) return; - dmaengine_terminate_all(tup->tx_dma_chan); + dmaengine_pause(tup->tx_dma_chan); dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); + dmaengine_terminate_all(tup->tx_dma_chan); count = tup->tx_bytes_requested - state.residue; async_tx_ack(tup->tx_dma_desc); uart_xmit_advance(&tup->uport, count); @@ -762,8 +763,9 @@ static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup) return; } - dmaengine_terminate_all(tup->rx_dma_chan); + dmaengine_pause(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); + dmaengine_terminate_all(tup->rx_dma_chan); tegra_uart_rx_buffer_push(tup, state.residue); tup->rx_dma_active = false; -- GitLab From 6dd07781b4cdd38103c81ddcc88fa4e8a31ebf71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:33:39 +0300 Subject: [PATCH 0330/1480] serial: Convert serial_rs485 to kernel doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert struct serial_rs485 comments to kernel doc format and include it into documentation. Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Reviewed-by: Bagas Sanjaya Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019093343.9546-2-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/serial-rs485.rst | 13 +++-- include/uapi/linux/serial.h | 55 ++++++++++++------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst index 6ebad75c74ed9..264e4b7537135 100644 --- a/Documentation/driver-api/serial/serial-rs485.rst +++ b/Documentation/driver-api/serial/serial-rs485.rst @@ -29,11 +29,11 @@ RS485 Serial Communications 3. Data Structures Already Available in the Kernel ================================================== - The Linux kernel provides the serial_rs485 structure (see [1]) to handle - RS485 communications. This data structure is used to set and configure RS485 + The Linux kernel provides the serial_rs485 structure to handle RS485 + communications. This data structure is used to set and configure RS485 parameters in the platform data and in ioctls. - The device tree can also provide RS485 boot time parameters (see [2] + The device tree can also provide RS485 boot time parameters (see [1] for bindings). The driver is in charge of filling this data structure from the values given by the device tree. @@ -47,6 +47,9 @@ RS485 Serial Communications for the uart_port. TIOCGRS485 ioctl can be used to read back the serial_rs485 structure matching to the current configuration. +.. kernel-doc:: include/uapi/linux/serial.h + :identifiers: serial_rs485 + 4. Usage from user-level ======================== @@ -126,6 +129,4 @@ RS485 Serial Communications 6. References ============= - [1] include/uapi/linux/serial.h - - [2] Documentation/devicetree/bindings/serial/rs485.txt + [1] Documentation/devicetree/bindings/serial/rs485.txt diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h index cea06924b295d..53bc1af67a411 100644 --- a/include/uapi/linux/serial.h +++ b/include/uapi/linux/serial.h @@ -107,33 +107,50 @@ struct serial_icounter_struct { int reserved[9]; }; -/* +/** + * struct serial_rs485 - serial interface for controlling RS485 settings. + * @flags: RS485 feature flags. + * @delay_rts_before_send: Delay before send (milliseconds). + * @delay_rts_after_send: Delay after send (milliseconds). + * @addr_recv: Receive filter for RS485 addressing mode + * (used only when %SER_RS485_ADDR_RECV is set). + * @addr_dest: Destination address for RS485 addressing mode + * (used only when %SER_RS485_ADDR_DEST is set). + * @padding0: Padding (set to zero). + * @padding1: Padding (set to zero). + * @padding: Deprecated, use @padding0 and @padding1 instead. + * Do not use with @addr_recv and @addr_dest (due to + * overlap). + * * Serial interface for controlling RS485 settings on chips with suitable * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your * platform. The set function returns the new state, with any unsupported bits * reverted appropriately. + * + * The flag bits are: + * + * * %SER_RS485_ENABLED - RS485 enabled. + * * %SER_RS485_RTS_ON_SEND - Logical level for RTS pin when sending. + * * %SER_RS485_RTS_AFTER_SEND - Logical level for RTS pin after sent. + * * %SER_RS485_RX_DURING_TX - Full-duplex RS485 line. + * * %SER_RS485_TERMINATE_BUS - Enable bus termination (if supported). + * * %SER_RS485_ADDRB - Enable RS485 addressing mode. + * * %SER_RS485_ADDR_RECV - Receive address filter (enables @addr_recv). Requires %SER_RS485_ADDRB. + * * %SER_RS485_ADDR_DEST - Destination address (enables @addr_dest). Requires %SER_RS485_ADDRB. */ - struct serial_rs485 { - __u32 flags; /* RS485 feature flags */ -#define SER_RS485_ENABLED (1 << 0) /* If enabled */ -#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for - RTS pin when - sending */ -#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for - RTS pin after sent*/ + __u32 flags; +#define SER_RS485_ENABLED (1 << 0) +#define SER_RS485_RTS_ON_SEND (1 << 1) +#define SER_RS485_RTS_AFTER_SEND (1 << 2) #define SER_RS485_RX_DURING_TX (1 << 4) -#define SER_RS485_TERMINATE_BUS (1 << 5) /* Enable bus - termination - (if supported) */ - -/* RS-485 addressing mode */ -#define SER_RS485_ADDRB (1 << 6) /* Enable addressing mode */ -#define SER_RS485_ADDR_RECV (1 << 7) /* Receive address filter */ -#define SER_RS485_ADDR_DEST (1 << 8) /* Destination address */ +#define SER_RS485_TERMINATE_BUS (1 << 5) +#define SER_RS485_ADDRB (1 << 6) +#define SER_RS485_ADDR_RECV (1 << 7) +#define SER_RS485_ADDR_DEST (1 << 8) - __u32 delay_rts_before_send; /* Delay before send (milliseconds) */ - __u32 delay_rts_after_send; /* Delay after send (milliseconds) */ + __u32 delay_rts_before_send; + __u32 delay_rts_after_send; /* The fields below are defined by flags */ union { -- GitLab From 851453abc8e9cfe92bbf8fdf07ee024ec372f09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:33:40 +0300 Subject: [PATCH 0331/1480] Documentation: rs485: Link reference properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Link DT bindings reference properly. Reviewed-by: Andy Shevchenko Reviewed-by: Bagas Sanjaya Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019093343.9546-3-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/serial/serial-rs485.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst index 264e4b7537135..513758a702a67 100644 --- a/Documentation/driver-api/serial/serial-rs485.rst +++ b/Documentation/driver-api/serial/serial-rs485.rst @@ -33,9 +33,9 @@ RS485 Serial Communications communications. This data structure is used to set and configure RS485 parameters in the platform data and in ioctls. - The device tree can also provide RS485 boot time parameters (see [1] - for bindings). The driver is in charge of filling this data structure from - the values given by the device tree. + The device tree can also provide RS485 boot time parameters + [#DT-bindings]_. The driver is in charge of filling this data structure + from the values given by the device tree. Any driver for devices capable of working both as RS232 and RS485 should implement the rs485_config callback and provide rs485_supported in the @@ -129,4 +129,4 @@ RS485 Serial Communications 6. References ============= - [1] Documentation/devicetree/bindings/serial/rs485.txt +.. [#DT-bindings] Documentation/devicetree/bindings/serial/rs485.txt -- GitLab From 0f4648a1a6d36487e4134a4fd75d8cdae0cd6bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:33:41 +0300 Subject: [PATCH 0332/1480] Documentation: rs485: Mention uart_get_rs485_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add to rs485 documentation that serial core prepares the struct serial_rs485 when uart_get_rs485_mode() is called. Remove the wrong claim that the driver must fill it by itself. Reviewed-by: Andy Shevchenko Reviewed-by: Bagas Sanjaya Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019093343.9546-4-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/serial/serial-rs485.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst index 513758a702a67..ee34c8e1e56ee 100644 --- a/Documentation/driver-api/serial/serial-rs485.rst +++ b/Documentation/driver-api/serial/serial-rs485.rst @@ -34,8 +34,9 @@ RS485 Serial Communications parameters in the platform data and in ioctls. The device tree can also provide RS485 boot time parameters - [#DT-bindings]_. The driver is in charge of filling this data structure - from the values given by the device tree. + [#DT-bindings]_. The serial core fills the struct serial_rs485 from the + values given by the device tree when the driver calls + uart_get_rs485_mode(). Any driver for devices capable of working both as RS232 and RS485 should implement the rs485_config callback and provide rs485_supported in the @@ -48,7 +49,7 @@ RS485 Serial Communications serial_rs485 structure matching to the current configuration. .. kernel-doc:: include/uapi/linux/serial.h - :identifiers: serial_rs485 + :identifiers: serial_rs485 uart_get_rs485_mode 4. Usage from user-level ======================== -- GitLab From 891e999394f56b52ed81b9ebcb7fe0bf050a3157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:33:42 +0300 Subject: [PATCH 0333/1480] Documentation: rs485: Fix struct referencing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use "struct serial_rs485" to get the references properly recognized. Reviewed-by: Andy Shevchenko Reviewed-by: Bagas Sanjaya Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019093343.9546-5-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/serial-rs485.rst | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst index ee34c8e1e56ee..e53aa291bcd7d 100644 --- a/Documentation/driver-api/serial/serial-rs485.rst +++ b/Documentation/driver-api/serial/serial-rs485.rst @@ -29,7 +29,7 @@ RS485 Serial Communications 3. Data Structures Already Available in the Kernel ================================================== - The Linux kernel provides the serial_rs485 structure to handle RS485 + The Linux kernel provides the struct serial_rs485 to handle RS485 communications. This data structure is used to set and configure RS485 parameters in the platform data and in ioctls. @@ -40,13 +40,14 @@ RS485 Serial Communications Any driver for devices capable of working both as RS232 and RS485 should implement the rs485_config callback and provide rs485_supported in the - uart_port structure. The serial core calls rs485_config to do the device - specific part in response to TIOCSRS485 ioctl (see below). The rs485_config - callback receives a pointer to a sanitizated serial_rs485 structure. The - serial_rs485 userspace provides is sanitized before calling rs485_config - using rs485_supported that indicates what RS485 features the driver supports - for the uart_port. TIOCGRS485 ioctl can be used to read back the - serial_rs485 structure matching to the current configuration. + struct uart_port. The serial core calls rs485_config to do the device + specific part in response to TIOCSRS485 ioctl (see below). The + rs485_config callback receives a pointer to a sanitizated struct + serial_rs485. The struct serial_rs485 userspace provides is sanitized + before calling rs485_config using rs485_supported that indicates what + RS485 features the driver supports for the struct uart_port. TIOCGRS485 + ioctl can be used to read back the struct serial_rs485 matching to the + current configuration. .. kernel-doc:: include/uapi/linux/serial.h :identifiers: serial_rs485 uart_get_rs485_mode @@ -108,8 +109,8 @@ RS485 Serial Communications The Linux kernel provides addressing mode for multipoint RS-485 serial communications line. The addressing mode is enabled with SER_RS485_ADDRB - flag in serial_rs485. Struct serial_rs485 has two additional flags and - fields for enabling receive and destination addresses. + flag in struct serial_rs485. The struct serial_rs485 has two additional + flags and fields for enabling receive and destination addresses. Address mode flags: - SER_RS485_ADDRB: Enabled addressing mode (sets also ADDRB in termios). -- GitLab From 7b1c56e08a45693ce6f708a4ee499e44c4fb9ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 12:33:43 +0300 Subject: [PATCH 0334/1480] Documentation: Make formatting consistent for rs485 docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tweak styling of names that come directly from the code. Suggested-by: Bagas Sanjaya Reviewed-by: Bagas Sanjaya Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019093343.9546-6-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/serial-rs485.rst | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst index e53aa291bcd7d..dce061ef76477 100644 --- a/Documentation/driver-api/serial/serial-rs485.rst +++ b/Documentation/driver-api/serial/serial-rs485.rst @@ -39,15 +39,15 @@ RS485 Serial Communications uart_get_rs485_mode(). Any driver for devices capable of working both as RS232 and RS485 should - implement the rs485_config callback and provide rs485_supported in the - struct uart_port. The serial core calls rs485_config to do the device - specific part in response to TIOCSRS485 ioctl (see below). The - rs485_config callback receives a pointer to a sanitizated struct + implement the ``rs485_config`` callback and provide ``rs485_supported`` + in the ``struct uart_port``. The serial core calls ``rs485_config`` to do + the device specific part in response to TIOCSRS485 ioctl (see below). The + ``rs485_config`` callback receives a pointer to a sanitizated struct serial_rs485. The struct serial_rs485 userspace provides is sanitized - before calling rs485_config using rs485_supported that indicates what - RS485 features the driver supports for the struct uart_port. TIOCGRS485 - ioctl can be used to read back the struct serial_rs485 matching to the - current configuration. + before calling ``rs485_config`` using ``rs485_supported`` that indicates + what RS485 features the driver supports for the ``struct uart_port``. + TIOCGRS485 ioctl can be used to read back the struct serial_rs485 + matching to the current configuration. .. kernel-doc:: include/uapi/linux/serial.h :identifiers: serial_rs485 uart_get_rs485_mode @@ -108,23 +108,24 @@ RS485 Serial Communications ======================== The Linux kernel provides addressing mode for multipoint RS-485 serial - communications line. The addressing mode is enabled with SER_RS485_ADDRB - flag in struct serial_rs485. The struct serial_rs485 has two additional - flags and fields for enabling receive and destination addresses. + communications line. The addressing mode is enabled with + ``SER_RS485_ADDRB`` flag in struct serial_rs485. The struct serial_rs485 + has two additional flags and fields for enabling receive and destination + addresses. Address mode flags: - - SER_RS485_ADDRB: Enabled addressing mode (sets also ADDRB in termios). - - SER_RS485_ADDR_RECV: Receive (filter) address enabled. - - SER_RS485_ADDR_DEST: Set destination address. + - ``SER_RS485_ADDRB``: Enabled addressing mode (sets also ADDRB in termios). + - ``SER_RS485_ADDR_RECV``: Receive (filter) address enabled. + - ``SER_RS485_ADDR_DEST``: Set destination address. - Address fields (enabled with corresponding SER_RS485_ADDR_* flag): - - addr_recv: Receive address. - - addr_dest: Destination address. + Address fields (enabled with corresponding ``SER_RS485_ADDR_*`` flag): + - ``addr_recv``: Receive address. + - ``addr_dest``: Destination address. Once a receive address is set, the communication can occur only with the particular device and other peers are filtered out. It is left up to the receiver side to enforce the filtering. Receive address will be cleared - if SER_RS485_ADDR_RECV is not set. + if ``SER_RS485_ADDR_RECV`` is not set. Note: not all devices supporting RS485 support multipoint addressing. -- GitLab From 0c3c184c5218d9209fcb8ee151074bc629bd4024 Mon Sep 17 00:00:00 2001 From: Siarhei Volkau Date: Mon, 31 Oct 2022 21:40:39 +0300 Subject: [PATCH 0335/1480] dt-bindings: serial: ingenic: Add support for the JZ4750/55 SoCs These SoCs UART block are the same as JZ4725b' one, the difference is outside of the block - it is in the clock generation unit (CGU). The difference requires to make a quirk for early console init. Acked-by: Krzysztof Kozlowski Signed-off-by: Siarhei Volkau Link: https://lore.kernel.org/r/20221031184041.1338129-2-lis8215@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/ingenic,uart.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml index 9ca7a18ecd8b1..315ceb722e199 100644 --- a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml +++ b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml @@ -20,6 +20,7 @@ properties: oneOf: - enum: - ingenic,jz4740-uart + - ingenic,jz4750-uart - ingenic,jz4760-uart - ingenic,jz4780-uart - ingenic,x1000-uart @@ -31,6 +32,9 @@ properties: - items: - const: ingenic,jz4725b-uart - const: ingenic,jz4740-uart + - items: + - const: ingenic,jz4755-uart + - const: ingenic,jz4750-uart reg: maxItems: 1 -- GitLab From e9c29d80278c0f5c6198ac741b10a534672042ca Mon Sep 17 00:00:00 2001 From: Siarhei Volkau Date: Mon, 31 Oct 2022 21:40:40 +0300 Subject: [PATCH 0336/1480] serial: 8250/ingenic: Add support for the JZ4750/JZ4755 JZ4750/55/60 (but not JZ4760b) have an optional /2 divider between the EXT oscillator and some peripherals including UART, which will be enabled if using a 24 MHz oscillator, and disabled when using a 12 MHz oscillator. This behavior relies on hardware differences: most boards (if not all) with those SoCs have 12 or 24 MHz oscillators but many peripherals want 12Mhz to operate properly (AIC and USB-PHY at least). The 16MHz threshold looks arbitrary but used in vendor's bootloader code for enable the divider. The patch doesn't affect JZ4760's behavior as it is subject for another patchset with re-classification of all supported ingenic UARTs. Link: https://github.com/carlos-wong/uboot_jz4755/blob/master/cpu/mips/jz_serial.c#L158 Signed-off-by: Siarhei Volkau Link: https://lore.kernel.org/r/20221031184041.1338129-3-lis8215@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_ingenic.c | 32 +++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 2b2f5d8d24b91..617b8ce60d6b5 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -87,7 +87,7 @@ static void __init ingenic_early_console_setup_clock(struct earlycon_device *dev dev->port.uartclk = be32_to_cpup(prop); } -static int __init ingenic_early_console_setup(struct earlycon_device *dev, +static int __init ingenic_earlycon_setup_tail(struct earlycon_device *dev, const char *opt) { struct uart_port *port = &dev->port; @@ -103,8 +103,6 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev, uart_parse_options(opt, &baud, &parity, &bits, &flow); } - ingenic_early_console_setup_clock(dev); - if (dev->baud) baud = dev->baud; divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud); @@ -129,9 +127,36 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev, return 0; } +static int __init ingenic_early_console_setup(struct earlycon_device *dev, + const char *opt) +{ + ingenic_early_console_setup_clock(dev); + + return ingenic_earlycon_setup_tail(dev, opt); +} + +static int __init jz4750_early_console_setup(struct earlycon_device *dev, + const char *opt) +{ + /* + * JZ4750/55/60 have an optional /2 divider between the EXT + * oscillator and some peripherals including UART, which will + * be enabled if using a 24 MHz oscillator, and disabled when + * using a 12 MHz oscillator. + */ + ingenic_early_console_setup_clock(dev); + if (dev->port.uartclk >= 16000000) + dev->port.uartclk /= 2; + + return ingenic_earlycon_setup_tail(dev, opt); +} + OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart", ingenic_early_console_setup); +OF_EARLYCON_DECLARE(jz4750_uart, "ingenic,jz4750-uart", + jz4750_early_console_setup); + OF_EARLYCON_DECLARE(jz4770_uart, "ingenic,jz4770-uart", ingenic_early_console_setup); @@ -328,6 +353,7 @@ static const struct ingenic_uart_config x1000_uart_config = { static const struct of_device_id of_match[] = { { .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config }, + { .compatible = "ingenic,jz4750-uart", .data = &jz4760_uart_config }, { .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config }, { .compatible = "ingenic,jz4770-uart", .data = &jz4760_uart_config }, { .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config }, -- GitLab From 79d0224f6bf296d04cd843cfc49921b19c97bb09 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 29 Sep 2022 16:44:00 +0200 Subject: [PATCH 0337/1480] tty: serial: imx: Handle RS485 DE signal active high The default polarity of RS485 DE signal is active high. This driver does not handle such case properly. Currently, when a pin is multiplexed as a UART CTS_B on boot, this pin is pulled HIGH by the i.MX UART CTS circuit, which activates DE signal on the RS485 transceiver and thus behave as if the RS485 was transmitting data, so the system blocks the RS485 bus when it starts and until user application takes over. This behavior is not OK. The problem consists of two separate parts. First, the i.MX UART IP requires UCR1 UARTEN and UCR2 RXEN to be set for UCR2 CTSC and CTS bits to have any effect. The UCR2 CTSC bit permits the driver to set CTS (RTS_B or RS485 DE signal) to either level sychronous to the internal UART IP clock. Compared to other options, like GPIO CTS control, this has the benefit of being synchronous to the UART IP clock and thus without glitches or bus delays. The reason for the CTS design is likely because when the Receiver is disabled, the UART IP can never indicate that it is ready to receive data by assering CTS signal, so the CTS is always pulled HIGH by default. When the port is closed by user space, imx_uart_stop_rx() clears UCR2 RXEN bit, and imx_uart_shutdown() clears UCR1 UARTEN bit. This disables UART Receiver and UART itself, and forces CTS signal HIGH, which leads to the RS485 bus being blocked because RS485 DE is incorrectly active. The proposed solution for this problem is to keep the Receiver running even after the port is closed, but in loopback mode. This disconnects the RX FIFO input from the RXD external signal, and since UCR2 TXEN is cleared, the UART Transmitter is disabled, so nothing can feed data in the RX FIFO. Because the Receiver is still enabled, the UCR2 CTSC and CTS bits still have effect and the CTS (RS485 DE) control is retained. Note that in case of RS485 DE signal active low, there is no problem and no special handling is necessary. The CTS signal defaults to HIGH, thus the RS485 is by default set to Receive and the bus is not blocked. Note that while there is the possibility to control CTS using GPIO with either CTS polarity, this has the downside of not being synchronous to the UART IP clock and thus glitchy and susceptible to slow DE switching. Second, on boot, before the UART driver probe callback is called, the driver core triggers pinctrl_init_done() and configures the IOMUXC to default state. At this point, UCR1 UARTEN and UCR2 RXEN are both still cleared, but UART CTS_B (RS485 DE) is configured as CTS function, thus the RTS signal is pulled HIGH by the UART IP CTS circuit. One part of the solution here is to enable UCR1 UARTEN and UCR2 RXEN and UTS loopback in this driver probe callback, thus unblocking the CTSC and CTS control early on. But this is still too late, since the pin control is already configured and CTS has been pulled HIGH for a short period of time. When Linux kernel boots and this driver is bound, the pin control is set to special "init" state if the state is available, and driver can switch the "default" state afterward when ready. This state can be used to set the CTS line as a GPIO in DT temporarily, and a GPIO hog can force such GPIO to LOW, thus keeping the RS485 DE line LOW early on boot. Once the driver takes over and UCR1 UARTEN and UCR2 RXEN and UTS loopback are all enabled, the driver can switch to "default" pin control state and control the CTS line as function instead. DT binding example is below: " &gpio6 { rts-init-hog { gpio-hog; gpios = <5 0>; output-low; line-name = "rs485-de"; }; }; &uart5 { /* DHCOM UART2 */ pinctrl-0 = <&pinctrl_uart5>; pinctrl-1 = <&pinctrl_uart5_init>; pinctrl-names = "default", "init"; ... }; pinctrl_uart5_init: uart5-init-grp { fsl,pins = < ... MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x30b1 >; }; pinctrl_uart5: uart5-grp { fsl,pins = < ... MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B 0x30b1 >; }; " Tested-by: Christoph Niedermaier Reviewed-by: Fabio Estevam Signed-off-by: Marek Vasut Link: https://lore.kernel.org/r/20220929144400.13571-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 64 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index a7548d0a1aeee..11ac805663aed 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -489,7 +489,7 @@ static void imx_uart_stop_tx(struct uart_port *port) static void imx_uart_stop_rx(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - u32 ucr1, ucr2, ucr4; + u32 ucr1, ucr2, ucr4, uts; ucr1 = imx_uart_readl(sport, UCR1); ucr2 = imx_uart_readl(sport, UCR2); @@ -505,7 +505,18 @@ static void imx_uart_stop_rx(struct uart_port *port) imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr4, UCR4); - ucr2 &= ~UCR2_RXEN; + /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ + if (port->rs485.flags & SER_RS485_ENABLED && + port->rs485.flags & SER_RS485_RTS_ON_SEND && + sport->have_rtscts && !sport->have_rtsgpio) { + uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); + uts |= UTS_LOOP; + imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); + ucr2 |= UCR2_RXEN; + } else { + ucr2 &= ~UCR2_RXEN; + } + imx_uart_writel(sport, ucr2, UCR2); } @@ -1390,7 +1401,7 @@ static int imx_uart_startup(struct uart_port *port) int retval, i; unsigned long flags; int dma_is_inited = 0; - u32 ucr1, ucr2, ucr3, ucr4; + u32 ucr1, ucr2, ucr3, ucr4, uts; retval = clk_prepare_enable(sport->clk_per); if (retval) @@ -1495,6 +1506,11 @@ static int imx_uart_startup(struct uart_port *port) imx_uart_writel(sport, ucr2, UCR2); } + /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ + uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); + uts &= ~UTS_LOOP; + imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); + spin_unlock_irqrestore(&sport->port.lock, flags); return 0; @@ -1504,7 +1520,7 @@ static void imx_uart_shutdown(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; - u32 ucr1, ucr2, ucr4; + u32 ucr1, ucr2, ucr4, uts; if (sport->dma_is_enabled) { dmaengine_terminate_sync(sport->dma_chan_tx); @@ -1548,7 +1564,18 @@ static void imx_uart_shutdown(struct uart_port *port) spin_lock_irqsave(&sport->port.lock, flags); ucr1 = imx_uart_readl(sport, UCR1); - ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN); + ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_RXDMAEN | UCR1_ATDMAEN); + /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ + if (port->rs485.flags & SER_RS485_ENABLED && + port->rs485.flags & SER_RS485_RTS_ON_SEND && + sport->have_rtscts && !sport->have_rtsgpio) { + uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); + uts |= UTS_LOOP; + imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); + ucr1 |= UCR1_UARTEN; + } else { + ucr1 &= ~UCR1_UARTEN; + } imx_uart_writel(sport, ucr1, UCR1); ucr4 = imx_uart_readl(sport, UCR4); @@ -2210,7 +2237,7 @@ static int imx_uart_probe(struct platform_device *pdev) void __iomem *base; u32 dma_buf_conf[2]; int ret = 0; - u32 ucr1; + u32 ucr1, ucr2, uts; struct resource *res; int txirq, rxirq, rtsirq; @@ -2347,6 +2374,31 @@ static int imx_uart_probe(struct platform_device *pdev) ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN); imx_uart_writel(sport, ucr1, UCR1); + /* + * In case RS485 is enabled without GPIO RTS control, the UART IP + * is used to control CTS signal. Keep both the UART and Receiver + * enabled, otherwise the UART IP pulls CTS signal always HIGH no + * matter how the UCR2 CTSC and CTS bits are set. To prevent any + * data from being fed into the RX FIFO, enable loopback mode in + * UTS register, which disconnects the RX path from external RXD + * pin and connects it to the Transceiver, which is disabled, so + * no data can be fed to the RX FIFO that way. + */ + if (sport->port.rs485.flags & SER_RS485_ENABLED && + sport->have_rtscts && !sport->have_rtsgpio) { + uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); + uts |= UTS_LOOP; + imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); + + ucr1 = imx_uart_readl(sport, UCR1); + ucr1 |= UCR1_UARTEN; + imx_uart_writel(sport, ucr1, UCR1); + + ucr2 = imx_uart_readl(sport, UCR2); + ucr2 |= UCR2_RXEN; + imx_uart_writel(sport, ucr2, UCR2); + } + if (!imx_uart_is_imx1(sport) && sport->dte_mode) { /* * The DCEDTE bit changes the direction of DSR, DCD, DTR and RI -- GitLab From 2cfc64f3f0e1c1136b1a8247e53dc24c54f0bf93 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 17 Oct 2022 20:16:33 +0300 Subject: [PATCH 0338/1480] serial: 8250_core: Use str_enabled_disabled() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use str_enabled_disabled() helper instead of open coding the same. Reviewed-by: Ilpo Järvinen Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221017171633.65275-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 94fbf0add2ce2..80a2fc2fbd4d7 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_SPARC @@ -1175,8 +1176,8 @@ static int __init serial8250_init(void) serial8250_isa_init_ports(); - pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %sabled\n", - nr_uarts, share_irqs ? "en" : "dis"); + pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %s\n", + nr_uarts, str_enabled_disabled(share_irqs)); #ifdef CONFIG_SPARC ret = sunserial_register_minors(&serial8250_reg, UART_NR); -- GitLab From cc72a1eea5e3f712ab4d59615bf1d4479cee16fc Mon Sep 17 00:00:00 2001 From: ruanjinjie Date: Wed, 19 Oct 2022 14:44:12 +0800 Subject: [PATCH 0339/1480] tty: hvc: make hvc_rtas_dev static The symbol is not used outside of the file, so mark it static. Fixes the following warning: drivers/tty/hvc/hvc_rtas.c:29:19: warning: symbol 'hvc_rtas_dev' was not declared. Should it be static? Reviewed-by: Jiri Slaby Signed-off-by: ruanjinjie Link: https://lore.kernel.org/r/20221019064412.3759874-1-ruanjinjie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index e8b8c645482b0..184d325abeeda 100644 --- a/drivers/tty/hvc/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c @@ -26,7 +26,7 @@ #include "hvc_console.h" #define hvc_rtas_cookie 0x67781e15 -struct hvc_struct *hvc_rtas_dev; +static struct hvc_struct *hvc_rtas_dev; static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE; static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE; -- GitLab From fa31528a214701e3afb3997f1c2c2b7290e1d05c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 21 Oct 2022 16:02:16 +0200 Subject: [PATCH 0340/1480] dt-bindings: serial: renesas,scif: Document r8a779g0 support Document support for the Serial Communication Interface with FIFO (SCIF) in the Renesas R-Car V4H (R8A779G0) SoC. Reviewed-by: Wolfram Sang Acked-by: Krzysztof Kozlowski Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/8a2d04651f04a97d652395b4d933af5c3c8d5b5b.1666360789.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,scif.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index f930e7f1349fc..f81f2d67a1ed4 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -67,6 +67,7 @@ properties: - enum: - renesas,scif-r8a779a0 # R-Car V3U - renesas,scif-r8a779f0 # R-Car S4-8 + - renesas,scif-r8a779g0 # R-Car V4H - const: renesas,rcar-gen4-scif # R-Car Gen4 - const: renesas,scif # generic SCIF compatible UART -- GitLab From 15730dc45dc7432713c7af9ee5abad76872f6405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 13:55:04 +0300 Subject: [PATCH 0341/1480] tty: Cleanup tty buffer align mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't use decimal for mask. Don't use literal for aligning. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019105504.16800-2-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 5e287dedce018..3f057805560fe 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -21,7 +21,7 @@ #include "tty.h" #define MIN_TTYB_SIZE 256 -#define TTYB_ALIGN_MASK 255 +#define TTYB_ALIGN_MASK 0xff /* * Byte threshold to limit memory consumption for flip buffers. @@ -37,7 +37,7 @@ * logic this must match. */ -#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) +#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~TTYB_ALIGN_MASK) /** * tty_buffer_lock_exclusive - gain exclusive access to buffer -- GitLab From 98e4c68ddcaf3721df9bef809775a8e3562cb6f9 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Tue, 1 Nov 2022 22:48:30 +0900 Subject: [PATCH 0342/1480] perf probe: Fix to avoid crashing if DW_AT_decl_file is NULL Since clang generates DWARF5 which sets DW_AT_decl_file as 0, dwarf_decl_file() thinks that is invalid and returns NULL. In that case 'perf probe' SIGSEGVs because it doesn't expect a NULL decl_file. This adds a dwarf_decl_file() return value check to avoid such SEGV with clang generated DWARF5 info. Without this, 'perf probe' crashes: $ perf probe -k $BIN_PATH/vmlinux -s $SRC_PATH -L vfs_read:10 Segmentation fault $ With this, it just warns about it: $ perf probe -k $BIN_PATH/vmlinux -s $SRC_PATH -L vfs_read:10 Debuginfo analysis failed. Error: Failed to show lines. $ Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/166731051077.2100653.15626653369345128302.stgit@devnote3 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 7 ++++++- tools/perf/util/probe-finder.c | 29 +++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 609ca16715018..406b7bdc851ab 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -137,7 +137,7 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, Dwarf_Addr addr, } out: - return *lineno ?: -ENOENT; + return (*lineno && *fname) ? *lineno : -ENOENT; } static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data); @@ -874,6 +874,11 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); dwarf_decl_line(rt_die, &decl); decf = dwarf_decl_file(rt_die); + if (!decf) { + pr_debug2("Failed to get the declared file name of %s\n", + dwarf_diename(rt_die)); + return -EINVAL; + } } else cu_die = rt_die; if (!cu_die) { diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 50d861a80f572..1aa8fcc41c76c 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1063,6 +1063,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) struct dwarf_callback_param *param = data; struct probe_finder *pf = param->data; struct perf_probe_point *pp = &pf->pev->point; + const char *fname; /* Check tag and diename */ if (!die_is_func_def(sp_die) || @@ -1070,12 +1071,17 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) return DWARF_CB_OK; /* Check declared file */ - if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die))) + fname = dwarf_decl_file(sp_die); + if (!fname) { + pr_warning("A function DIE doesn't have decl_line. Maybe broken DWARF?\n"); + return DWARF_CB_OK; + } + if (pp->file && fname && strtailcmp(pp->file, fname)) return DWARF_CB_OK; pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die), (unsigned long)dwarf_dieoffset(sp_die)); - pf->fname = dwarf_decl_file(sp_die); + pf->fname = fname; if (pp->line) { /* Function relative line */ dwarf_decl_line(sp_die, &pf->lno); pf->lno += pp->line; @@ -1134,6 +1140,7 @@ struct pubname_callback_param { static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) { struct pubname_callback_param *param = data; + const char *fname; if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) { if (dwarf_tag(param->sp_die) != DW_TAG_subprogram) @@ -1143,9 +1150,11 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die)) return DWARF_CB_OK; - if (param->file && - strtailcmp(param->file, dwarf_decl_file(param->sp_die))) - return DWARF_CB_OK; + if (param->file) { + fname = dwarf_decl_file(param->sp_die); + if (!fname || strtailcmp(param->file, fname)) + return DWARF_CB_OK; + } param->found = 1; return DWARF_CB_ABORT; @@ -1779,7 +1788,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr, } /* Verify the lineno and baseline are in a same file */ tmp = dwarf_decl_file(&spdie); - if (!tmp || strcmp(tmp, fname) != 0) + if (!tmp || (fname && strcmp(tmp, fname) != 0)) lineno = 0; } @@ -1889,10 +1898,14 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) struct dwarf_callback_param *param = data; struct line_finder *lf = param->data; struct line_range *lr = lf->lr; + const char *fname; /* Check declared file */ - if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) - return DWARF_CB_OK; + if (lr->file) { + fname = dwarf_decl_file(sp_die); + if (!fname || strtailcmp(lr->file, fname)) + return DWARF_CB_OK; + } if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) { lf->fname = dwarf_decl_file(sp_die); -- GitLab From f828929ab7f0dc3353e4a617f94f297fa8f3dec3 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Tue, 1 Nov 2022 22:48:39 +0900 Subject: [PATCH 0343/1480] perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor Use dwarf_attr_integrate() instead of dwarf_attr() for generic attribute acccessor functions, so that it can find the specified attribute from abstact origin DIE etc. Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/166731051988.2100653.13595339994343449770.stgit@devnote3 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 406b7bdc851ab..216fc3d959e80 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -308,7 +308,7 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name, { Dwarf_Attribute attr; - if (dwarf_attr(tp_die, attr_name, &attr) == NULL || + if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL || dwarf_formudata(&attr, result) != 0) return -ENOENT; @@ -321,7 +321,7 @@ static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name, { Dwarf_Attribute attr; - if (dwarf_attr(tp_die, attr_name, &attr) == NULL || + if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL || dwarf_formsdata(&attr, result) != 0) return -ENOENT; -- GitLab From dc9a5d2ccd5c823cc05cafe75fcf19b682d8152c Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Tue, 1 Nov 2022 22:48:49 +0900 Subject: [PATCH 0344/1480] perf probe: Fix to get declared file name from clang DWARF5 Fix to get the declared file name even if it uses file index 0 in DWARF5, using custom die_get_decl_file() function. Actually, the DWARF5 standard says file index 0 of the DW_AT_decl_file is invalid(1), but there is a discussion and maybe this will be updated [2]. Anyway, clang generates such DWARF5 file for the linux kernel. Thus it must be handled. Without this, 'perf probe' returns an error: $ ./perf probe -k $BIN_PATH/vmlinux -s $SRC_PATH -L vfs_read:10 Debuginfo analysis failed. Error: Failed to show lines. With this, it can handle the case correctly: $ ./perf probe -k $BIN_PATH/vmlinux -s $SRC_PATH -L vfs_read:10 11 ret = rw_verify_area(READ, file, pos, count); 12 if (ret) return ret; [1] DWARF5 specification 2.14 says "The value 0 indicates that no source file has been specified.") [2] http://wiki.dwarfstd.org/index.php?title=DWARF5_Line_Table_File_Numbers) Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/166731052936.2100653.13380621874859467731.stgit@devnote3 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 47 +++++++++++++++++++++++----------- tools/perf/util/dwarf-aux.h | 3 +++ tools/perf/util/probe-finder.c | 14 +++++----- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 216fc3d959e80..30b36b525681a 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -123,7 +123,7 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, Dwarf_Addr addr, if (die_find_realfunc(cu_die, addr, &die_mem) && die_entrypc(&die_mem, &faddr) == 0 && faddr == addr) { - *fname = dwarf_decl_file(&die_mem); + *fname = die_get_decl_file(&die_mem); dwarf_decl_line(&die_mem, lineno); goto out; } @@ -486,6 +486,19 @@ static int die_get_decl_fileno(Dwarf_Die *pdie) return -ENOENT; } +/* Return the file name by index */ +static const char *die_get_file_name(Dwarf_Die *dw_die, int idx) +{ + Dwarf_Die cu_die; + Dwarf_Files *files; + + if (idx < 0 || !dwarf_diecu(dw_die, &cu_die, NULL, NULL) || + dwarf_getsrcfiles(&cu_die, &files, NULL) != 0) + return NULL; + + return dwarf_filesrc(files, idx, NULL, NULL); +} + /** * die_get_call_file - Get callsite file name of inlined function instance * @in_die: a DIE of an inlined function instance @@ -495,18 +508,22 @@ static int die_get_decl_fileno(Dwarf_Die *pdie) */ const char *die_get_call_file(Dwarf_Die *in_die) { - Dwarf_Die cu_die; - Dwarf_Files *files; - int idx; - - idx = die_get_call_fileno(in_die); - if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) || - dwarf_getsrcfiles(&cu_die, &files, NULL) != 0) - return NULL; - - return dwarf_filesrc(files, idx, NULL, NULL); + return die_get_file_name(in_die, die_get_call_fileno(in_die)); } +/** + * die_get_decl_file - Find the declared file name of this DIE + * @dw_die: a DIE for something declared. + * + * Get declared file name of @dw_die. + * NOTE: Since some version of clang DWARF5 implementation incorrectly uses + * file index 0 for DW_AT_decl_file, die_get_decl_file() will return NULL for + * such cases. Use this function instead. + */ +const char *die_get_decl_file(Dwarf_Die *dw_die) +{ + return die_get_file_name(dw_die, die_get_decl_fileno(dw_die)); +} /** * die_find_child - Generic DIE search function in DIE tree @@ -790,7 +807,7 @@ static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) } if (addr) { - fname = dwarf_decl_file(in_die); + fname = die_get_decl_file(in_die); if (fname && dwarf_decl_line(in_die, &lineno) == 0) { lw->retval = lw->callback(fname, lineno, addr, lw->data); if (lw->retval != 0) @@ -818,7 +835,7 @@ static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive, int lineno; /* Handle function declaration line */ - fname = dwarf_decl_file(sp_die); + fname = die_get_decl_file(sp_die); if (fname && dwarf_decl_line(sp_die, &lineno) == 0 && die_entrypc(sp_die, &addr) == 0) { lw.retval = callback(fname, lineno, addr, data); @@ -873,7 +890,7 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) if (dwarf_tag(rt_die) != DW_TAG_compile_unit) { cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); dwarf_decl_line(rt_die, &decl); - decf = dwarf_decl_file(rt_die); + decf = die_get_decl_file(rt_die); if (!decf) { pr_debug2("Failed to get the declared file name of %s\n", dwarf_diename(rt_die)); @@ -928,7 +945,7 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) dwarf_decl_line(&die_mem, &inl); if (inl != decl || - decf != dwarf_decl_file(&die_mem)) + decf != die_get_decl_file(&die_mem)) continue; } } diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 7ee0fa19b5c49..7ec8bc1083bb3 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -50,6 +50,9 @@ int die_get_call_lineno(Dwarf_Die *in_die); /* Get callsite file name of inlined function instance */ const char *die_get_call_file(Dwarf_Die *in_die); +/* Get declared file name of a DIE */ +const char *die_get_decl_file(Dwarf_Die *dw_die); + /* Get type die */ Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1aa8fcc41c76c..54b49ce85c9f2 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -763,7 +763,7 @@ static int find_best_scope_cb(Dwarf_Die *fn_die, void *data) /* Skip if declared file name does not match */ if (fsp->file) { - file = dwarf_decl_file(fn_die); + file = die_get_decl_file(fn_die); if (!file || strcmp(fsp->file, file) != 0) return 0; } @@ -1071,7 +1071,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) return DWARF_CB_OK; /* Check declared file */ - fname = dwarf_decl_file(sp_die); + fname = die_get_decl_file(sp_die); if (!fname) { pr_warning("A function DIE doesn't have decl_line. Maybe broken DWARF?\n"); return DWARF_CB_OK; @@ -1151,7 +1151,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) return DWARF_CB_OK; if (param->file) { - fname = dwarf_decl_file(param->sp_die); + fname = die_get_decl_file(param->sp_die); if (!fname || strtailcmp(param->file, fname)) return DWARF_CB_OK; } @@ -1750,7 +1750,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr, goto post; } - fname = dwarf_decl_file(&spdie); + fname = die_get_decl_file(&spdie); if (addr == baseaddr) { /* Function entry - Relative line number is 0 */ lineno = baseline; @@ -1787,7 +1787,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr, } } /* Verify the lineno and baseline are in a same file */ - tmp = dwarf_decl_file(&spdie); + tmp = die_get_decl_file(&spdie); if (!tmp || (fname && strcmp(tmp, fname) != 0)) lineno = 0; } @@ -1902,13 +1902,13 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) /* Check declared file */ if (lr->file) { - fname = dwarf_decl_file(sp_die); + fname = die_get_decl_file(sp_die); if (!fname || strtailcmp(lr->file, fname)) return DWARF_CB_OK; } if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) { - lf->fname = dwarf_decl_file(sp_die); + lf->fname = die_get_decl_file(sp_die); dwarf_decl_line(sp_die, &lr->offset); pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); lf->lno_s = lr->offset + lr->start; -- GitLab From f3c9bd4e16a503cb14891963428d388a4f70ffb8 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:06 -0700 Subject: [PATCH 0345/1480] perf build: Update to C standard to gnu11 C11 has become the standard for mainstream kernel development [1], allowing it in the perf build enables libraries like stdatomic.h to be assumed to be present. This came up in the context of [2]. [1] https://lore.kernel.org/lkml/CAHk-=whWbENRz-vLY6vpESDLj6kGUTKO3khGtVfipHqwewh2HQ@mail.gmail.com/ [2] https://lore.kernel.org/lkml/20221024011024.462518-1-irogers@google.com/ Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 898226ea8cadc..d3d3c13a9f25b 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -307,7 +307,7 @@ CORE_CFLAGS += -ggdb3 CORE_CFLAGS += -funwind-tables CORE_CFLAGS += -Wall CORE_CFLAGS += -Wextra -CORE_CFLAGS += -std=gnu99 +CORE_CFLAGS += -std=gnu11 CXXFLAGS += -std=gnu++14 -fno-exceptions -fno-rtti CXXFLAGS += -Wall -- GitLab From 8ed28c2b56b78442989ef1afee2b968e9d51a65c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:07 -0700 Subject: [PATCH 0346/1480] perf record: Use sig_atomic_t for signal handlers This removes undefined behavior as described in: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Suggested-by: Leo Yan Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 59f3d98a0196d..bd462a3f2bbdb 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -646,10 +646,10 @@ static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size) return record__write(rec, map, bf, size); } -static volatile int signr = -1; -static volatile int child_finished; +static volatile sig_atomic_t signr = -1; +static volatile sig_atomic_t child_finished; #ifdef HAVE_EVENTFD_SUPPORT -static volatile int done_fd = -1; +static volatile sig_atomic_t done_fd = -1; #endif static void sig_handler(int sig) @@ -1926,7 +1926,7 @@ static void record__read_lost_samples(struct record *rec) } -static volatile int workload_exec_errno; +static volatile sig_atomic_t workload_exec_errno; /* * evlist__prepare_workload will send a SIGUSR1 -- GitLab From 7f3374299f9762ba7946138bf0d5cfbd50da111b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:08 -0700 Subject: [PATCH 0347/1480] perf daemon: Use sig_atomic_t to avoid UB Use sig_atomic_t for a variable written to in a signal handler and read elsewhere. This is undefined behavior as per: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c index 3ce0c960ccc9b..7036ec92d47d0 100644 --- a/tools/perf/builtin-daemon.c +++ b/tools/perf/builtin-daemon.c @@ -105,7 +105,7 @@ static const char * const daemon_usage[] = { NULL }; -static bool done; +static volatile sig_atomic_t done; static void sig_handler(int sig __maybe_unused) { -- GitLab From 853596fb71f7c2f7ff0de7b13f09d6598d4d56cd Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:09 -0700 Subject: [PATCH 0348/1480] perf ftrace: Use sig_atomic_t to avoid UB Use sig_atomic_t for a variable written to in a signal handler and read elsewhere. This is undefined behavior as per: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 7de07bb16d235..d7fe00f66b831 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -36,8 +36,8 @@ #define DEFAULT_TRACER "function_graph" -static volatile int workload_exec_errno; -static bool done; +static volatile sig_atomic_t workload_exec_errno; +static volatile sig_atomic_t done; static void sig_handler(int sig __maybe_unused) { -- GitLab From 057929f9d083e80c9b30c324add69d2054ca6d82 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:10 -0700 Subject: [PATCH 0349/1480] perf session: Change type to avoid undefined behaviour in a signal handler The 'session_done' variable is written to inside the signal handler of 'perf report' and 'perf script'. Switch its type to avoid undefined behavior. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1a4f10de29ffe..0e1a3d6bacb92 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -2022,7 +2023,7 @@ static int perf_session__flush_thread_stacks(struct perf_session *session) NULL); } -volatile int session_done; +volatile sig_atomic_t session_done; static int __perf_session__process_decomp_events(struct perf_session *session); -- GitLab From 01513fdc18f395dbcc924bc5e9962b12f86f947a Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:11 -0700 Subject: [PATCH 0350/1480] perf stat: Use sig_atomic_t to avoid undefined behaviour in a signal handler Use sig_atomic_t for variables written/accessed in signal handlers. This is undefined behavior as per: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e52601a54b26d..d5e1670bca204 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -173,7 +173,7 @@ static struct target target = { #define METRIC_ONLY_LEN 20 -static volatile pid_t child_pid = -1; +static volatile sig_atomic_t child_pid = -1; static int detailed_run = 0; static bool transaction_run; static bool topdown_run = false; @@ -208,7 +208,7 @@ struct perf_stat { static struct perf_stat perf_stat; #define STAT_RECORD perf_stat.record -static volatile int done = 0; +static volatile sig_atomic_t done = 0; static struct perf_stat_config stat_config = { .aggr_mode = AGGR_GLOBAL, @@ -580,7 +580,7 @@ static void disable_counters(void) } } -static volatile int workload_exec_errno; +static volatile sig_atomic_t workload_exec_errno; /* * evlist__prepare_workload will send a SIGUSR1 @@ -1039,7 +1039,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv) evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv); } -static volatile int signr = -1; +static volatile sig_atomic_t signr = -1; static void skip_signal(int signo) { -- GitLab From 691768968f2a13eba8d52e8475dca7feb288d4f2 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:12 -0700 Subject: [PATCH 0351/1480] perf top: Use sig_atomic_t to avoid undefined behaviour in a signal handler Use sig_atomic_t for variables written/accessed in signal handlers. This is undefined behavior as per: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 4b3ff7687236e..bb5bd241246bc 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -87,8 +87,8 @@ #include #include -static volatile int done; -static volatile int resize; +static volatile sig_atomic_t done; +static volatile sig_atomic_t resize; #define HEADER_LINE_NR 5 -- GitLab From 92ea0720ba9cf7f09589a711245c2da145125958 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 24 Oct 2022 11:19:13 -0700 Subject: [PATCH 0352/1480] perf trace: Use sig_atomic_t to avoid undefined behaviour in a signal handler Use sig_atomic_t for variables written/accessed in signal handlers. This is undefined behavior as per: https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221024181913.630986-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d3c757769b965..72991528687ea 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1535,8 +1535,8 @@ static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) } static pid_t workload_pid = -1; -static bool done = false; -static bool interrupted = false; +static volatile sig_atomic_t done = false; +static volatile sig_atomic_t interrupted = false; static void sighandler_interrupt(int sig __maybe_unused) { -- GitLab From 7a09c1269702db8eccb6f718da2b00173e1e0034 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 2 Nov 2022 14:13:19 -0400 Subject: [PATCH 0353/1480] USB: core: Change configuration warnings to notices It has been pointed out that the kernel log messages warning about problems in USB configuration and related descriptors are vexing for users. The warning log level has a fairly high priority, but the user can do nothing to fix the underlying errors in the device's firmware. To reduce the amount of useless information produced by tools that filter high-priority log messages, we can change these warnings to notices, i.e., change dev_warn() to dev_notice(). The same holds for a few messages that currently use dev_err(): Unless they indicate a failure that might make a device unusable (such as inability to transfer a config descriptor), change them to dev_notice() also. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216630 Suggested-by: Artem S. Tashkinov Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/Y2KzPx0h6z1jXCuN@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 48bc8a4814ac4..725b8dbcfe5f0 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -61,7 +61,7 @@ static void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev, desc = (struct usb_ssp_isoc_ep_comp_descriptor *) buffer; if (desc->bDescriptorType != USB_DT_SSP_ISOC_ENDPOINT_COMP || size < USB_DT_SSP_ISOC_EP_COMP_SIZE) { - dev_warn(ddev, "Invalid SuperSpeedPlus isoc endpoint companion" + dev_notice(ddev, "Invalid SuperSpeedPlus isoc endpoint companion" "for config %d interface %d altsetting %d ep %d.\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); return; @@ -83,7 +83,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || size < USB_DT_SS_EP_COMP_SIZE) { - dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " + dev_notice(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); @@ -109,13 +109,13 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, /* Check the various values */ if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) { - dev_warn(ddev, "Control endpoint with bMaxBurst = %d in " + dev_notice(ddev, "Control endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bMaxBurst = 0; } else if (desc->bMaxBurst > 15) { - dev_warn(ddev, "Endpoint with bMaxBurst = %d in " + dev_notice(ddev, "Endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to 15\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); @@ -125,7 +125,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, if ((usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) && desc->bmAttributes != 0) { - dev_warn(ddev, "%s endpoint with bmAttributes = %d in " + dev_notice(ddev, "%s endpoint with bmAttributes = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", @@ -134,7 +134,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, ep->ss_ep_comp.bmAttributes = 0; } else if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) { - dev_warn(ddev, "Bulk endpoint with more than 65536 streams in " + dev_notice(ddev, "Bulk endpoint with more than 65536 streams in " "config %d interface %d altsetting %d ep %d: " "setting to max\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); @@ -142,7 +142,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, } else if (usb_endpoint_xfer_isoc(&ep->desc) && !USB_SS_SSP_ISOC_COMP(desc->bmAttributes) && USB_SS_MULT(desc->bmAttributes) > 3) { - dev_warn(ddev, "Isoc endpoint has Mult of %d in " + dev_notice(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", USB_SS_MULT(desc->bmAttributes), @@ -160,7 +160,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, else max_tx = 999999; if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { - dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " + dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", @@ -273,7 +273,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, else if (d->bLength >= USB_DT_ENDPOINT_SIZE) n = USB_DT_ENDPOINT_SIZE; else { - dev_warn(ddev, "config %d interface %d altsetting %d has an " + dev_notice(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint descriptor of length %d, skipping\n", cfgno, inum, asnum, d->bLength); goto skip_to_next_endpoint_or_interface_descriptor; @@ -281,7 +281,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, i = d->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK; if (i >= 16 || i == 0) { - dev_warn(ddev, "config %d interface %d altsetting %d has an " + dev_notice(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint with address 0x%X, skipping\n", cfgno, inum, asnum, d->bEndpointAddress); goto skip_to_next_endpoint_or_interface_descriptor; @@ -293,7 +293,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, /* Check for duplicate endpoint addresses */ if (config_endpoint_is_duplicate(config, inum, asnum, d)) { - dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", + dev_notice(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", cfgno, inum, asnum, d->bEndpointAddress); goto skip_to_next_endpoint_or_interface_descriptor; } @@ -301,7 +301,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, /* Ignore some endpoints */ if (udev->quirks & USB_QUIRK_ENDPOINT_IGNORE) { if (usb_endpoint_is_ignored(udev, ifp, d)) { - dev_warn(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n", + dev_notice(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n", cfgno, inum, asnum, d->bEndpointAddress); goto skip_to_next_endpoint_or_interface_descriptor; @@ -378,7 +378,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, } } if (d->bInterval < i || d->bInterval > j) { - dev_warn(ddev, "config %d interface %d altsetting %d " + dev_notice(ddev, "config %d interface %d altsetting %d " "endpoint 0x%X has an invalid bInterval %d, " "changing to %d\n", cfgno, inum, asnum, @@ -391,7 +391,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, * them usable, we will try treating them as Interrupt endpoints. */ if (udev->speed == USB_SPEED_LOW && usb_endpoint_xfer_bulk(d)) { - dev_warn(ddev, "config %d interface %d altsetting %d " + dev_notice(ddev, "config %d interface %d altsetting %d " "endpoint 0x%X is Bulk; changing to Interrupt\n", cfgno, inum, asnum, d->bEndpointAddress); endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; @@ -408,7 +408,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, */ maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize); if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { - dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", + dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", cfgno, inum, asnum, d->bEndpointAddress); } @@ -439,7 +439,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)]; if (maxp > j) { - dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", + dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", cfgno, inum, asnum, d->bEndpointAddress, maxp, j); maxp = j; endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp); @@ -452,7 +452,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, */ if (udev->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(d)) { if (maxp != 512) - dev_warn(ddev, "config %d interface %d altsetting %d " + dev_notice(ddev, "config %d interface %d altsetting %d " "bulk endpoint 0x%X has invalid maxpacket %d\n", cfgno, inum, asnum, d->bEndpointAddress, maxp); @@ -533,7 +533,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, i < intfc->num_altsetting; (++i, ++alt)) { if (alt->desc.bAlternateSetting == asnum) { - dev_warn(ddev, "Duplicate descriptor for config %d " + dev_notice(ddev, "Duplicate descriptor for config %d " "interface %d altsetting %d, skipping\n", cfgno, inum, asnum); goto skip_to_next_interface_descriptor; @@ -559,7 +559,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, num_ep = num_ep_orig = alt->desc.bNumEndpoints; alt->desc.bNumEndpoints = 0; /* Use as a counter */ if (num_ep > USB_MAXENDPOINTS) { - dev_warn(ddev, "too many endpoints for config %d interface %d " + dev_notice(ddev, "too many endpoints for config %d interface %d " "altsetting %d: %d, using maximum allowed: %d\n", cfgno, inum, asnum, num_ep, USB_MAXENDPOINTS); num_ep = USB_MAXENDPOINTS; @@ -590,7 +590,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, } if (n != num_ep_orig) - dev_warn(ddev, "config %d interface %d altsetting %d has %d " + dev_notice(ddev, "config %d interface %d altsetting %d has %d " "endpoint descriptor%s, different from the interface " "descriptor's value: %d\n", cfgno, inum, asnum, n, plural(n), num_ep_orig); @@ -625,7 +625,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, if (config->desc.bDescriptorType != USB_DT_CONFIG || config->desc.bLength < USB_DT_CONFIG_SIZE || config->desc.bLength > size) { - dev_err(ddev, "invalid descriptor for config index %d: " + dev_notice(ddev, "invalid descriptor for config index %d: " "type = 0x%X, length = %d\n", cfgidx, config->desc.bDescriptorType, config->desc.bLength); return -EINVAL; @@ -636,7 +636,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, size -= config->desc.bLength; if (nintf > USB_MAXINTERFACES) { - dev_warn(ddev, "config %d has too many interfaces: %d, " + dev_notice(ddev, "config %d has too many interfaces: %d, " "using maximum allowed: %d\n", cfgno, nintf, USB_MAXINTERFACES); nintf = USB_MAXINTERFACES; @@ -650,7 +650,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, (buffer2 += header->bLength, size2 -= header->bLength)) { if (size2 < sizeof(struct usb_descriptor_header)) { - dev_warn(ddev, "config %d descriptor has %d excess " + dev_notice(ddev, "config %d descriptor has %d excess " "byte%s, ignoring\n", cfgno, size2, plural(size2)); break; @@ -658,7 +658,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, header = (struct usb_descriptor_header *) buffer2; if ((header->bLength > size2) || (header->bLength < 2)) { - dev_warn(ddev, "config %d has an invalid descriptor " + dev_notice(ddev, "config %d has an invalid descriptor " "of length %d, skipping remainder of the config\n", cfgno, header->bLength); break; @@ -670,7 +670,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, d = (struct usb_interface_descriptor *) header; if (d->bLength < USB_DT_INTERFACE_SIZE) { - dev_warn(ddev, "config %d has an invalid " + dev_notice(ddev, "config %d has an invalid " "interface descriptor of length %d, " "skipping\n", cfgno, d->bLength); continue; @@ -680,7 +680,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, if ((dev->quirks & USB_QUIRK_HONOR_BNUMINTERFACES) && n >= nintf_orig) { - dev_warn(ddev, "config %d has more interface " + dev_notice(ddev, "config %d has more interface " "descriptors, than it declares in " "bNumInterfaces, ignoring interface " "number: %d\n", cfgno, inum); @@ -688,7 +688,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, } if (inum >= nintf_orig) - dev_warn(ddev, "config %d has an invalid " + dev_notice(ddev, "config %d has an invalid " "interface number: %d but max is %d\n", cfgno, inum, nintf_orig - 1); @@ -713,14 +713,14 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, d = (struct usb_interface_assoc_descriptor *)header; if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { - dev_warn(ddev, + dev_notice(ddev, "config %d has an invalid interface association descriptor of length %d, skipping\n", cfgno, d->bLength); continue; } if (iad_num == USB_MAXIADS) { - dev_warn(ddev, "found more Interface " + dev_notice(ddev, "found more Interface " "Association Descriptors " "than allocated for in " "configuration %d\n", cfgno); @@ -731,7 +731,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, } else if (header->bDescriptorType == USB_DT_DEVICE || header->bDescriptorType == USB_DT_CONFIG) - dev_warn(ddev, "config %d contains an unexpected " + dev_notice(ddev, "config %d contains an unexpected " "descriptor of type 0x%X, skipping\n", cfgno, header->bDescriptorType); @@ -740,11 +740,11 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0); if (n != nintf) - dev_warn(ddev, "config %d has %d interface%s, different from " + dev_notice(ddev, "config %d has %d interface%s, different from " "the descriptor's value: %d\n", cfgno, n, plural(n), nintf_orig); else if (n == 0) - dev_warn(ddev, "config %d has no interfaces?\n", cfgno); + dev_notice(ddev, "config %d has no interfaces?\n", cfgno); config->desc.bNumInterfaces = nintf = n; /* Check for missing interface numbers */ @@ -754,7 +754,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, break; } if (j >= nintf) - dev_warn(ddev, "config %d has no interface number " + dev_notice(ddev, "config %d has no interface number " "%d\n", cfgno, i); } @@ -762,7 +762,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, for (i = 0; i < nintf; ++i) { j = nalts[i]; if (j > USB_MAXALTSETTING) { - dev_warn(ddev, "too many alternate settings for " + dev_notice(ddev, "too many alternate settings for " "config %d interface %d: %d, " "using maximum allowed: %d\n", cfgno, inums[i], j, USB_MAXALTSETTING); @@ -811,7 +811,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, break; } if (n >= intfc->num_altsetting) - dev_warn(ddev, "config %d interface %d has no " + dev_notice(ddev, "config %d interface %d has no " "altsetting %d\n", cfgno, inums[i], j); } } @@ -868,7 +868,7 @@ int usb_get_configuration(struct usb_device *dev) int result; if (ncfg > USB_MAXCONFIG) { - dev_warn(ddev, "too many configurations: %d, " + dev_notice(ddev, "too many configurations: %d, " "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; } @@ -902,7 +902,7 @@ int usb_get_configuration(struct usb_device *dev) "descriptor/%s: %d\n", cfgno, "start", result); if (result != -EPIPE) goto err; - dev_err(ddev, "chopping to %d config(s)\n", cfgno); + dev_notice(ddev, "chopping to %d config(s)\n", cfgno); dev->descriptor.bNumConfigurations = cfgno; break; } else if (result < 4) { @@ -934,7 +934,7 @@ int usb_get_configuration(struct usb_device *dev) goto err; } if (result < length) { - dev_warn(ddev, "config index %d descriptor too short " + dev_notice(ddev, "config index %d descriptor too short " "(expected %i, got %i)\n", cfgno, length, result); length = result; } @@ -993,7 +993,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) /* Get BOS descriptor */ ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE); if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) { - dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n"); + dev_notice(ddev, "unable to get BOS descriptor or descriptor too short\n"); if (ret >= 0) ret = -ENOMSG; kfree(bos); @@ -1021,7 +1021,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) ret = usb_get_descriptor(dev, USB_DT_BOS, 0, buffer, total_len); if (ret < total_len) { - dev_err(ddev, "unable to get BOS descriptor set\n"); + dev_notice(ddev, "unable to get BOS descriptor set\n"); if (ret >= 0) ret = -ENOMSG; goto err; @@ -1046,7 +1046,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) } if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { - dev_warn(ddev, "descriptor type invalid, skip\n"); + dev_notice(ddev, "descriptor type invalid, skip\n"); continue; } -- GitLab From 372488c6936f4e7734e4ff5613c504affb49ff68 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 1 Nov 2022 22:13:55 +0100 Subject: [PATCH 0354/1480] usb: core: Use kstrtobool() instead of strtobool() strtobool() is the same as kstrtobool(). However, the latter is more used within the kernel. In order to remove strtobool() and slightly simplify kstrtox.h, switch to the other function name. While at it, include the corresponding header file () Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/f01ef2ddaf12a6412127611617786adc1234e0b4.1667336095.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/port.c | 3 ++- drivers/usb/core/sysfs.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 38c1a4f4fdeae..015204fc67a10 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -7,6 +7,7 @@ * Author: Lan Tianyu */ +#include #include #include #include @@ -63,7 +64,7 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr, bool disabled; int rc; - rc = strtobool(buf, &disabled); + rc = kstrtobool(buf, &disabled); if (rc) return rc; diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 631574718d8ac..8217032dfb85f 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -505,7 +506,7 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev, if (ret < 0) return -EINTR; - ret = strtobool(buf, &value); + ret = kstrtobool(buf, &value); if (!ret) { udev->usb2_hw_lpm_allowed = value; @@ -975,7 +976,7 @@ static ssize_t interface_authorized_default_store(struct device *dev, int rc = count; bool val; - if (strtobool(buf, &val) != 0) + if (kstrtobool(buf, &val) != 0) return -EINVAL; if (val) @@ -1176,7 +1177,7 @@ static ssize_t interface_authorized_store(struct device *dev, struct usb_interface *intf = to_usb_interface(dev); bool val; - if (strtobool(buf, &val) != 0) + if (kstrtobool(buf, &val) != 0) return -EINVAL; if (val) -- GitLab From a8bc8cc193c69e41df5e757d1a592346526e136d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 1 Nov 2022 22:13:56 +0100 Subject: [PATCH 0355/1480] usb: gadget: Use kstrtobool() instead of strtobool() strtobool() is the same as kstrtobool(). However, the latter is more used within the kernel. In order to remove strtobool() and slightly simplify kstrtox.h, switch to the other function name. While at it, include the corresponding header file () Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/09bc980d8432a4b5f7d88388ec0df5b085583139.1667336095.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/configfs.c | 3 ++- drivers/usb/gadget/function/f_mass_storage.c | 3 ++- drivers/usb/gadget/function/storage_common.c | 9 +++++---- drivers/usb/gadget/function/u_serial.c | 3 ++- drivers/usb/gadget/legacy/serial.c | 3 ++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 3a6b4926193ef..96121d1c8df4c 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -800,7 +801,7 @@ static ssize_t os_desc_use_store(struct config_item *item, const char *page, bool use; mutex_lock(&gi->lock); - ret = strtobool(page, &use); + ret = kstrtobool(page, &use); if (!ret) { gi->use_os_desc = use; ret = len; diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 3abf7f586e2af..3a30feb47073f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -176,6 +176,7 @@ #include #include #include +#include #include #include #include @@ -3387,7 +3388,7 @@ static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page, return -EBUSY; } - ret = strtobool(page, &stall); + ret = kstrtobool(page, &stall); if (!ret) { opts->common->can_stall = stall; ret = len; diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 208c6a92780ab..2a4163b0f6fe2 100644 --- a/drivers/usb/gadget/function/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "storage_common.h" @@ -396,7 +397,7 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, ssize_t rc; bool ro; - rc = strtobool(buf, &ro); + rc = kstrtobool(buf, &ro); if (rc) return rc; @@ -419,7 +420,7 @@ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) bool nofua; int ret; - ret = strtobool(buf, &nofua); + ret = kstrtobool(buf, &nofua); if (ret) return ret; @@ -470,7 +471,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, bool cdrom; int ret; - ret = strtobool(buf, &cdrom); + ret = kstrtobool(buf, &cdrom); if (ret) return ret; @@ -493,7 +494,7 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, bool removable; int ret; - ret = strtobool(buf, &removable); + ret = kstrtobool(buf, &removable); if (ret) return ret; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 7538279f98179..840626e064e13 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1070,7 +1071,7 @@ ssize_t gserial_set_console(unsigned char port_num, const char *page, size_t cou bool enable; int ret; - ret = strtobool(page, &enable); + ret = kstrtobool(page, &enable); if (ret) return ret; diff --git a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c index dcd3a6603d900..4974bee6049a6 100644 --- a/drivers/usb/gadget/legacy/serial.c +++ b/drivers/usb/gadget/legacy/serial.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -109,7 +110,7 @@ static int enable_set(const char *s, const struct kernel_param *kp) if (!s) /* called for no-arg enable == default */ return 0; - ret = strtobool(s, &do_enable); + ret = kstrtobool(s, &do_enable); if (ret || enable == do_enable) return ret; -- GitLab From 14e4b9f4289aed2c8d4858cd750748041b6c434f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 2 Nov 2022 21:54:31 -0700 Subject: [PATCH 0356/1480] perf trace: Raw augmented syscalls fix libbpf 1.0+ compatibility Don't use deprecated and now broken map style. Avoid use of tools/perf/include/bpf/bpf.h and use the more regular BPF headers. Committer notes: Add /usr/include to the include path so that bpf/bpf_helpers.h can be found, remove sys/socket.h, adding the sockaddr_storage definition, also remove stdbool.h, both were preventing building the augmented_raw_syscalls.c file with clang, revisit later. Testing it: Asking for syscalls that have string arguments: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,string --max-events 10 0.000 thermald/1144 openat(dfd: CWD, filename: "/sys/class/powercap/intel-rapl/intel-rapl:0/intel-rapl:0:2/energy_uj", flags: RDONLY) = 13 0.158 thermald/1144 openat(dfd: CWD, filename: "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj", flags: RDONLY) = 13 0.215 thermald/1144 openat(dfd: CWD, filename: "/sys/class/thermal/thermal_zone3/temp", flags: RDONLY) = 13 16.448 cgroupify/36478 openat(dfd: 4, filename: ".", flags: RDONLY|CLOEXEC|DIRECTORY|NONBLOCK) = 5 16.468 cgroupify/36478 newfstatat(dfd: 5, filename: "", statbuf: 0x7fffca5b4130, flag: 4096) = 0 16.473 systemd-oomd/972 openat(dfd: CWD, filename: "/proc/meminfo", flags: RDONLY|CLOEXEC) = 12 16.499 systemd-oomd/972 newfstatat(dfd: 12, filename: "", statbuf: 0x7ffd2bc73cc0, flag: 4096) = 0 16.516 abrt-dump-jour/1370 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 16.538 abrt-dump-jour/1370 newfstatat(dfd: 21, filename: "", statbuf: 0x7ffc651b8980, flag: 4096) = 0 16.540 abrt-dump-jour/1371 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 # Networking syscalls: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,sendto*,connect* --max-events 10 0.000 isc-net-0005/1206 connect(fd: 512, uservaddr: { .family: INET, port: 53, addr: 23.211.132.65 }, addrlen: 16) = 0 0.070 isc-net-0002/1203 connect(fd: 515, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.031 isc-net-0006/1207 connect(fd: 513, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.079 isc-net-0006/1207 sendto(fd: 3, buff: 0x7f73a40611b0, len: 106, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 106 0.180 isc-net-0006/1207 connect(fd: 519, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:1::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.211 isc-net-0006/1207 sendto(fd: 3, buff: 0x7f73a4061230, len: 106, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 106 0.298 isc-net-0006/1207 connect(fd: 515, uservaddr: { .family: INET, port: 53, addr: 96.7.49.67 }, addrlen: 16) = 0 0.109 isc-net-0004/1205 connect(fd: 518, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.164 isc-net-0002/1203 sendto(fd: 3, buff: 0x7f73ac064300, len: 107, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 107 0.247 isc-net-0002/1203 connect(fd: 522, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:1::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) # Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221103045437.163510-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 3 +- .../examples/bpf/augmented_raw_syscalls.c | 103 +++++++++++++++--- tools/perf/util/llvm-utils.c | 2 +- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index d3d3c13a9f25b..59420676dee8e 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -1239,7 +1239,8 @@ includedir = $(abspath $(prefix)/$(includedir_relative)) mandir = share/man infodir = share/info perfexecdir = libexec/perf-core -perf_include_dir = lib/perf/include +# FIXME: system's libbpf header directory, where we expect to find bpf/bpf_helpers.h, for instance +perf_include_dir = /usr/include perf_examples_dir = lib/perf/examples sharedir = $(prefix)/share template_dir = share/perf-core/templates diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index a262dcd020f49..926238efd7d8d 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -14,13 +14,21 @@ * code that will combine entry/exit in a strace like way. */ -#include +#include +#include #include -#include -#include + +// FIXME: These should come from system headers +typedef char bool; +typedef int pid_t; /* bpf-output associated map */ -bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__); +struct __augmented_syscalls__ { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); + __type(key, int); + __type(value, __u32); + __uint(max_entries, __NR_CPUS__); +} __augmented_syscalls__ SEC(".maps"); /* * string_args_len: one per syscall arg, 0 means not a string or don't copy it, @@ -29,24 +37,39 @@ bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__); */ struct syscall { bool enabled; - u16 string_args_len[6]; + __u16 string_args_len[6]; }; -bpf_map(syscalls, ARRAY, int, struct syscall, 512); +struct syscalls { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, int); + __type(value, struct syscall); + __uint(max_entries, 512); +} syscalls SEC(".maps"); /* * What to augment at entry? * * Pointer arg payloads (filenames, etc) passed from userspace to the kernel */ -bpf_map(syscalls_sys_enter, PROG_ARRAY, u32, u32, 512); +struct syscalls_sys_enter { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __type(key, __u32); + __type(value, __u32); + __uint(max_entries, 512); +} syscalls_sys_enter SEC(".maps"); /* * What to augment at exit? * * Pointer arg payloads returned from the kernel (struct stat, etc) to userspace. */ -bpf_map(syscalls_sys_exit, PROG_ARRAY, u32, u32, 512); +struct syscalls_sys_exit { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __type(key, __u32); + __type(value, __u32); + __uint(max_entries, 512); +} syscalls_sys_exit SEC(".maps"); struct syscall_enter_args { unsigned long long common_tp_fields; @@ -66,7 +89,38 @@ struct augmented_arg { char value[PATH_MAX]; }; -pid_filter(pids_filtered); +struct pids_filtered { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, pid_t); + __type(value, bool); + __uint(max_entries, 64); +} pids_filtered SEC(".maps"); + +/* + * Desired design of maximum size and alignment (see RFC2553) + */ +#define SS_MAXSIZE 128 /* Implementation specific max size */ + +typedef unsigned short sa_family_t; + +/* + * FIXME: Should come from system headers + * + * The definition uses anonymous union and struct in order to control the + * default alignment. + */ +struct sockaddr_storage { + union { + struct { + sa_family_t ss_family; /* address family */ + /* Following field(s) are implementation specific */ + char __data[SS_MAXSIZE - sizeof(unsigned short)]; + /* space to achieve desired size, */ + /* _SS_MAXSIZE value minus size of ss_family */ + }; + void *__align; /* implementation specific desired alignment */ + }; +}; struct augmented_args_payload { struct syscall_enter_args args; @@ -79,7 +133,12 @@ struct augmented_args_payload { }; // We need more tmp space than the BPF stack can give us -bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); +struct augmented_args_tmp { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, int); + __type(value, struct augmented_args_payload); + __uint(max_entries, 1); +} augmented_args_tmp SEC(".maps"); static inline struct augmented_args_payload *augmented_args_payload(void) { @@ -90,14 +149,14 @@ static inline struct augmented_args_payload *augmented_args_payload(void) static inline int augmented__output(void *ctx, struct augmented_args_payload *args, int len) { /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len); + return bpf_perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len); } static inline unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len) { unsigned int augmented_len = sizeof(*augmented_arg); - int string_len = probe_read_str(&augmented_arg->value, arg_len, arg); + int string_len = bpf_probe_read_str(&augmented_arg->value, arg_len, arg); augmented_arg->size = augmented_arg->err = 0; /* @@ -146,7 +205,7 @@ int sys_enter_connect(struct syscall_enter_args *args) if (socklen > sizeof(augmented_args->saddr)) socklen = sizeof(augmented_args->saddr); - probe_read(&augmented_args->saddr, socklen, sockaddr_arg); + bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg); return augmented__output(args, augmented_args, len + socklen); } @@ -165,7 +224,7 @@ int sys_enter_sendto(struct syscall_enter_args *args) if (socklen > sizeof(augmented_args->saddr)) socklen = sizeof(augmented_args->saddr); - probe_read(&augmented_args->saddr, socklen, sockaddr_arg); + bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg); return augmented__output(args, augmented_args, len + socklen); } @@ -234,6 +293,16 @@ int sys_enter_renameat(struct syscall_enter_args *args) return augmented__output(args, augmented_args, len); } +static pid_t getpid(void) +{ + return bpf_get_current_pid_tgid(); +} + +static bool pid_filter__has(struct pids_filtered *pids, pid_t pid) +{ + return bpf_map_lookup_elem(pids, &pid) != NULL; +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { @@ -257,7 +326,7 @@ int sys_enter(struct syscall_enter_args *args) if (augmented_args == NULL) return 1; - probe_read(&augmented_args->args, sizeof(augmented_args->args), args); + bpf_probe_read(&augmented_args->args, sizeof(augmented_args->args), args); /* * Jump to syscall specific augmenter, even if the default one, @@ -278,7 +347,7 @@ int sys_exit(struct syscall_exit_args *args) if (pid_filter__has(&pids_filtered, getpid())) return 0; - probe_read(&exit_args, sizeof(exit_args), args); + bpf_probe_read(&exit_args, sizeof(exit_args), args); /* * Jump to syscall specific return augmenter, even if the default one, * "!raw_syscalls:unaugmented" that will just return 1 to return the @@ -291,4 +360,4 @@ int sys_exit(struct syscall_exit_args *args) return 0; } -license(GPL); +char _license[] SEC("license") = "GPL"; diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 2dc7970074196..a5cac85783d87 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -495,7 +495,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, snprintf(linux_version_code_str, sizeof(linux_version_code_str), "0x%x", kernel_version); - if (asprintf(&perf_bpf_include_opts, "-I%s/bpf", perf_include_dir) < 0) + if (asprintf(&perf_bpf_include_opts, "-I%s/", perf_include_dir) < 0) goto errout; force_set_env("NR_CPUS", nr_cpus_avail_str); force_set_env("LINUX_VERSION_CODE", linux_version_code_str); -- GitLab From 514607e3c0f0e381aa4f6fe866b70b1fa9bfae74 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 2 Nov 2022 21:54:34 -0700 Subject: [PATCH 0357/1480] perf trace: hello fix libbpf 1.0+ compatibility Don't use deprecated and now broken map style. Avoid use of tools/perf/include/bpf/bpf.h and use the more regular BPF headers. Switch to raw_syscalls:sys_enter to avoid the evlist being empty and fixing generating output. Committer testing: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/hello.c --call-graph=dwarf --max-events 5 0.000 perf/206852 __bpf_stdout__(Hello, world) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __GI___sched_setaffinity_new (/usr/lib64/libc.so.6) 8.561 pipewire/2290 __bpf_stdout__(Hello, world) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __libc_read (/usr/lib64/libc.so.6) 8.571 pipewire/2290 __bpf_stdout__(Hello, world) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __GI___ioctl (/usr/lib64/libc.so.6) 8.586 pipewire/2290 __bpf_stdout__(Hello, world) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __GI___write (/usr/lib64/libc.so.6) 8.592 pipewire/2290 __bpf_stdout__(Hello, world) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) syscall_trace_enter.constprop.0 ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __timerfd_settime (/usr/lib64/libc.so.6) # Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221103045437.163510-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/hello.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/perf/examples/bpf/hello.c b/tools/perf/examples/bpf/hello.c index cf3c2fdc7f79c..e9080b0df1587 100644 --- a/tools/perf/examples/bpf/hello.c +++ b/tools/perf/examples/bpf/hello.c @@ -1,9 +1,27 @@ -#include +// SPDX-License-Identifier: GPL-2.0 +#include +#include -int syscall_enter(openat)(void *args) +struct __bpf_stdout__ { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); + __type(key, int); + __type(value, __u32); + __uint(max_entries, __NR_CPUS__); +} __bpf_stdout__ SEC(".maps"); + +#define puts(from) \ + ({ const int __len = sizeof(from); \ + char __from[sizeof(from)] = from; \ + bpf_perf_event_output(args, &__bpf_stdout__, BPF_F_CURRENT_CPU, \ + &__from, __len & (sizeof(from) - 1)); }) + +struct syscall_enter_args; + +SEC("raw_syscalls:sys_enter") +int sys_enter(struct syscall_enter_args *args) { puts("Hello, world\n"); return 0; } -license(GPL); +char _license[] SEC("license") = "GPL"; -- GitLab From baddab891a21e5870723d182020fec445b0874b3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 2 Nov 2022 21:54:35 -0700 Subject: [PATCH 0358/1480] perf trace: empty fix libbpf 1.0+ compatibility Avoid use of tools/perf/include/bpf/bpf.h and use the more regular BPF headers. Add raw_syscalls:sys_enter to avoid the evlist being empty. Committer testing: # time perf trace -e ~acme/git/perf/tools/perf/examples/bpf/empty.c sleep 5 real 0m5.697s user 0m0.217s sys 0m0.453s # I.e. it sets up everything successfully (use -v to see the details) and filters out all syscalls, then exits when the workload (sleep 5) finishes. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221103045437.163510-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/empty.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/perf/examples/bpf/empty.c b/tools/perf/examples/bpf/empty.c index 7d7fb0c9fe76b..3e296c0c53d7d 100644 --- a/tools/perf/examples/bpf/empty.c +++ b/tools/perf/examples/bpf/empty.c @@ -1,3 +1,12 @@ -#include +// SPDX-License-Identifier: GPL-2.0 +#include +#include -license(GPL); +struct syscall_enter_args; + +SEC("raw_syscalls:sys_enter") +int sys_enter(struct syscall_enter_args *args) +{ + return 0; +} +char _license[] SEC("license") = "GPL"; -- GitLab From 71811e8c77e974a0ab978c86a2b32b3f2c82f455 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 2 Nov 2022 21:54:36 -0700 Subject: [PATCH 0359/1480] perf trace: 5sec fix libbpf 1.0+ compatibility Avoid use of tools/perf/include/bpf/bpf.h and use the more regular BPF headers. Committer testing: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/5sec.c sleep 5 0.000 perf_bpf_probe:hrtimer_nanosleep(__probe_ip: -1474734416, rqtp: 5000000000) # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/5sec.c/max-stack=7/ sleep 5 0.000 perf_bpf_probe:hrtimer_nanosleep(__probe_ip: -1474734416, rqtp: 5000000000) hrtimer_nanosleep ([kernel.kallsyms]) common_nsleep ([kernel.kallsyms]) __x64_sys_clock_nanosleep ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64_after_hwframe ([kernel.kallsyms]) __GI___clock_nanosleep (/usr/lib64/libc.so.6) [0] ([unknown]) # Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221103045437.163510-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/5sec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/perf/examples/bpf/5sec.c b/tools/perf/examples/bpf/5sec.c index e6b6181c6dc63..3bd7fc17631f0 100644 --- a/tools/perf/examples/bpf/5sec.c +++ b/tools/perf/examples/bpf/5sec.c @@ -39,13 +39,15 @@ Copyright (C) 2018 Red Hat, Inc., Arnaldo Carvalho de Melo */ -#include +#include +#include #define NSEC_PER_SEC 1000000000L -int probe(hrtimer_nanosleep, rqtp)(void *ctx, int err, long long sec) +SEC("hrtimer_nanosleep=hrtimer_nanosleep rqtp") +int hrtimer_nanosleep(void *ctx, int err, long long sec) { return sec / NSEC_PER_SEC == 5ULL; } -license(GPL); +char _license[] SEC("license") = "GPL"; -- GitLab From cfddf0d4a5571bcc94760c27729a60daefda38bb Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 2 Nov 2022 21:54:37 -0700 Subject: [PATCH 0360/1480] perf bpf: Remove now unused BPF headers Example code has migrated to use standard BPF header files, remove unnecessary perf equivalents. Update install step to not try to copy these. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20221103045437.163510-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 5 -- tools/perf/include/bpf/bpf.h | 70 --------------------------- tools/perf/include/bpf/linux/socket.h | 24 --------- tools/perf/include/bpf/pid_filter.h | 21 -------- tools/perf/include/bpf/stdio.h | 16 ------ tools/perf/include/bpf/unistd.h | 10 ---- 6 files changed, 146 deletions(-) delete mode 100644 tools/perf/include/bpf/bpf.h delete mode 100644 tools/perf/include/bpf/linux/socket.h delete mode 100644 tools/perf/include/bpf/pid_filter.h delete mode 100644 tools/perf/include/bpf/stdio.h delete mode 100644 tools/perf/include/bpf/unistd.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a432e59afc42a..67819f9056116 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -960,11 +960,6 @@ endif $(call QUIET_INSTALL, libexec) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' ifndef NO_LIBBPF - $(call QUIET_INSTALL, bpf-headers) \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'; \ - $(INSTALL) include/bpf/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ - $(INSTALL) include/bpf/linux/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux' $(call QUIET_INSTALL, bpf-examples) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \ $(INSTALL) examples/bpf/*.c -m 644 -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h deleted file mode 100644 index b422aeef53396..0000000000000 --- a/tools/perf/include/bpf/bpf.h +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef _PERF_BPF_H -#define _PERF_BPF_H - -#include - -/* - * A helper structure used by eBPF C program to describe map attributes to - * elf_bpf loader, taken from tools/testing/selftests/bpf/bpf_helpers.h: - */ -struct bpf_map { - unsigned int type; - unsigned int key_size; - unsigned int value_size; - unsigned int max_entries; - unsigned int map_flags; - unsigned int inner_map_idx; - unsigned int numa_node; -}; - -#define bpf_map(name, _type, type_key, type_val, _max_entries) \ -struct bpf_map SEC("maps") name = { \ - .type = BPF_MAP_TYPE_##_type, \ - .key_size = sizeof(type_key), \ - .value_size = sizeof(type_val), \ - .max_entries = _max_entries, \ -}; \ -struct ____btf_map_##name { \ - type_key key; \ - type_val value; \ -}; \ -struct ____btf_map_##name __attribute__((section(".maps." #name), used)) \ - ____btf_map_##name = { } - -/* - * FIXME: this should receive .max_entries as a parameter, as careful - * tuning of these limits is needed to avoid hitting limits that - * prevents other BPF constructs, such as tracepoint handlers, - * to get installed, with cryptic messages from libbpf, etc. - * For the current need, 'perf trace --filter-pids', 64 should - * be good enough, but this surely needs to be revisited. - */ -#define pid_map(name, value_type) bpf_map(name, HASH, pid_t, value_type, 64) - -static int (*bpf_map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags) = (void *)BPF_FUNC_map_update_elem; -static void *(*bpf_map_lookup_elem)(struct bpf_map *map, void *key) = (void *)BPF_FUNC_map_lookup_elem; - -static void (*bpf_tail_call)(void *ctx, void *map, int index) = (void *)BPF_FUNC_tail_call; - -#define SEC(NAME) __attribute__((section(NAME), used)) - -#define probe(function, vars) \ - SEC(#function "=" #function " " #vars) function - -#define syscall_enter(name) \ - SEC("syscalls:sys_enter_" #name) syscall_enter_ ## name - -#define syscall_exit(name) \ - SEC("syscalls:sys_exit_" #name) syscall_exit_ ## name - -#define license(name) \ -char _license[] SEC("license") = #name; \ -int _version SEC("version") = LINUX_VERSION_CODE; - -static int (*probe_read)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read; -static int (*probe_read_str)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read_str; - -static int (*perf_event_output)(void *, struct bpf_map *, int, void *, unsigned long) = (void *)BPF_FUNC_perf_event_output; - -#endif /* _PERF_BPF_H */ diff --git a/tools/perf/include/bpf/linux/socket.h b/tools/perf/include/bpf/linux/socket.h deleted file mode 100644 index 7f844568dab87..0000000000000 --- a/tools/perf/include/bpf/linux/socket.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _UAPI_LINUX_SOCKET_H -#define _UAPI_LINUX_SOCKET_H - -/* - * Desired design of maximum size and alignment (see RFC2553) - */ -#define _K_SS_MAXSIZE 128 /* Implementation specific max size */ -#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *)) - /* Implementation specific desired alignment */ - -typedef unsigned short __kernel_sa_family_t; - -struct __kernel_sockaddr_storage { - __kernel_sa_family_t ss_family; /* address family */ - /* Following field(s) are implementation specific */ - char __data[_K_SS_MAXSIZE - sizeof(unsigned short)]; - /* space to achieve desired size, */ - /* _SS_MAXSIZE value minus size of ss_family */ -} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ - -#define sockaddr_storage __kernel_sockaddr_storage - -#endif /* _UAPI_LINUX_SOCKET_H */ diff --git a/tools/perf/include/bpf/pid_filter.h b/tools/perf/include/bpf/pid_filter.h deleted file mode 100644 index 6e61c4bdf5482..0000000000000 --- a/tools/perf/include/bpf/pid_filter.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 - -#ifndef _PERF_BPF_PID_FILTER_ -#define _PERF_BPF_PID_FILTER_ - -#include - -#define pid_filter(name) pid_map(name, bool) - -static int pid_filter__add(struct bpf_map *pids, pid_t pid) -{ - bool value = true; - return bpf_map_update_elem(pids, &pid, &value, BPF_NOEXIST); -} - -static bool pid_filter__has(struct bpf_map *pids, pid_t pid) -{ - return bpf_map_lookup_elem(pids, &pid) != NULL; -} - -#endif // _PERF_BPF_PID_FILTER_ diff --git a/tools/perf/include/bpf/stdio.h b/tools/perf/include/bpf/stdio.h deleted file mode 100644 index 316af5b2ff351..0000000000000 --- a/tools/perf/include/bpf/stdio.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include - -struct bpf_map SEC("maps") __bpf_stdout__ = { - .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, - .key_size = sizeof(int), - .value_size = sizeof(u32), - .max_entries = __NR_CPUS__, -}; - -#define puts(from) \ - ({ const int __len = sizeof(from); \ - char __from[__len] = from; \ - perf_event_output(args, &__bpf_stdout__, BPF_F_CURRENT_CPU, \ - &__from, __len & (sizeof(from) - 1)); }) diff --git a/tools/perf/include/bpf/unistd.h b/tools/perf/include/bpf/unistd.h deleted file mode 100644 index ca7877f9a976f..0000000000000 --- a/tools/perf/include/bpf/unistd.h +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 - -#include - -static int (*bpf_get_current_pid_tgid)(void) = (void *)BPF_FUNC_get_current_pid_tgid; - -static pid_t getpid(void) -{ - return bpf_get_current_pid_tgid(); -} -- GitLab From 3cd65616f607cd3769647e2e0490e4048c0f289e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Nov 2022 11:15:51 -0300 Subject: [PATCH 0361/1480] perf examples bpf: Remove augmented_syscalls.c, the raw_syscalls one should be used instead The attempt at using BPF to copy syscall pointer arguments to show them like strace does started with sys_{enter,exit}_SYSCALL_NAME tracepoints, in tools/perf/examples/bpf/augmented_syscalls.c, but then achieving this result using raw_syscalls:{enter,exit} and BPF tail calls was deemed more flexible. The 'perf trace' codebase was adapted to using it while trying to continue supporting the old style per-syscall tracepoints, which at some point became too unwieldly and now isn't working properly. So lets scale back and concentrate on the augmented_raw_syscalls.c model on the way to using BPF skeletons. For the same reason remove the etcsnoop.c example, that used the old style per-tp syscalls just for the 'open' and 'openat' syscalls, looking at the pathnames starting with "/etc/", we should be able to do this later using filters, after we move to BPF skels. The augmented_raw_syscalls.c one continues to work, now with libbpf 1.0, after Ian work on using the libbpf map style: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,open* --max-events 4 0.000 ping/194815 openat(dfd: CWD, filename: "/etc/hosts", flags: RDONLY|CLOEXEC) = 5 20.225 systemd-oomd/972 openat(dfd: CWD, filename: "/proc/meminfo", flags: RDONLY|CLOEXEC) = 12 20.285 abrt-dump-jour/1371 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 20.301 abrt-dump-jour/1370 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 # This is using this: # cat ~/.perfconfig [trace] show_zeros = yes show_duration = no no_inherit = yes args_alignment = 40 Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_syscalls.c | 169 ------------------- tools/perf/examples/bpf/etcsnoop.c | 76 --------- 2 files changed, 245 deletions(-) delete mode 100644 tools/perf/examples/bpf/augmented_syscalls.c delete mode 100644 tools/perf/examples/bpf/etcsnoop.c diff --git a/tools/perf/examples/bpf/augmented_syscalls.c b/tools/perf/examples/bpf/augmented_syscalls.c deleted file mode 100644 index 524fdb8534b3f..0000000000000 --- a/tools/perf/examples/bpf/augmented_syscalls.c +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Augment syscalls with the contents of the pointer arguments. - * - * Test it with: - * - * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null - * - * It'll catch some openat syscalls related to the dynamic linked and - * the last one should be the one for '/etc/passwd'. - * - * This matches what is marshalled into the raw_syscall:sys_enter payload - * expected by the 'perf trace' beautifiers, and can be used by them, that will - * check if perf_sample->raw_data is more than what is expected for each - * syscalls:sys_{enter,exit}_SYSCALL tracepoint, uing the extra data as the - * contents of pointer arguments. - */ - -#include -#include - -/* bpf-output associated map */ -bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__); - -struct syscall_exit_args { - unsigned long long common_tp_fields; - long syscall_nr; - long ret; -}; - -struct augmented_filename { - unsigned int size; - int reserved; - char value[256]; -}; - -#define augmented_filename_syscall(syscall) \ -struct augmented_enter_##syscall##_args { \ - struct syscall_enter_##syscall##_args args; \ - struct augmented_filename filename; \ -}; \ -int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \ -{ \ - struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; \ - unsigned int len = sizeof(augmented_args); \ - probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \ - augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, \ - sizeof(augmented_args.filename.value), \ - args->filename_ptr); \ - if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) { \ - len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size; \ - len &= sizeof(augmented_args.filename.value) - 1; \ - } \ - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \ - &augmented_args, len); \ -} \ -int syscall_exit(syscall)(struct syscall_exit_args *args) \ -{ \ - return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \ -} - -struct syscall_enter_openat_args { - unsigned long long common_tp_fields; - long syscall_nr; - long dfd; - char *filename_ptr; - long flags; - long mode; -}; - -augmented_filename_syscall(openat); - -struct syscall_enter_open_args { - unsigned long long common_tp_fields; - long syscall_nr; - char *filename_ptr; - long flags; - long mode; -}; - -augmented_filename_syscall(open); - -struct syscall_enter_inotify_add_watch_args { - unsigned long long common_tp_fields; - long syscall_nr; - long fd; - char *filename_ptr; - long mask; -}; - -augmented_filename_syscall(inotify_add_watch); - -struct statbuf; - -struct syscall_enter_newstat_args { - unsigned long long common_tp_fields; - long syscall_nr; - char *filename_ptr; - struct stat *statbuf; -}; - -augmented_filename_syscall(newstat); - -#ifndef _K_SS_MAXSIZE -#define _K_SS_MAXSIZE 128 -#endif - -#define augmented_sockaddr_syscall(syscall) \ -struct augmented_enter_##syscall##_args { \ - struct syscall_enter_##syscall##_args args; \ - struct sockaddr_storage addr; \ -}; \ -int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \ -{ \ - struct augmented_enter_##syscall##_args augmented_args; \ - unsigned long addrlen = sizeof(augmented_args.addr); \ - probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \ -/* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */ \ -/* if (addrlen > augmented_args.args.addrlen) */ \ -/* addrlen = augmented_args.args.addrlen; */ \ -/* */ \ - probe_read(&augmented_args.addr, addrlen, args->addr_ptr); \ - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \ - &augmented_args, \ - sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\ -} \ -int syscall_exit(syscall)(struct syscall_exit_args *args) \ -{ \ - return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \ -} - -struct sockaddr; - -struct syscall_enter_bind_args { - unsigned long long common_tp_fields; - long syscall_nr; - long fd; - struct sockaddr *addr_ptr; - unsigned long addrlen; -}; - -augmented_sockaddr_syscall(bind); - -struct syscall_enter_connect_args { - unsigned long long common_tp_fields; - long syscall_nr; - long fd; - struct sockaddr *addr_ptr; - unsigned long addrlen; -}; - -augmented_sockaddr_syscall(connect); - -struct syscall_enter_sendto_args { - unsigned long long common_tp_fields; - long syscall_nr; - long fd; - void *buff; - long len; - unsigned long flags; - struct sockaddr *addr_ptr; - long addr_len; -}; - -augmented_sockaddr_syscall(sendto); - -license(GPL); diff --git a/tools/perf/examples/bpf/etcsnoop.c b/tools/perf/examples/bpf/etcsnoop.c deleted file mode 100644 index e81b535346c0b..0000000000000 --- a/tools/perf/examples/bpf/etcsnoop.c +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Augment the filename syscalls with the contents of the filename pointer argument - * filtering only those that do not start with /etc/. - * - * Test it with: - * - * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null - * - * It'll catch some openat syscalls related to the dynamic linked and - * the last one should be the one for '/etc/passwd'. - * - * This matches what is marshalled into the raw_syscall:sys_enter payload - * expected by the 'perf trace' beautifiers, and can be used by them unmodified, - * which will be done as that feature is implemented in the next csets, for now - * it will appear in a dump done by the default tracepoint handler in 'perf trace', - * that uses bpf_output__fprintf() to just dump those contents, as done with - * the bpf-output event associated with the __bpf_output__ map declared in - * tools/perf/include/bpf/stdio.h. - */ - -#include - -/* bpf-output associated map */ -bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__); - -struct augmented_filename { - int size; - int reserved; - char value[64]; -}; - -#define augmented_filename_syscall_enter(syscall) \ -struct augmented_enter_##syscall##_args { \ - struct syscall_enter_##syscall##_args args; \ - struct augmented_filename filename; \ -}; \ -int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \ -{ \ - char etc[6] = "/etc/"; \ - struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; \ - probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \ - augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, \ - sizeof(augmented_args.filename.value), \ - args->filename_ptr); \ - if (__builtin_memcmp(augmented_args.filename.value, etc, 4) != 0) \ - return 0; \ - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \ - &augmented_args, \ - (sizeof(augmented_args) - sizeof(augmented_args.filename.value) + \ - augmented_args.filename.size)); \ -} - -struct syscall_enter_openat_args { - unsigned long long common_tp_fields; - long syscall_nr; - long dfd; - char *filename_ptr; - long flags; - long mode; -}; - -augmented_filename_syscall_enter(openat); - -struct syscall_enter_open_args { - unsigned long long common_tp_fields; - long syscall_nr; - char *filename_ptr; - long flags; - long mode; -}; - -augmented_filename_syscall_enter(open); - -license(GPL); -- GitLab From b018899e620b8ee4529f43bd02e9e8e43043e33e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Nov 2022 11:45:36 -0300 Subject: [PATCH 0362/1480] perf bpf: Rename perf_include_dir to libbpf_include_dir As this is where we expect to find bpf/bpf_helpers.h, etc. This needs more work to make it follow LIBBPF_DYNAMIC=1 usage, i.e. when not using the system libbpf it should use the headers in the in-kernel sources libbpf in tools/lib/bpf. We need to do that anyway to avoid this mixup system libbpf and in-kernel files, so we'll get this sorted out that way. And this also may become moot as we move to using BPF skels for this feature. Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 12 ++++++------ tools/perf/util/Build | 2 +- tools/perf/util/llvm-utils.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 59420676dee8e..a7f6c0669fae4 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -1216,7 +1216,7 @@ endif # Among the variables below, these: # perfexecdir -# perf_include_dir +# libbpf_include_dir # perf_examples_dir # template_dir # mandir @@ -1240,7 +1240,7 @@ mandir = share/man infodir = share/info perfexecdir = libexec/perf-core # FIXME: system's libbpf header directory, where we expect to find bpf/bpf_helpers.h, for instance -perf_include_dir = /usr/include +libbpf_include_dir = /usr/include perf_examples_dir = lib/perf/examples sharedir = $(prefix)/share template_dir = share/perf-core/templates @@ -1273,7 +1273,7 @@ includedir_SQ = $(subst ','\'',$(includedir)) mandir_SQ = $(subst ','\'',$(mandir)) infodir_SQ = $(subst ','\'',$(infodir)) perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) -perf_include_dir_SQ = $(subst ','\'',$(perf_include_dir)) +libbpf_include_dir_SQ = $(subst ','\'',$(libbpf_include_dir)) perf_examples_dir_SQ = $(subst ','\'',$(perf_examples_dir)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_SQ = $(subst ','\'',$(htmldir)) @@ -1285,13 +1285,13 @@ srcdir_SQ = $(subst ','\'',$(srcdir)) ifneq ($(filter /%,$(firstword $(perfexecdir))),) perfexec_instdir = $(perfexecdir) -perf_include_instdir = $(perf_include_dir) +perf_include_instdir = $(libbpf_include_dir) perf_examples_instdir = $(perf_examples_dir) STRACE_GROUPS_INSTDIR = $(STRACE_GROUPS_DIR) tip_instdir = $(tipdir) else perfexec_instdir = $(prefix)/$(perfexecdir) -perf_include_instdir = $(prefix)/$(perf_include_dir) +perf_include_instdir = $(prefix)/$(libbpf_include_dir) perf_examples_instdir = $(prefix)/$(perf_examples_dir) STRACE_GROUPS_INSTDIR = $(prefix)/$(STRACE_GROUPS_DIR) tip_instdir = $(prefix)/$(tipdir) @@ -1353,7 +1353,7 @@ $(call detected_var,ETC_PERFCONFIG_SQ) $(call detected_var,STRACE_GROUPS_DIR_SQ) $(call detected_var,prefix_SQ) $(call detected_var,perfexecdir_SQ) -$(call detected_var,perf_include_dir_SQ) +$(call detected_var,libbpf_include_dir_SQ) $(call detected_var,perf_examples_dir_SQ) $(call detected_var,tipdir_SQ) $(call detected_var,srcdir_SQ) diff --git a/tools/perf/util/Build b/tools/perf/util/Build index e315ecaec3233..47a7db3ad0a1f 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -220,7 +220,7 @@ perf-$(CONFIG_CXX) += c++/ perf-$(CONFIG_LIBPFM4) += pfm.o CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" -CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))" +CFLAGS_llvm-utils.o += -DLIBBPF_INCLUDE_DIR="BUILD_STR($(libbpf_include_dir_SQ))" # avoid compiler warnings in 32-bit mode CFLAGS_genelf_debug.o += -Wno-packed diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index a5cac85783d87..650ffe336f3aa 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -463,7 +463,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, char *pipe_template = NULL; const char *opts = llvm_param.opts; char *command_echo = NULL, *command_out; - char *perf_include_dir = system_path(PERF_INCLUDE_DIR); + char *libbpf_include_dir = system_path(LIBBPF_INCLUDE_DIR); if (path[0] != '-' && realpath(path, abspath) == NULL) { err = errno; @@ -495,7 +495,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, snprintf(linux_version_code_str, sizeof(linux_version_code_str), "0x%x", kernel_version); - if (asprintf(&perf_bpf_include_opts, "-I%s/", perf_include_dir) < 0) + if (asprintf(&perf_bpf_include_opts, "-I%s/", libbpf_include_dir) < 0) goto errout; force_set_env("NR_CPUS", nr_cpus_avail_str); force_set_env("LINUX_VERSION_CODE", linux_version_code_str); @@ -556,7 +556,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, free(kbuild_dir); free(kbuild_include_opts); free(perf_bpf_include_opts); - free(perf_include_dir); + free(libbpf_include_dir); if (!p_obj_buf) free(obj_buf); @@ -572,7 +572,7 @@ errout: free(kbuild_include_opts); free(obj_buf); free(perf_bpf_include_opts); - free(perf_include_dir); + free(libbpf_include_dir); free(pipe_template); if (p_obj_buf) *p_obj_buf = NULL; -- GitLab From 46af287cd5d7de316f1afd7966b27fc4369c6c35 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 4 Nov 2022 10:39:13 +0100 Subject: [PATCH 0363/1480] bus: mhi: host: pci_generic: add support for sc8280xp-crd SDX55 variant The SC8280XP Compute Reference Design (CRD) has an on-PCB SDX55 modem which uses MBIM. The exact channel configuration is not known but the Foxconn SDX55 configuration allows the modem to be used so reuse that one for now. Signed-off-by: Johan Hovold Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20221104093913.23347-1-johan+linaro@kernel.org [mani: modified the subject to format "bus: mhi: host"] Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/pci_generic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index c4259cb2d2899..fb3b050aed70e 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -544,6 +544,8 @@ static const struct mhi_pci_dev_info mhi_telit_fn990_info = { static const struct pci_device_id mhi_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c), + .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200), .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, -- GitLab From a5cfc9d65879c0d377f732531a2e80ee3a9eebbc Mon Sep 17 00:00:00 2001 From: Rajat Khandelwal Date: Tue, 1 Nov 2022 17:20:42 +0530 Subject: [PATCH 0364/1480] thunderbolt: Add wake on connect/disconnect on USB4 ports Wake on connect/disconnect is only supported while runtime suspend for now, which is obviously necessary. It is also not inherently desired for the system to wakeup on Thunderbolt/USB4 hot plug events. However, we can still make user in control of waking up the system in the events of hot plug/unplug. This patch adds 'wakeup' attribute under 'usb4_portX/power' sysfs attribute and only enables wakes on connect/disconnect to the respective port when 'wakeup' is set to 'enabled'. The attribute is set to 'disabled' by default. Signed-off-by: Rajat Khandelwal Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb_regs.h | 2 ++ drivers/thunderbolt/usb4.c | 33 +++++++++++++++++++++++++-------- drivers/thunderbolt/usb4_port.c | 3 +++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 86319dca0f8ca..3c38b0cb8f74e 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -361,6 +361,8 @@ struct tb_regs_port_header { #define PORT_CS_18_BE BIT(8) #define PORT_CS_18_TCM BIT(9) #define PORT_CS_18_CPS BIT(10) +#define PORT_CS_18_WOCS BIT(16) +#define PORT_CS_18_WODS BIT(17) #define PORT_CS_18_WOU4S BIT(18) #define PORT_CS_19 0x13 #define PORT_CS_19_PC BIT(3) diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index f986854aa207a..2ed50fcbcca7a 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -155,6 +155,8 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode, static void usb4_switch_check_wakes(struct tb_switch *sw) { + bool wakeup_usb4 = false; + struct usb4_port *usb4; struct tb_port *port; bool wakeup = false; u32 val; @@ -173,20 +175,31 @@ static void usb4_switch_check_wakes(struct tb_switch *sw) wakeup = val & (ROUTER_CS_6_WOPS | ROUTER_CS_6_WOUS); } - /* Check for any connected downstream ports for USB4 wake */ + /* + * Check for any downstream ports for USB4 wake, + * connection wake and disconnection wake. + */ tb_switch_for_each_port(sw, port) { - if (!tb_port_has_remote(port)) + if (!port->cap_usb4) continue; if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1)) break; - tb_port_dbg(port, "USB4 wake: %s\n", - (val & PORT_CS_18_WOU4S) ? "yes" : "no"); + tb_port_dbg(port, "USB4 wake: %s, connection wake: %s, disconnection wake: %s\n", + (val & PORT_CS_18_WOU4S) ? "yes" : "no", + (val & PORT_CS_18_WOCS) ? "yes" : "no", + (val & PORT_CS_18_WODS) ? "yes" : "no"); + + wakeup_usb4 = val & (PORT_CS_18_WOU4S | PORT_CS_18_WOCS | + PORT_CS_18_WODS); + + usb4 = port->usb4; + if (device_may_wakeup(&usb4->dev) && wakeup_usb4) + pm_wakeup_event(&usb4->dev, 0); - if (val & PORT_CS_18_WOU4S) - wakeup = true; + wakeup |= wakeup_usb4; } if (wakeup) @@ -366,6 +379,7 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw) */ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags) { + struct usb4_port *usb4; struct tb_port *port; u64 route = tb_route(sw); u32 val; @@ -395,10 +409,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags) val |= PORT_CS_19_WOU4; } else { bool configured = val & PORT_CS_19_PC; + usb4 = port->usb4; - if ((flags & TB_WAKE_ON_CONNECT) && !configured) + if (((flags & TB_WAKE_ON_CONNECT) | + device_may_wakeup(&usb4->dev)) && !configured) val |= PORT_CS_19_WOC; - if ((flags & TB_WAKE_ON_DISCONNECT) && configured) + if (((flags & TB_WAKE_ON_DISCONNECT) | + device_may_wakeup(&usb4->dev)) && configured) val |= PORT_CS_19_WOD; if ((flags & TB_WAKE_ON_USB4) && configured) val |= PORT_CS_19_WOU4; diff --git a/drivers/thunderbolt/usb4_port.c b/drivers/thunderbolt/usb4_port.c index 1a30c0a232865..e355bfd6343ff 100644 --- a/drivers/thunderbolt/usb4_port.c +++ b/drivers/thunderbolt/usb4_port.c @@ -284,6 +284,9 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port) } } + if (!tb_is_upstream_port(port)) + device_set_wakeup_capable(&usb4->dev, true); + pm_runtime_no_callbacks(&usb4->dev); pm_runtime_set_active(&usb4->dev); pm_runtime_enable(&usb4->dev); -- GitLab From d8425a8c3a8419dd505016951dd6393f21fb394e Mon Sep 17 00:00:00 2001 From: Song Fuchang Date: Mon, 7 Nov 2022 19:18:35 +0530 Subject: [PATCH 0365/1480] bus: mhi: host: pci_generic: Add HP variant of T99W175 The Foxconn T99W175 modem has an HP variant, which has the following output from lspci: 01:00.0 Wireless controller [0d40]: Device 03f0:0a6c It also has some HP-specific serial numbers on the metal case. It works well with this driver, so add support for this to the pci_generic driver. Signed-off-by: Song Fuchang Reviewed-by: Manivannan Sadhasivam [mani: manually applied the patch] Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/pci_generic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index fb3b050aed70e..b58a303678964 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -598,6 +598,9 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* MV32-WB (Cinterion) */ { PCI_DEVICE(0x1269, 0x00bb), .driver_data = (kernel_ulong_t) &mhi_mv32_info }, + /* T99W175 (sdx55), HP variant */ + { PCI_DEVICE(0x03f0, 0x0a6c), + .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, { } }; MODULE_DEVICE_TABLE(pci, mhi_pci_id_table); -- GitLab From a9cd6c6766857212894dd736d9f2bc29f1416f6a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Nov 2022 16:44:52 -0300 Subject: [PATCH 0366/1480] perf trace: Add BPF augmenter to perf_event_open()'s 'struct perf_event_attr' arg Using BPF for that, doing a cleverish reuse of perf_event_attr__fprintf(), that really needs to be turned into __snprintf(), etc. But since the plan is to go the BTF way probably use libbpf's btf_dump__dump_type_data(). Example: [root@quaco ~]# perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,perf_event_open --max-events 10 perf stat --quiet sleep 0.001 fg 0.000 perf_event_open(attr_uptr: { type: 1, size: 128, config: 0x1, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 3 0.067 perf_event_open(attr_uptr: { type: 1, size: 128, config: 0x3, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 4 0.120 perf_event_open(attr_uptr: { type: 1, size: 128, config: 0x4, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 5 0.172 perf_event_open(attr_uptr: { type: 1, size: 128, config: 0x2, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 7 0.190 perf_event_open(attr_uptr: { size: 128, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 8 0.199 perf_event_open(attr_uptr: { size: 128, config: 0x1, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 9 0.204 perf_event_open(attr_uptr: { size: 128, config: 0x4, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 10 0.210 perf_event_open(attr_uptr: { size: 128, config: 0x5, sample_type: IDENTIFIER, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 }, pid: 258859 (perf), cpu: -1, group_fd: -1, flags: FD_CLOEXEC) = 11 [root@quaco ~]# Suggested-by: Ian Rogers Tested-by: Ian Rogers Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lore.kernel.org/r/Y2V2Tpu+2vzJyon2@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 +- .../examples/bpf/augmented_raw_syscalls.c | 44 +++++++++++++++++++ tools/perf/trace/beauty/perf_event_open.c | 44 +++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 72991528687ea..5690c33c523b3 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1053,7 +1053,8 @@ static struct syscall_fmt syscall_fmts[] = { .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "perf_event_open", - .arg = { [2] = { .scnprintf = SCA_INT, /* cpu */ }, + .arg = { [0] = { .scnprintf = SCA_PERF_ATTR, /* attr */ }, + [2] = { .scnprintf = SCA_INT, /* cpu */ }, [3] = { .scnprintf = SCA_FD, /* group_fd */ }, [4] = { .scnprintf = SCA_PERF_FLAGS, /* flags */ }, }, }, { .name = "pipe2", diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 926238efd7d8d..0599823e8ae1b 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -129,6 +129,7 @@ struct augmented_args_payload { struct augmented_arg arg, arg2; }; struct sockaddr_storage saddr; + char __data[sizeof(struct augmented_arg)]; }; }; @@ -293,6 +294,49 @@ int sys_enter_renameat(struct syscall_enter_args *args) return augmented__output(args, augmented_args, len); } +#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */ + +// we need just the start, get the size to then copy it +struct perf_event_attr_size { + __u32 type; + /* + * Size of the attr structure, for fwd/bwd compat. + */ + __u32 size; +}; + +SEC("!syscalls:sys_enter_perf_event_open") +int sys_enter_perf_event_open(struct syscall_enter_args *args) +{ + struct augmented_args_payload *augmented_args = augmented_args_payload(); + const struct perf_event_attr_size *attr = (const struct perf_event_attr_size *)args->args[0], *attr_read; + unsigned int len = sizeof(augmented_args->args); + + if (augmented_args == NULL) + goto failure; + + if (bpf_probe_read(&augmented_args->__data, sizeof(*attr), attr) < 0) + goto failure; + + attr_read = (const struct perf_event_attr_size *)augmented_args->__data; + + __u32 size = attr_read->size; + + if (!size) + size = PERF_ATTR_SIZE_VER0; + + if (size > sizeof(augmented_args->__data)) + goto failure; + + // Now that we read attr->size and tested it against the size limits, read it completely + if (bpf_probe_read(&augmented_args->__data, size, attr) < 0) + goto failure; + + return augmented__output(args, augmented_args, len + size); +failure: + return 1; /* Failure: don't filter */ +} + static pid_t getpid(void) { return bpf_get_current_pid_tgid(); diff --git a/tools/perf/trace/beauty/perf_event_open.c b/tools/perf/trace/beauty/perf_event_open.c index 11d47dbe63bd1..01ee15fe9d0c7 100644 --- a/tools/perf/trace/beauty/perf_event_open.c +++ b/tools/perf/trace/beauty/perf_event_open.c @@ -44,3 +44,47 @@ static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size, } #define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags + +struct attr_fprintf_args { + size_t size, printed; + char *bf; + bool first; +}; + +static int attr__fprintf(FILE *fp __maybe_unused, const char *name, const char *val, void *priv) +{ + struct attr_fprintf_args *args = priv; + size_t printed = scnprintf(args->bf + args->printed , args->size - args->printed, "%s%s: %s", args->first ? "" : ", ", name, val); + + args->first = false; + args->printed += printed; + return printed; +} + +static size_t perf_event_attr___scnprintf(struct perf_event_attr *attr, char *bf, size_t size, bool show_zeros __maybe_unused) +{ + struct attr_fprintf_args args = { + .printed = scnprintf(bf, size, "{ "), + .size = size, + .first = true, + .bf = bf, + }; + + perf_event_attr__fprintf(stdout, attr, attr__fprintf, &args); + return args.printed + scnprintf(bf + args.printed, size - args.printed, " }"); +} + +static size_t syscall_arg__scnprintf_augmented_perf_event_attr(struct syscall_arg *arg, char *bf, size_t size) +{ + return perf_event_attr___scnprintf((void *)arg->augmented.args, bf, size, arg->trace->show_zeros); +} + +static size_t syscall_arg__scnprintf_perf_event_attr(char *bf, size_t size, struct syscall_arg *arg) +{ + if (arg->augmented.args) + return syscall_arg__scnprintf_augmented_perf_event_attr(arg, bf, size); + + return scnprintf(bf, size, "%#lx", arg->val); +} + +#define SCA_PERF_ATTR syscall_arg__scnprintf_perf_event_attr -- GitLab From 5c30f3e4a6e67c88c979ad30554bf4ef9b24fbd0 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Nov 2022 19:46:35 -0800 Subject: [PATCH 0367/1480] tty: Move TIOCSTI toggle variable before kerndoc The variable "tty_legacy_tiocsti" should be defined before the kerndoc for the tiocsti() function. The new variable was breaking the "htmldocs" build target: drivers/tty/tty_io.c:2271: warning: cannot understand function prototype: 'bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); ' Fixes: 83efeeeb3d04 ("tty: Allow TIOCSTI to be disabled") Reported-by: Stephen Rothwell Link: https://lore.kernel.org/lkml/20221107143434.66f7be35@canb.auug.org.au Cc: Jiri Slaby Signed-off-by: Kees Cook Acked-by: Randy Dunlap Link: https://lore.kernel.org/r/20221107034631.never.637-kees@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index a6a16cf986b72..24ebcb495145d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2255,6 +2255,7 @@ static int tty_fasync(int fd, struct file *filp, int on) return retval; } +static bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); /** * tiocsti - fake input character * @tty: tty to fake input into @@ -2268,7 +2269,6 @@ static int tty_fasync(int fd, struct file *filp, int on) * * Called functions take tty_ldiscs_lock * * current->signal->tty check is safe without locks */ -static bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); static int tiocsti(struct tty_struct *tty, char __user *p) { char ch, mbz = 0; -- GitLab From 96a53586ec095dcc426df5bc6a568108dcfa8a0a Mon Sep 17 00:00:00 2001 From: Tanjuate Brunostar Date: Thu, 3 Nov 2022 07:34:22 +0000 Subject: [PATCH 0368/1480] staging: vt6655: change 2 variable names wFB_Opt0 and wFB_Opt1 These variables are named using Hungarian notation, which is not used in the Linux kernel. Signed-off-by: Tanjuate Brunostar Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/Y2Nu/i957Ill7r+d@elroy-temp-vm.gaiao0uenmiufjlowqgp5yxwdh.gvxx.internal.cloudapp.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index baa3f6f1508f7..522d34ca9b0ff 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -59,12 +59,12 @@ static const unsigned short time_stamp_off[2][MAX_RATE] = { {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */ }; -static const unsigned short wFB_Opt0[2][5] = { +static const unsigned short fb_opt0[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */ {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */ }; -static const unsigned short wFB_Opt1[2][5] = { +static const unsigned short fb_opt1[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */ {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */ }; @@ -310,9 +310,9 @@ s_uGetDataDuration( wRate -= RATE_18M; if (byFBOption == AUTO_FB_0) - wRate = wFB_Opt0[FB_RATE0][wRate]; + wRate = fb_opt0[FB_RATE0][wRate]; else - wRate = wFB_Opt1[FB_RATE0][wRate]; + wRate = fb_opt1[FB_RATE0][wRate]; uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, len, wRate, bNeedAck); @@ -365,52 +365,52 @@ s_uGetRTSCTSDuration( case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; -- GitLab From f541335e830eb1abf3e4e260fcef98c429165aac Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 3 Nov 2022 04:06:59 +0530 Subject: [PATCH 0369/1480] staging: rtl8192e: Use min_t/max_t macros for variable comparison Simplify code by using min_t and max_t helper macros in place of lengthy if/else block oriented logical evaluation and value assignment. This issue is identified by coccicheck using the minmax.cocci file. Use the *_t variants of min/max macros to avoid compiler warnings about data typecast. Also, use u32 as type for min_t macro to avoid any truncation of data associated with enum constant HT_AGG_SIZE_32K. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/Y2LxC2kziM1TznhO@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_HTProc.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 62aa8e893c34c..ccb86660ab487 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -587,17 +587,12 @@ void HTOnAssocRsp(struct rtllib_device *ieee) else pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; } else { - if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) - pHTInfo->CurrentAMPDUFactor = - pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; + pHTInfo->CurrentAMPDUFactor = min_t(u32, pPeerHTCap->MaxRxAMPDUFactor, + HT_AGG_SIZE_32K); } } - if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) - pHTInfo->current_mpdu_density = pHTInfo->MPDU_Density; - else - pHTInfo->current_mpdu_density = pPeerHTCap->MPDUDensity; + pHTInfo->current_mpdu_density = max_t(u8, pHTInfo->MPDU_Density, + pPeerHTCap->MPDUDensity); if (pHTInfo->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K) { pHTInfo->bCurrentAMPDUEnable = false; pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; -- GitLab From 6c6ff293337b62c0c646d1ede2e9962f7501f9e4 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 3 Nov 2022 15:03:29 +0530 Subject: [PATCH 0370/1480] staging: rtl8723bs: Use min/max macros for variable comparison Simplify code by using min and max helper macros in place of lengthy if/else block oriented logical evaluation and value assignment. This issue is identified by coccicheck using the minmax.cocci file. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y2OK6fcIkH3S2/1f@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 12 ++++-------- drivers/staging/rtl8723bs/hal/odm_DIG.c | 5 +---- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index 18ba846c0b7b7..ba39c8b1a9ae1 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -986,15 +986,11 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_80211_var_ie *pIE) pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]); } else { /* modify from fw by Thomas 2010/11/17 */ - if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3)) - max_AMPDU_len = (pIE->data[i] & 0x3); - else - max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3); + max_AMPDU_len = min(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3, + pIE->data[i] & 0x3); - if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c)) - min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c); - else - min_MPDU_spacing = (pIE->data[i] & 0x1c); + min_MPDU_spacing = max(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c, + pIE->data[i] & 0x1c); pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; } diff --git a/drivers/staging/rtl8723bs/hal/odm_DIG.c b/drivers/staging/rtl8723bs/hal/odm_DIG.c index 07edf74ccfe52..97a51546463a6 100644 --- a/drivers/staging/rtl8723bs/hal/odm_DIG.c +++ b/drivers/staging/rtl8723bs/hal/odm_DIG.c @@ -598,10 +598,7 @@ void odm_DIGbyRSSI_LPS(void *pDM_VOID) /* Lower bound checking */ /* RSSI Lower bound check */ - if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) - RSSI_Lower = pDM_Odm->RSSI_Min-10; - else - RSSI_Lower = DM_DIG_MIN_NIC; + RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC); /* Upper and Lower Bound checking */ if (CurrentIGI > DM_DIG_MAX_NIC) -- GitLab From 84415762be0736efe7ed1b26d72a65ef9e0c6e58 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 3 Nov 2022 22:58:06 +0530 Subject: [PATCH 0371/1480] staging: r8188eu: remove unused ijk_matrix_regs_set implementation Instance IQKMatrixRegSetting of struct ijk_matrix_regs_set is initialised and its member variables are assigned values, but it is not used anywhere. Remove the structure and its unused implementation. Suggested-by: Dan Carpenter Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y2P6Jj+IcPss0wFd@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 8 -------- drivers/staging/r8188eu/include/odm.h | 7 ------- 2 files changed, 15 deletions(-) diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c index 622f95d3f2edf..26e710ef5134d 100644 --- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c @@ -882,14 +882,6 @@ void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery) if (RegE94 != 0) patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0)); -/* To Fix BSOD when final_candidate is 0xff */ -/* by sherry 20120321 */ - if (final_candidate < 4) { - for (i = 0; i < IQK_Matrix_REG_NUM; i++) - dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.Value[0][i] = result[final_candidate][i]; - dm_odm->RFCalibrateInfo.IQKMatrixRegSetting.bIQKDone = true; - } - _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); } diff --git a/drivers/staging/r8188eu/include/odm.h b/drivers/staging/r8188eu/include/odm.h index 89b01dd614ba9..8cea166b7b735 100644 --- a/drivers/staging/r8188eu/include/odm.h +++ b/drivers/staging/r8188eu/include/odm.h @@ -80,7 +80,6 @@ struct odm_rate_adapt { #define HP_THERMAL_NUM 8 #define AVG_THERMAL_NUM 8 -#define IQK_Matrix_REG_NUM 8 struct odm_phy_dbg_info { /* ODM Write,debug info */ @@ -164,11 +163,6 @@ struct odm_ra_info { u8 PTSmoothFactor; }; -struct ijk_matrix_regs_set { - bool bIQKDone; - s32 Value[1][IQK_Matrix_REG_NUM]; -}; - struct odm_rf_cal { /* for tx power tracking */ u32 RegA24; /* for TempCCK */ @@ -206,7 +200,6 @@ struct odm_rf_cal { u8 ThermalValue_HP[HP_THERMAL_NUM]; u8 ThermalValue_HP_index; - struct ijk_matrix_regs_set IQKMatrixRegSetting; u8 Delta_IQK; u8 Delta_LCK; -- GitLab From 1d6290639bfce477f71392392436d2aa830bca2e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 3 Nov 2022 13:06:19 +0000 Subject: [PATCH 0372/1480] staging: rtl8192e: rtl819x_HTProc: make arrays const and one static Make two dead-only arrays const. Make array EWC11NHTCap static const so it is not populated on the stack, makes the code smaller too. Signed-off-by: Colin Ian King Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/20221103130619.78413-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_HTProc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index ccb86660ab487..2c0a8d5c8f279 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -282,7 +282,7 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, memset(posHTCap, 0, *len); if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { - u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); pCapELE = (struct ht_capab_ele *)&posHTCap[4]; @@ -515,8 +515,8 @@ void HTOnAssocRsp(struct rtllib_device *ieee) u16 nMaxAMSDUSize = 0; u8 *pMcsFilter = NULL; - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; - static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; + static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; + static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 }; if (!pHTInfo->bCurrentHTSupport) { netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); -- GitLab From dcb18f5140ab7b4ea23417598c601b9468141d99 Mon Sep 17 00:00:00 2001 From: Phillip Potter Date: Thu, 3 Nov 2022 23:06:32 +0000 Subject: [PATCH 0373/1480] staging: r8188eu: change return type of rtw_set_802_11_disassociate to void Change return type of rtw_set_802_11_disassociate to void. This function always returns 'true' no matter what, so there is no need to return a value, and no need to check for it in the two call sites within rtw_wx_set_mlme. Also, as we are no longer using ret in rtw_wx_set_mlme except as the return value, just remove it and return 0 directly. Suggested-by: Michael Straube Signed-off-by: Phillip Potter Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221103230632.6946-1-phil@philpotter.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_ioctl_set.c | 4 +--- drivers/staging/r8188eu/include/rtw_ioctl_set.h | 2 +- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 9 +++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c index 7864318266598..785c0dba508fa 100644 --- a/drivers/staging/r8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/r8188eu/core/rtw_ioctl_set.c @@ -314,7 +314,7 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, return true; } -u8 rtw_set_802_11_disassociate(struct adapter *padapter) +void rtw_set_802_11_disassociate(struct adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -328,8 +328,6 @@ u8 rtw_set_802_11_disassociate(struct adapter *padapter) } spin_unlock_bh(&pmlmepriv->lock); - - return true; } u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_set.h b/drivers/staging/r8188eu/include/rtw_ioctl_set.h index abe460d6504d0..c3eb2479f27b4 100644 --- a/drivers/staging/r8188eu/include/rtw_ioctl_set.h +++ b/drivers/staging/r8188eu/include/rtw_ioctl_set.h @@ -12,7 +12,7 @@ u8 rtw_set_802_11_authentication_mode(struct adapter *adapt, enum ndis_802_11_auth_mode authmode); u8 rtw_set_802_11_bssid(struct adapter *adapter, u8 *bssid); u8 rtw_set_802_11_add_wep(struct adapter *adapter, struct ndis_802_11_wep *wep); -u8 rtw_set_802_11_disassociate(struct adapter *adapter); +void rtw_set_802_11_disassociate(struct adapter *adapter); u8 rtw_set_802_11_bssid_list_scan(struct adapter *adapter, struct ndis_802_11_ssid *pssid, int ssid_max_num); diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c index dda48a2a6d0c1..8e9b7b0664bc3 100644 --- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -1011,7 +1011,6 @@ static int rtw_wx_set_mlme(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - int ret = 0; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *)extra; @@ -1020,17 +1019,15 @@ static int rtw_wx_set_mlme(struct net_device *dev, switch (mlme->cmd) { case IW_MLME_DEAUTH: - if (!rtw_set_802_11_disassociate(padapter)) - ret = -1; + rtw_set_802_11_disassociate(padapter); break; case IW_MLME_DISASSOC: - if (!rtw_set_802_11_disassociate(padapter)) - ret = -1; + rtw_set_802_11_disassociate(padapter); break; default: return -EOPNOTSUPP; } - return ret; + return 0; } static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, -- GitLab From bb5b5e2104ca000888df89e35ff42c677df22671 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 3 Nov 2022 20:27:50 -0500 Subject: [PATCH 0374/1480] staging: rtl8192e: Fix divide fault when calculating beacon age When the configuration parameter CONFIG_HZ is less that 100, the compiler generates an error as follows: ../drivers/staging/rtl8192e/rtllib_wx.c: In function 'rtl819x_translate_scan': ../drivers/staging/rtl8192e/rtllib_wx.c:220:57: warning: division by zero [-Wdiv-by-zero] 220 | (jiffies - network->last_scanned) / (HZ / 100)); | ^ In file included from ../include/linux/skbuff.h:45, from ../include/linux/if_ether.h:19, from ../include/linux/etherdevice.h:20, from ../drivers/staging/rtl8192e/rtllib_wx.c:18: ../drivers/staging/rtl8192e/rtllib_wx.c: In function 'rtllib_wx_get_scan': ../drivers/staging/rtl8192e/rtllib_wx.c:261:70: warning: division by zero [-Wdiv-by-zero] 261 | (jiffies - network->last_scanned) / | In fact, is HZ is not a multiple of 100, the calculation will be wrong, but it will compile correctly. The fix is to get rid of the (HZ / 100) portion. To decrease any round-off errors, the compiler is forced to perform the 100 * jiffies-difference before dividing by HZ. This patch is only compile tested. Reported-by: Randy Dunlap Acked-by: Randy Dunlap # build-tested Signed-off-by: Larry Finger Tested-by: Philipp Hortmann Link: https://lore.kernel.org/r/20221104012750.2076-1-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_wx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index da2c41c9b92f1..217426ee2e92a 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -217,7 +217,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, p = custom; p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Last beacon: %lums ago", - (jiffies - network->last_scanned) / (HZ / 100)); + (100 * (jiffies - network->last_scanned)) / HZ); iwe.u.data.length = p - custom; if (iwe.u.data.length) start = iwe_stream_add_point_rsl(info, start, stop, @@ -258,8 +258,8 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee, escape_essid(network->ssid, network->ssid_len), network->bssid, - (jiffies - network->last_scanned) / - (HZ / 100)); + (100 * (jiffies - network->last_scanned)) / + HZ); } spin_unlock_irqrestore(&ieee->lock, flags); -- GitLab From 11454ddeb2f68a1c03b90f0c2bba18570f1a3019 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sat, 5 Nov 2022 16:45:52 +0530 Subject: [PATCH 0375/1480] staging: rtl8723bs: replace underutilized struct by array variable For structure iqk_matrix_regs_setting, only the "Value" member variable is utilized whereas the other struct members are only declared but not utilised. Replace the struct declaration and implementation by an equivalent variable similar to the only used struct member variable. While in there, update the macro mixed case names to uppercase style. The resultant code is simpler and is easy to maintain. Suggested-by: Dan Carpenter Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y2ZF6O1KU3zZ6r3C@qemulion Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723bs/hal/HalPhyRf_8723B.c | 21 +++++++++---------- drivers/staging/rtl8723bs/hal/odm.h | 12 +++-------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c index a52748f7b56eb..22e33b97800d1 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c @@ -244,8 +244,8 @@ void ODM_TxPwrTrackSetPwr_8723B( Final_CCK_Swing_Index = 0; setIqkMatrix_8723B(pDM_Odm, Final_OFDM_Swing_Index, RFPath, - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0], + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]); setCCKFilterCoefficient(pDM_Odm, Final_CCK_Swing_Index); @@ -257,8 +257,8 @@ void ODM_TxPwrTrackSetPwr_8723B( pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - PwrTrackingLimit_OFDM; setIqkMatrix_8723B(pDM_Odm, PwrTrackingLimit_OFDM, RFPath, - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0], + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]); pDM_Odm->Modify_TxAGC_Flag_PathA = true; PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM); @@ -267,16 +267,16 @@ void ODM_TxPwrTrackSetPwr_8723B( pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index; setIqkMatrix_8723B(pDM_Odm, 0, RFPath, - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0], + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]); pDM_Odm->Modify_TxAGC_Flag_PathA = true; PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, OFDM); PHY_SetTxPowerIndexByRateSection(Adapter, RFPath, pHalData->CurrentChannel, HT_MCS0_MCS7); } else { setIqkMatrix_8723B(pDM_Odm, Final_OFDM_Swing_Index, RFPath, - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0], + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]); if (pDM_Odm->Modify_TxAGC_Flag_PathA) { /* If TxAGC has changed, reset TxAGC again */ pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = 0; @@ -1759,9 +1759,8 @@ void PHY_IQCalibrate_8723B( /* To Fix BSOD when final_candidate is 0xff */ /* by sherry 20120321 */ if (final_candidate < 4) { - for (i = 0; i < IQK_Matrix_REG_NUM; i++) - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i]; - pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true; + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[0][i] = result[final_candidate][i]; } _PHY_SaveADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); diff --git a/drivers/staging/rtl8723bs/hal/odm.h b/drivers/staging/rtl8723bs/hal/odm.h index fe9782d2d4fd2..f5c804a1b9d55 100644 --- a/drivers/staging/rtl8723bs/hal/odm.h +++ b/drivers/staging/rtl8723bs/hal/odm.h @@ -193,8 +193,8 @@ struct odm_rate_adaptive { #define HP_THERMAL_NUM 8 #define AVG_THERMAL_NUM 8 -#define IQK_Matrix_REG_NUM 8 -#define IQK_Matrix_Settings_NUM 14 /* Channels_2_4G_NUM */ +#define IQK_MATRIX_REG_NUM 8 +#define IQK_MATRIX_SETTINGS_NUM 14 /* Channels_2_4G_NUM */ #define DM_Type_ByFW 0 #define DM_Type_ByDriver 1 @@ -479,12 +479,6 @@ enum odm_type_alna_e { /* tag_ODM_TYPE_ALNA_Definition */ TYPE_ALNA3 = BIT(3)|BIT(2)|BIT(1)|BIT(0) }; -struct iqk_matrix_regs_setting { /* _IQK_MATRIX_REGS_SETTING */ - bool bIQKDone; - s32 Value[3][IQK_Matrix_REG_NUM]; - bool bBWIqkResultSaved[3]; -}; - /* Remove PATHDIV_PARA struct to odm_PathDiv.h */ struct odm_rf_cal_t { /* ODM_RF_Calibration_Structure */ @@ -530,7 +524,7 @@ struct odm_rf_cal_t { /* ODM_RF_Calibration_Structure */ u8 ThermalValue_HP[HP_THERMAL_NUM]; u8 ThermalValue_HP_index; - struct iqk_matrix_regs_setting IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; + s32 iqk_matrix_regs_setting_value[IQK_MATRIX_SETTINGS_NUM][IQK_MATRIX_REG_NUM]; bool bNeedIQK; bool bIQKInProgress; u8 Delta_IQK; -- GitLab From f6f213ba49107be5ea2e4aad9ffea9e844c58a2a Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sun, 6 Nov 2022 15:51:58 +0530 Subject: [PATCH 0376/1480] staging: emxx_udc: use min helper macro for variable comparison Simplify code by using min helper macros in place of lengthy if/else block oriented logical evaluation and value assignment. This issue is identified by coccicheck using the minmax.cocci file. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y2eKxoUWtbPY/88b@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index b6abd3770e81c..b4e19174bef2e 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -1004,10 +1004,7 @@ static int _nbu2ss_in_dma(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep, /* MAX Packet Size */ mpkt = _nbu2ss_readl(&preg->EP_REGS[num].EP_PCKT_ADRS) & EPN_MPKT; - if ((DMA_MAX_COUNT * mpkt) < length) - i_write_length = DMA_MAX_COUNT * mpkt; - else - i_write_length = length; + i_write_length = min(DMA_MAX_COUNT * mpkt, length); /*------------------------------------------------------------*/ /* Number of transmission packets */ -- GitLab From 38aa1741c3b373fb021b2d2ab1f5f07bec03fbd3 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 3 Nov 2022 02:23:18 +0530 Subject: [PATCH 0377/1480] staging: r8188eu: remove unused struct declarations Some structures are only declared but have not been used anywhere in the code. Remove such unused structs. Issue identified as part of coccicheck report driven code investigation. Suggested-by: Pavel Skripkin Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/Y2LYvhr74ng+xFbz@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/wlan_bssdef.h | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/staging/r8188eu/include/wlan_bssdef.h b/drivers/staging/r8188eu/include/wlan_bssdef.h index 831c465df5001..ffeafa19ef264 100644 --- a/drivers/staging/r8188eu/include/wlan_bssdef.h +++ b/drivers/staging/r8188eu/include/wlan_bssdef.h @@ -177,20 +177,6 @@ struct ndis_802_11_status_ind { /* MIC check time, 60 seconds. */ #define MIC_CHECK_TIME 60000000 -struct ndis_802_11_auth_evt { - struct ndis_802_11_status_ind Status; - struct ndis_802_11_auth_req Request[1]; -}; - -struct ndis_802_11_test { - u32 Length; - u32 Type; - union { - struct ndis_802_11_auth_evt AuthenticationEvent; - NDIS_802_11_RSSI RssiTrigger; - } tt; -}; - #ifndef Ndis802_11APMode #define Ndis802_11APMode (Ndis802_11InfrastructureMax+1) #endif @@ -279,34 +265,6 @@ enum UAPSD_MAX_SP { #define NUM_PRE_AUTH_KEY 16 #define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY -/* -* WPA2 -*/ - -struct pmkid_candidate { - unsigned char BSSID[ETH_ALEN]; - u32 Flags; -}; - -struct ndis_802_11_pmkid_list { - u32 Version; /* Version of the structure */ - u32 NumCandidates; /* No. of pmkid candidates */ - struct pmkid_candidate CandidateList[1]; -}; - -struct ndis_802_11_auth_encrypt { - enum ndis_802_11_auth_mode AuthModeSupported; - enum ndis_802_11_wep_status EncryptStatusSupported; -}; - -struct ndis_802_11_cap { - u32 Length; - u32 Version; - u32 NoOfPMKIDs; - u32 NoOfAuthEncryptPairsSupported; - struct ndis_802_11_auth_encrypt AuthenticationEncryptionSupported[1]; -}; - u8 key_2char2num(u8 hch, u8 lch); u8 key_char2num(u8 ch); u8 str_2char2num(u8 hch, u8 lch); -- GitLab From 30534c72bac17a6c160017229ba38fcd0cc21ac6 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sat, 5 Nov 2022 10:39:16 +0100 Subject: [PATCH 0378/1480] staging: r8188eu: convert three functions to bool The functions is_client_associated_to_ap() is_client_associated_to_ibss() is_IBSS_empty() return boolean values. Convert their return type to bool and replace _FAIL, which is defined as 0, with false. Another step to get rid of _SUCCESS / _FAIL. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221105093916.8255-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_wlan_util.c | 18 +++++++++--------- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c index e50631848cab6..c95438a12b598 100644 --- a/drivers/staging/r8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c @@ -331,35 +331,35 @@ u16 get_beacon_interval(struct wlan_bssid_ex *bss) return le16_to_cpu(val); } -int is_client_associated_to_ap(struct adapter *padapter) +bool is_client_associated_to_ap(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; if (!padapter) - return _FAIL; + return false; pmlmeext = &padapter->mlmeextpriv; pmlmeinfo = &pmlmeext->mlmext_info; if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)) return true; - else - return _FAIL; + + return false; } -int is_client_associated_to_ibss(struct adapter *padapter) +bool is_client_associated_to_ibss(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) return true; - else - return _FAIL; + + return false; } -int is_IBSS_empty(struct adapter *padapter) +bool is_IBSS_empty(struct adapter *padapter) { unsigned int i; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -367,7 +367,7 @@ int is_IBSS_empty(struct adapter *padapter) for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { if (pmlmeinfo->FW_sta_info[i].status == 1) - return _FAIL; + return false; } return true; } diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index e234a3b9af6fa..7652e72a03f4c 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -432,9 +432,9 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork); u16 get_beacon_interval(struct wlan_bssid_ex *bss); -int is_client_associated_to_ap(struct adapter *padapter); -int is_client_associated_to_ibss(struct adapter *padapter); -int is_IBSS_empty(struct adapter *padapter); +bool is_client_associated_to_ap(struct adapter *padapter); +bool is_client_associated_to_ibss(struct adapter *padapter); +bool is_IBSS_empty(struct adapter *padapter); unsigned char check_assoc_AP(u8 *pframe, uint len); -- GitLab From cc027b3e4087e27d23e5c1d778e802c35f4c987d Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:53 +0100 Subject: [PATCH 0379/1480] staging: r8188eu: don't store addba request There's no need to store an incoming addba request in struct mlme_ext_info. We only need the addba request to copy some of its fields into our addba response. It's simpler to pass the incoming request's management frame to issue_action_BA as an additional parameter. issue_action_BA can then extract the required fields. If issue_action_BA prepares a request rather than a response, the caller sets the parameter for the incoming request to NULL. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 25 ++++++++----------- .../staging/r8188eu/include/rtw_mlme_ext.h | 4 +-- drivers/staging/r8188eu/include/wifi.h | 8 ------ 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 6679d4037d6bd..324757699716a 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1486,11 +1486,9 @@ static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_fra struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; struct sta_info *psta = NULL; struct recv_reorder_ctrl *preorder_ctrl; - unsigned char *frame_body; unsigned short tid; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - u8 *pframe = precv_frame->rx_data; struct sta_priv *pstapriv = &padapter->stapriv; if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) @@ -1501,23 +1499,19 @@ static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_fra if (!psta) return; - frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); - if (!pmlmeinfo->HT_enable) return; /* All union members start with an action code, it's ok to use addba_req. */ switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: - memcpy(&pmlmeinfo->ADDBA_req, &frame_body[2], sizeof(struct ADDBA_request)); tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_req.capab), IEEE80211_ADDBA_PARAM_TID_MASK); preorder_ctrl = &psta->recvreorder_ctrl[tid]; preorder_ctrl->indicate_seq = 0xffff; preorder_ctrl->enable = pmlmeinfo->bAcceptAddbaReq; - issue_action_BA(padapter, mgmt->sa, WLAN_ACTION_ADDBA_RESP, pmlmeinfo->bAcceptAddbaReq ? - WLAN_STATUS_SUCCESS : WLAN_STATUS_REQUEST_DECLINED); + WLAN_STATUS_SUCCESS : WLAN_STATUS_REQUEST_DECLINED, mgmt); break; case WLAN_ACTION_ADDBA_RESP: tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_resp.capab), @@ -5377,7 +5371,8 @@ exit: return ret; } -void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, u16 status) +void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, + u16 status, struct ieee80211_mgmt *mgmt_req) { u16 start_seq; u16 BA_starting_seqctrl = 0; @@ -5446,13 +5441,13 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, break; case WLAN_ACTION_ADDBA_RESP: mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; - mgmt->u.action.u.addba_resp.dialog_token = pmlmeinfo->ADDBA_req.dialog_token; + mgmt->u.action.u.addba_resp.dialog_token = mgmt_req->u.action.u.addba_req.dialog_token; mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); - capab = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f; + capab = le16_to_cpu(mgmt_req->u.action.u.addba_req.capab) & 0x3f; capab |= u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); capab |= u16_encode_bits(pregpriv->ampdu_amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); - mgmt->u.action.u.addba_resp.timeout = pmlmeinfo->ADDBA_req.BA_timeout_value; + mgmt->u.action.u.addba_resp.timeout = mgmt_req->u.action.u.addba_req.timeout; pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.addba_resp.timeout); break; case WLAN_ACTION_DELBA: @@ -5620,7 +5615,8 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) if (initiator == 0) { /* recipient */ for (tid = 0; tid < MAXTID; tid++) { if (psta->recvreorder_ctrl[tid].enable) { - issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); + issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, + (((tid << 1) | initiator) & 0x1F), NULL); psta->recvreorder_ctrl[tid].enable = false; psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; } @@ -5628,7 +5624,8 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) } else if (initiator == 1) { /* originator */ for (tid = 0; tid < MAXTID; tid++) { if (psta->htpriv.agg_enable_bitmap & BIT(tid)) { - issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); + issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, + (((tid << 1) | initiator) & 0x1F), NULL); psta->htpriv.agg_enable_bitmap &= ~BIT(tid); psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); } @@ -7683,7 +7680,7 @@ u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { - issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); + issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid, NULL); _set_timer(&psta->addba_retry_timer, ADDBA_TO); } else { psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 7652e72a03f4c..9c0af4704607b 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -285,7 +285,6 @@ struct mlme_ext_info { u8 bwmode_updated; u8 hidden_ssid_mode; - struct ADDBA_request ADDBA_req; struct WMM_para_element WMM_param; struct HT_caps_element HT_caps; struct HT_info_element HT_info; @@ -523,7 +522,8 @@ int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason); int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt, int wait_ms); -void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, u16 status); +void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, + u16 status, struct ieee80211_mgmt *mgmt_req); unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr); unsigned int send_beacon(struct adapter *padapter); bool get_beacon_valid_bit(struct adapter *adapter); diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index 92a584a8b6c07..2381c519ceafe 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -430,14 +430,6 @@ struct WMM_para_element { struct AC_param ac_param[4]; } __packed; -struct ADDBA_request { - unsigned char action_code; - unsigned char dialog_token; - __le16 BA_para_set; - __le16 BA_timeout_value; - __le16 BA_starting_seqctrl; -} __packed; - #define MAX_AMPDU_FACTOR_64K 3 /* Spatial Multiplexing Power Save Modes */ -- GitLab From 4142c442f2597c806d6fdcaf253aa38bfea4233c Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:54 +0100 Subject: [PATCH 0380/1480] staging: r8188eu: remove some obsolete comments Remove obsolete comments in validate_recv_data_frame. There is no prxcmd variable (any more?). Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_recv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index 94f85cd7038dc..cb0f35d7ab98d 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -1065,8 +1065,6 @@ static int validate_recv_data_frame(struct adapter *adapter, if (!psta) return _FAIL; - /* psta->rssi = prxcmd->rssi; */ - /* psta->signal_quality = prxcmd->sq; */ precv_frame->psta = psta; pattrib->amsdu = 0; -- GitLab From 8554c4768a36da65ca35a397e4d9c6285b8daf5e Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:55 +0100 Subject: [PATCH 0381/1480] staging: r8188eu: reorder assignments, clarify the header format Reorder some of the assignments in update_recvframe_attrib_88e. This should make it a bit easier to understand the format of the header that is added by the chip's firmware. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c index 9a61eef8550bd..d1ac2960f1c44 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c @@ -66,28 +66,25 @@ void update_recvframe_attrib_88e(struct recv_frame *precvframe, struct recv_stat if (pattrib->pkt_rpt_type == NORMAL_RX) { pattrib->pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff; + pattrib->icv_err = (le32_to_cpu(prxstat->rxdw0) >> 15) & 0x1; pattrib->drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) >> 16) & 0xf) * 8; - + pattrib->encrypt = (u8)((le32_to_cpu(prxstat->rxdw0) >> 20) & 0x7); + pattrib->qos = (le32_to_cpu(prxstat->rxdw0) >> 23) & 0x1; + pattrib->shift_sz = (le32_to_cpu(prxstat->rxdw0) >> 24) & 0x3; pattrib->physt = (le32_to_cpu(prxstat->rxdw0) >> 26) & 0x1; - pattrib->bdecrypted = (le32_to_cpu(prxstat->rxdw0) & BIT(27)) ? 0 : 1; - pattrib->encrypt = (le32_to_cpu(prxstat->rxdw0) >> 20) & 0x7; - pattrib->qos = (le32_to_cpu(prxstat->rxdw0) >> 23) & 0x1; pattrib->priority = (le32_to_cpu(prxstat->rxdw1) >> 8) & 0xf; - pattrib->amsdu = (le32_to_cpu(prxstat->rxdw1) >> 13) & 0x1; + pattrib->mdata = (le32_to_cpu(prxstat->rxdw1) >> 26) & 0x1; + pattrib->mfrag = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1; pattrib->seq_num = le32_to_cpu(prxstat->rxdw2) & 0x00000fff; pattrib->frag_num = (le32_to_cpu(prxstat->rxdw2) >> 12) & 0xf; - pattrib->mfrag = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1; - pattrib->mdata = (le32_to_cpu(prxstat->rxdw1) >> 26) & 0x1; pattrib->mcs_rate = le32_to_cpu(prxstat->rxdw3) & 0x3f; pattrib->rxht = (le32_to_cpu(prxstat->rxdw3) >> 6) & 0x1; - pattrib->icv_err = (le32_to_cpu(prxstat->rxdw0) >> 15) & 0x1; - pattrib->shift_sz = (le32_to_cpu(prxstat->rxdw0) >> 24) & 0x3; } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */ pattrib->pkt_len = TX_RPT1_PKT_LEN; } else if (pattrib->pkt_rpt_type == TX_REPORT2) { -- GitLab From 2dbc324eaab66098ae485114b0862653355a0a2b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:56 +0100 Subject: [PATCH 0382/1480] staging: r8188eu: reformat a function header The definition of Hal_EfuseParseIDCode88E can be a single line. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/rtl8188e_hal_init.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c index cc29963f4b491..73855bca76fe0 100644 --- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c @@ -676,11 +676,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy) return status; } -void -Hal_EfuseParseIDCode88E( - struct adapter *padapter, - u8 *hwinfo - ) +void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo) { struct eeprom_priv *pEEPROM = &padapter->eeprompriv; struct net_device *netdev = padapter->pnetdev; -- GitLab From d44fa4cb2e30fc22b2763fd425f2c48be958354f Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:57 +0100 Subject: [PATCH 0383/1480] staging: r8188eu: remove state checks in rtw_led_control There's no need to check for bSurpriseRemoved or bDriverStopped in the rtw_led_control function. This function schedules a delayed worker which calls SwLedOn or SwLedOff (or the function calls SwLedOff directly). SwLedOn and SwLedOff check bDriverStopped themselves or they initiate a USB control transfer via usb_write, where bSurpriseRemoved is checked. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_led.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c index ce8de2eb7845f..48725ce9d369e 100644 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ b/drivers/staging/r8188eu/core/rtw_led.c @@ -140,8 +140,7 @@ void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) struct registry_priv *registry_par; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) || - (!padapter->hw_init_completed)) + if (!padapter->hw_init_completed) return; if (!pLed->bRegUseLed) -- GitLab From b69373787637e9b38f73ff9f8b7b03e9d9767839 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:58 +0100 Subject: [PATCH 0384/1480] staging: r8188eu: clean up rtw_hal_init Clean up the rtw_hal_init function. Remove the status variable. Exit immediately for errors. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/hal/hal_intf.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c index 37935aef71eab..13790e32f11c2 100644 --- a/drivers/staging/r8188eu/hal/hal_intf.c +++ b/drivers/staging/r8188eu/hal/hal_intf.c @@ -6,24 +6,19 @@ #include "../include/drv_types.h" #include "../include/hal_intf.h" -uint rtw_hal_init(struct adapter *adapt) +uint rtw_hal_init(struct adapter *adapt) { - uint status = _SUCCESS; - adapt->hw_init_completed = false; - status = rtl8188eu_hal_init(adapt); + if (rtl8188eu_hal_init(adapt) != _SUCCESS) + return _FAIL; - if (status == _SUCCESS) { - adapt->hw_init_completed = true; + adapt->hw_init_completed = true; - if (adapt->registrypriv.notch_filter == 1) - hal_notch_filter_8188e(adapt, 1); - } else { - adapt->hw_init_completed = false; - } + if (adapt->registrypriv.notch_filter == 1) + hal_notch_filter_8188e(adapt, 1); - return status; + return _SUCCESS; } uint rtw_hal_deinit(struct adapter *adapt) -- GitLab From b78ec61d9478d438bc9e723214cf609ac669d132 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:48:59 +0100 Subject: [PATCH 0385/1480] staging: r8188eu: remove get_fwstate The get_fwstate function is not used. Remove it. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/rtw_mlme.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h index ca539c652f26d..268f898b151bb 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme.h +++ b/drivers/staging/r8188eu/include/rtw_mlme.h @@ -443,11 +443,6 @@ static inline bool check_fwstate(struct mlme_priv *pmlmepriv, int state) return false; } -static inline int get_fwstate(struct mlme_priv *pmlmepriv) -{ - return pmlmepriv->fw_state; -} - /* * No Limit on the calling context, * therefore set it to be the critical section... -- GitLab From 32265aaf61c6bf399a7ed2c06d75a7d00dd5500e Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:49:00 +0100 Subject: [PATCH 0386/1480] staging: r8188eu: merge two rtw_free_network_nolock functions Remove the _rtw_free_network_nolock function and merge it into rtw_free_network_nolock, which is its only caller. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme.c | 23 ++++++++-------------- drivers/staging/r8188eu/include/rtw_mlme.h | 2 -- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c index a47ae33454b3d..b272123626ac6 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme.c +++ b/drivers/staging/r8188eu/core/rtw_mlme.c @@ -76,19 +76,6 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwor spin_unlock_bh(&free_queue->lock); } -void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) -{ - struct __queue *free_queue = &pmlmepriv->free_bss_pool; - - if (!pnetwork) - return; - if (pnetwork->fixed) - return; - list_del_init(&pnetwork->list); - list_add_tail(&pnetwork->list, get_list_head(free_queue)); - pmlmepriv->num_of_scanned--; -} - /* return the wlan_network with the matching addr @@ -307,9 +294,15 @@ exit: static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) { + struct __queue *free_queue = &pmlmepriv->free_bss_pool; - _rtw_free_network_nolock(pmlmepriv, pnetwork); - + if (!pnetwork) + return; + if (pnetwork->fixed) + return; + list_del_init(&pnetwork->list); + list_add_tail(&pnetwork->list, get_list_head(free_queue)); + pmlmepriv->num_of_scanned--; } void rtw_free_network_queue(struct adapter *dev, u8 isfreeall) diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h index 268f898b151bb..3ff653ff1d816 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme.h +++ b/drivers/staging/r8188eu/include/rtw_mlme.h @@ -539,8 +539,6 @@ struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv); void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall); -void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork); struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr); -- GitLab From c12b5b5614ac39c66d6dcf8f367620e614343b25 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sun, 6 Nov 2022 13:49:01 +0100 Subject: [PATCH 0387/1480] staging: r8188eu: remove checks in dump_mgntframe There's no need to check for bSurpriseRemoved and bDriverStopped in dump_mgmtframe. The sequence of function calls is dump_mgntframe rtl8188eu_mgnt_xmit rtw_dump_xframe loop over all fragments For each fragment, rtw_write_port is called. This function checks bSurpriseRemoved and bDriverStopped. Signed-off-by: Martin Kaiser Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106124901.720785-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 324757699716a..17803aca83c8a 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3959,9 +3959,6 @@ void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattri void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe) { - if (padapter->bSurpriseRemoved || padapter->bDriverStopped) - return; - rtl8188eu_mgnt_xmit(padapter, pmgntframe); } -- GitLab From 2b62e1b447c643de8bb063d64348e4d000f3c557 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Sun, 6 Nov 2022 14:34:43 +0100 Subject: [PATCH 0388/1480] staging: r8188eu: clean up error handling in rtw_start_drv_threads() Convert the error handling in the function rtw_start_drv_threads() to the common logic used in the kernel. Another step to get rid of _FAIL and _SUCCESS which uses inverted logic. Signed-off-by: Michael Straube Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/20221106133443.8872-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/include/osdep_intf.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h index 0f7d74a3ff6df..6d66cb57225e7 100644 --- a/drivers/staging/r8188eu/include/osdep_intf.h +++ b/drivers/staging/r8188eu/include/osdep_intf.h @@ -46,7 +46,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter); void rtw_free_drv_sw(struct adapter *padapter); void rtw_reset_drv_sw(struct adapter *padapter); -u32 rtw_start_drv_threads(struct adapter *padapter); +int rtw_start_drv_threads(struct adapter *padapter); void rtw_stop_drv_threads (struct adapter *padapter); void rtw_cancel_all_timer(struct adapter *padapter); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 970f380bac961..66556e07ed93d 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -363,18 +363,16 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter) return pnetdev; } -u32 rtw_start_drv_threads(struct adapter *padapter) +int rtw_start_drv_threads(struct adapter *padapter) { - u32 _status = _SUCCESS; - padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); if (IS_ERR(padapter->cmdThread)) - _status = _FAIL; - else - /* wait for rtw_cmd_thread() to start running */ - wait_for_completion(&padapter->cmdpriv.start_cmd_thread); + return PTR_ERR(padapter->cmdThread); - return _status; + /* wait for rtw_cmd_thread() to start running */ + wait_for_completion(&padapter->cmdpriv.start_cmd_thread); + + return 0; } void rtw_stop_drv_threads(struct adapter *padapter) @@ -627,8 +625,7 @@ static int _netdev_open(struct net_device *pnetdev) netdev_dbg(pnetdev, "MAC Address = %pM\n", pnetdev->dev_addr); - status = rtw_start_drv_threads(padapter); - if (status == _FAIL) { + if (rtw_start_drv_threads(padapter)) { pr_info("Initialize driver software resource Failed!\n"); goto netdev_open_error; } -- GitLab From c1a84fe1f431cb3de6763aabddcf6073d5053f9d Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sun, 6 Nov 2022 23:25:37 +0530 Subject: [PATCH 0389/1480] staging: r8188eu: simplify complex pointer casting Pointers to structures udphdr and dhcpMessage are derived by casting adjacent pointers with size_t. Such typecast of pointer using size_t is not preferred. The code looks complex and delicate. Simplify such casting by utilizing generic "void *" casting. Suggested-by: Joe Perches Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/1428580d09a9916899209c9278dca40ee2d297d3.1667755987.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index a23f7df373ede..4deaa7e352a34 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -610,12 +610,11 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); if (iph->protocol == IPPROTO_UDP) { /* UDP */ - struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2)); + struct udphdr *udph = (void *)iph + (iph->ihl << 2); if ((udph->source == htons(CLIENT_PORT)) && (udph->dest == htons(SERVER_PORT))) { /* DHCP request */ - struct dhcpMessage *dhcph = - (struct dhcpMessage *)((size_t)udph + sizeof(struct udphdr)); + struct dhcpMessage *dhcph = (void *)udph + sizeof(struct udphdr); u32 cookie = be32_to_cpu((__be32)dhcph->cookie); if (cookie == DHCP_MAGIC) { /* match magic word */ -- GitLab From a57ef65a09a0214776675dcf931ace146724b63c Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sun, 6 Nov 2022 23:27:12 +0530 Subject: [PATCH 0390/1480] staging: r8188eu: remove unnecessary casting The dhcpMessage struct member variable "cookie" is already declared to be of type __be32. There is no need to cast it again as __be32. Signed-off-by: Deepak R Varma Tested-by: Philipp Hortmann # Edimax N150 Link: https://lore.kernel.org/r/c333e22349c5c347c740b425330b35830b969fa9.1667755987.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_br_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c index 4deaa7e352a34..a7c67014dde0f 100644 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ b/drivers/staging/r8188eu/core/rtw_br_ext.c @@ -615,7 +615,7 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) if ((udph->source == htons(CLIENT_PORT)) && (udph->dest == htons(SERVER_PORT))) { /* DHCP request */ struct dhcpMessage *dhcph = (void *)udph + sizeof(struct udphdr); - u32 cookie = be32_to_cpu((__be32)dhcph->cookie); + u32 cookie = be32_to_cpu(dhcph->cookie); if (cookie == DHCP_MAGIC) { /* match magic word */ if (!(dhcph->flags & htons(BROADCAST_FLAG))) { -- GitLab From d54b6ac14d3f1ac033fe88a7f9935ba9f1f47077 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 7 Nov 2022 21:28:22 +0100 Subject: [PATCH 0391/1480] staging: r8188eu: use a qos_hdr in validate_recv_data_frame Define a struct ieee80211_qos_hdr in the validate_recv_data_frame function. Use this struct to replace some numeric offsets and make the code easier to understand. Reported-by: Dan Carpenter Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221107202824.61431-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_recv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index cb0f35d7ab98d..5b0a66aebff19 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -1032,7 +1032,6 @@ static int validate_recv_data_frame(struct adapter *adapter, struct recv_frame *precv_frame) { struct sta_info *psta = NULL; - u8 *ptr = precv_frame->rx_data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct security_priv *psecuritypriv = &adapter->securitypriv; @@ -1071,10 +1070,12 @@ static int validate_recv_data_frame(struct adapter *adapter, pattrib->ack_policy = 0; /* parsing QC field */ if (pattrib->qos) { + struct ieee80211_qos_hdr *qos_hdr = (struct ieee80211_qos_hdr *)hdr; + pattrib->priority = ieee80211_get_tid(hdr); - pattrib->ack_policy = GetAckpolicy((ptr + 24)); - pattrib->amsdu = GetAMsdu((ptr + 24)); - pattrib->hdrlen = 26; + pattrib->ack_policy = GetAckpolicy(&qos_hdr->qos_ctrl); + pattrib->amsdu = GetAMsdu(&qos_hdr->qos_ctrl); + pattrib->hdrlen = sizeof(*qos_hdr); if (pattrib->priority != 0 && pattrib->priority != 3) adapter->recvpriv.bIsAnyNonBEPkts = true; -- GitLab From fa2a8d4284225fbc0ee3db4760d6d7339586d61d Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 7 Nov 2022 21:28:23 +0100 Subject: [PATCH 0392/1480] staging: r8188eu: drop another removal/stop check There's no need to check bDriverStopped and bSurpriseRemoved in issue_probereq_ex. The code path looks like issue_probereq_ex _issue_probereq dump_mgntframe or dump_mgntframe_and_wait_ack All paths from dump_mgntframe check the two variables. dump_mgntframe_and_wait_ack contains a check as well. Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221107202824.61431-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 17803aca83c8a..bfd6afd7266e3 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -4496,9 +4496,6 @@ int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, i++; - if (padapter->bDriverStopped || padapter->bSurpriseRemoved) - break; - if (i < try_cnt && wait_ms > 0 && ret == _FAIL) msleep(wait_ms); -- GitLab From a614e753e8e7f3322b560dcf6eaf44468ec22b3a Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 7 Nov 2022 21:28:24 +0100 Subject: [PATCH 0393/1480] staging: r8188eu: drop removal/stop check in dump_mgntframe_and_wait_ack We can remove the checks for bDriverStopped and bSurpriseRemoved in dump_mgntframe_and_wait_ack. The code path from this function looks like dump_mgntframe_and_wait_ack rtl8188eu_mgnt_xmit rtw_dump_xframe loop over all fragments rtw_write_port is called for each fragment. bSurpriseRemoved and bDriverStopped are checked in rtw_write_port. Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221107202824.61431-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index bfd6afd7266e3..be33489d3dfdd 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3988,9 +3988,6 @@ s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmg u32 timeout_ms = 500;/* 500ms */ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - if (padapter->bSurpriseRemoved || padapter->bDriverStopped) - return -1; - mutex_lock(&pxmitpriv->ack_tx_mutex); pxmitpriv->ack_tx = true; -- GitLab From 0ce0f9d0785a7ba5637a22b63332cf747772da2a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 7 Nov 2022 00:05:06 +0100 Subject: [PATCH 0394/1480] usb: phy: phy-gpio-vbus-usb: Add device tree probing Make it possible to probe the GPIO VBUS detection driver from the device tree compatible for GPIO USB B connectors. Since this driver is using the "gpio-usb-b-connector" compatible, it is important to discern it from the role switch connector driver (which does not provide a phy), so we add some Kconfig text and depend on !USB_CONN_GPIO. Cc: Rob Herring Cc: Prashant Malani Cc: Felipe Balbi Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221106230506.1646101-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/Kconfig | 6 +++++- drivers/usb/phy/phy-gpio-vbus-usb.c | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 2acbe41fbf7e0..efdcafdbe46d7 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -93,12 +93,16 @@ config USB_GPIO_VBUS tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" depends on GPIOLIB || COMPILE_TEST depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' + depends on !USB_CONN_GPIO select USB_PHY help Provides simple GPIO VBUS sensing for controllers with an internal transceiver via the usb_phy interface, and optionally control of a D+ pullup GPIO as well as a VBUS - current limit regulator. + current limit regulator. This driver is for devices that do + NOT support role switch. OTG devices that can do role switch + (master/peripheral) shall use the USB based connection + detection driver USB_CONN_GPIO. config OMAP_OTG tristate "OMAP USB OTG controller driver" diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index f13f5530746cc..12dfeff7de3d0 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -366,12 +366,24 @@ static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { MODULE_ALIAS("platform:gpio-vbus"); +/* + * NOTE: this driver matches against "gpio-usb-b-connector" for + * devices that do NOT support role switch. + */ +static const struct of_device_id gpio_vbus_of_match[] = { + { + .compatible = "gpio-usb-b-connector", + }, + {}, +}; + static struct platform_driver gpio_vbus_driver = { .driver = { .name = "gpio-vbus", #ifdef CONFIG_PM .pm = &gpio_vbus_dev_pm_ops, #endif + .of_match_table = gpio_vbus_of_match, }, .probe = gpio_vbus_probe, .remove = gpio_vbus_remove, -- GitLab From 04914233561377fc0369b984c9d19ec1b6ce2845 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Mon, 7 Nov 2022 16:37:55 -0800 Subject: [PATCH 0395/1480] usb: dwc3: gadget: Reduce TRB IOC settings When the TRB ring is full, the dwc3 driver must make sure that there's at least 1 TRB with Interrupt On Completion (IOC) set to notify of available TRBs. The current logic just sets the TRB's IOC whenever we run out of TRBs, but it doesn't consider that there may be other TRBs with IOC/LST set already. This creates more events and unnecessary delay from interrupt handling. Only forcefully set IOC when we run out of TRBs and none of the TRBs in the TRB ring has had IOC set. Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/72a1fa448eb1201b152e65be7902a5d1c75b9f3a.1667867687.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 5fe2d136dff51..ecddb144871be 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1463,8 +1463,18 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, */ if (num_trbs_left == 1 || (needs_extra_trb && num_trbs_left <= 2 && - sg_dma_len(sg_next(s)) >= length)) - must_interrupt = true; + sg_dma_len(sg_next(s)) >= length)) { + struct dwc3_request *r; + + /* Check if previous requests already set IOC */ + list_for_each_entry(r, &dep->started_list, list) { + if (r != req && !r->request.no_interrupt) + break; + + if (r == req) + must_interrupt = true; + } + } dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, must_interrupt); -- GitLab From 430d57f53eb1cdbf9ba9bbd397317912b3cd2de5 Mon Sep 17 00:00:00 2001 From: Ray Chi Date: Mon, 7 Nov 2022 15:27:54 +0800 Subject: [PATCH 0396/1480] usb: core: stop USB enumeration if too many retries When a broken USB accessory connects to a USB host, usbcore might keep doing enumeration retries. If the host has a watchdog mechanism, the kernel panic will happen on the host. This patch provides an attribute early_stop to limit the numbers of retries for each port of a hub. If a port was marked with early_stop attribute, unsuccessful connection attempts will fail quickly. In addition, if an early_stop port has failed to initialize, it will ignore all future connection events until early_stop attribute is clear. Signed-off-by: Ray Chi Reviewed-by: Alan Stern Link: https://lore.kernel.org/r/20221107072754.3336357-1-raychi@google.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 11 +++++ drivers/usb/core/hub.c | 60 +++++++++++++++++++++++++ drivers/usb/core/hub.h | 4 ++ drivers/usb/core/port.c | 27 +++++++++++ 4 files changed, 102 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 568103d3376ee..545c2dd97ed02 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -264,6 +264,17 @@ Description: attached to the port will not be detected, initialized, or enumerated. +What: /sys/bus/usb/devices/...//port/early_stop +Date: Sep 2022 +Contact: Ray Chi +Description: + Some USB hosts have some watchdog mechanisms so that the device + may enter ramdump if it takes a long time during port initialization. + This attribute allows each port just has two attempts so that the + port initialization will be failed quickly. In addition, if a port + which is marked with early_stop has failed to initialize, it will ignore + all future connections until this attribute is clear. + What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout Date: May 2013 Contact: Mathias Nyman diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index bbab424b0d559..77e73fc8d6736 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3081,6 +3081,48 @@ done: return status; } +/* + * hub_port_stop_enumerate - stop USB enumeration or ignore port events + * @hub: target hub + * @port1: port num of the port + * @retries: port retries number of hub_port_init() + * + * Return: + * true: ignore port actions/events or give up connection attempts. + * false: keep original behavior. + * + * This function will be based on retries to check whether the port which is + * marked with early_stop attribute would stop enumeration or ignore events. + * + * Note: + * This function didn't change anything if early_stop is not set, and it will + * prevent all connection attempts when early_stop is set and the attempts of + * the port are more than 1. + */ +static bool hub_port_stop_enumerate(struct usb_hub *hub, int port1, int retries) +{ + struct usb_port *port_dev = hub->ports[port1 - 1]; + + if (port_dev->early_stop) { + if (port_dev->ignore_event) + return true; + + /* + * We want unsuccessful attempts to fail quickly. + * Since some devices may need one failure during + * port initialization, we allow two tries but no + * more. + */ + if (retries < 2) + return false; + + port_dev->ignore_event = 1; + } else + port_dev->ignore_event = 0; + + return port_dev->ignore_event; +} + /* Check if a port is power on */ int usb_port_is_power_on(struct usb_hub *hub, unsigned int portstatus) { @@ -4796,6 +4838,11 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, do_new_scheme = use_new_scheme(udev, retry_counter, port_dev); for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) { + if (hub_port_stop_enumerate(hub, port1, retries)) { + retval = -ENODEV; + break; + } + if (do_new_scheme) { struct usb_device_descriptor *buf; int r = 0; @@ -5246,6 +5293,11 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, status = 0; for (i = 0; i < PORT_INIT_TRIES; i++) { + if (hub_port_stop_enumerate(hub, port1, i)) { + status = -ENODEV; + break; + } + usb_lock_port(port_dev); mutex_lock(hcd->address0_mutex); retry_locked = true; @@ -5614,6 +5666,10 @@ static void port_event(struct usb_hub *hub, int port1) if (!pm_runtime_active(&port_dev->dev)) return; + /* skip port actions if ignore_event and early_stop are true */ + if (port_dev->ignore_event && port_dev->early_stop) + return; + if (hub_handle_remote_wakeup(hub, port1, portstatus, portchange)) connect_change = 1; @@ -5927,6 +5983,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) mutex_lock(hcd->address0_mutex); for (i = 0; i < PORT_INIT_TRIES; ++i) { + if (hub_port_stop_enumerate(parent_hub, port1, i)) { + ret = -ENODEV; + break; + } /* ep0 maxpacket size may change; let the HCD know about it. * Other endpoints will be handled by re-enumeration. */ diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index b2925856b4cb4..e23833562e4f2 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -90,6 +90,8 @@ struct usb_hub { * @is_superspeed cache super-speed status * @usb3_lpm_u1_permit: whether USB3 U1 LPM is permitted. * @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted. + * @early_stop: whether port initialization will be stopped earlier. + * @ignore_event: whether events of the port are ignored. */ struct usb_port { struct usb_device *child; @@ -103,6 +105,8 @@ struct usb_port { u32 over_current_count; u8 portnum; u32 quirks; + unsigned int early_stop:1; + unsigned int ignore_event:1; unsigned int is_superspeed:1; unsigned int usb3_lpm_u1_permit:1; unsigned int usb3_lpm_u2_permit:1; diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 015204fc67a10..06a8f1f84f6f8 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -18,6 +18,32 @@ static int usb_port_block_power_off; static const struct attribute_group *port_dev_group[]; +static ssize_t early_stop_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_port *port_dev = to_usb_port(dev); + + return sysfs_emit(buf, "%s\n", port_dev->early_stop ? "yes" : "no"); +} + +static ssize_t early_stop_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_port *port_dev = to_usb_port(dev); + bool value; + + if (kstrtobool(buf, &value)) + return -EINVAL; + + if (value) + port_dev->early_stop = 1; + else + port_dev->early_stop = 0; + + return count; +} +static DEVICE_ATTR_RW(early_stop); + static ssize_t disable_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -237,6 +263,7 @@ static struct attribute *port_dev_attrs[] = { &dev_attr_quirks.attr, &dev_attr_over_current_count.attr, &dev_attr_disable.attr, + &dev_attr_early_stop.attr, NULL, }; -- GitLab From a9dfc46c67b52ad43b8e335e28f4cf8002c67793 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Sat, 5 Nov 2022 12:01:14 +0900 Subject: [PATCH 0397/1480] perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged data DWARF version 5 standard Sec 2.14 says that Any debugging information entry representing the declaration of an object, module, subprogram or type may have DW_AT_decl_file, DW_AT_decl_line and DW_AT_decl_column attributes, each of whose value is an unsigned integer constant. So it should be an unsigned integer data. Also, even though the standard doesn't clearly say the DW_AT_call_file is signed or unsigned, the elfutils (eu-readelf) interprets it as unsigned integer data and it is natural to handle it as unsigned integer data as same as DW_AT_decl_file. This changes the DW_AT_call_file as unsigned integer data too. Fixes: 3f4460a28fb2f73d ("perf probe: Filter out redundant inline-instances") Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: stable@vger.kernel.org Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/166761727445.480106.3738447577082071942.stgit@devnote3 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 30b36b525681a..b074144097710 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -315,19 +315,6 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name, return 0; } -/* Get attribute and translate it as a sdata */ -static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name, - Dwarf_Sword *result) -{ - Dwarf_Attribute attr; - - if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL || - dwarf_formsdata(&attr, result) != 0) - return -ENOENT; - - return 0; -} - /** * die_is_signed_type - Check whether a type DIE is signed or not * @tp_die: a DIE of a type @@ -467,9 +454,9 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs) /* Get the call file index number in CU DIE */ static int die_get_call_fileno(Dwarf_Die *in_die) { - Dwarf_Sword idx; + Dwarf_Word idx; - if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0) + if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0) return (int)idx; else return -ENOENT; @@ -478,9 +465,9 @@ static int die_get_call_fileno(Dwarf_Die *in_die) /* Get the declared file index number in CU DIE */ static int die_get_decl_fileno(Dwarf_Die *pdie) { - Dwarf_Sword idx; + Dwarf_Word idx; - if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0) + if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0) return (int)idx; else return -ENOENT; -- GitLab From 0349fdab2ff0673cc3c3f300316522d4f2bb1af9 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Fri, 4 Nov 2022 22:55:13 +0100 Subject: [PATCH 0398/1480] usb: gadget: at91-udc: simplify at91rm9200_udc_pullup callback Just simplify the use of is_on and get rid of superfluous condition. Cc: gregkh@linuxfoundation.org Cc: nicolas.ferre@microchip.com Cc: alexandre.belloni@bootlin.com Cc: linux-usb@vger.kernel.org Cc: kernel@pengutronix.de Reviewed-by: Claudiu Beznea Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20221104215516.2874922-2-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/at91_udc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index a9a7b3fc60ec9..922b4187004b0 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1628,10 +1628,7 @@ static int at91rm9200_udc_init(struct at91_udc *udc) static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on) { - if (is_on) - gpiod_set_value(udc->board.pullup_pin, 1); - else - gpiod_set_value(udc->board.pullup_pin, 0); + gpiod_set_value(udc->board.pullup_pin, is_on); } static const struct at91_udc_caps at91rm9200_udc_caps = { -- GitLab From afb21a5155a136a2549947c151b13507a34976ae Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 3 Nov 2022 12:59:23 +0100 Subject: [PATCH 0399/1480] dt-bindings: usb: usb-drd: Describe default dual-role mode The dual-role mode default, in the absence of the dr_mode property, is already documented to be OTG. Use the "default" property to mark it as such more explicitly. Signed-off-by: Thierry Reding Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221103115923.1467525-1-thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-drd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/usb-drd.yaml b/Documentation/devicetree/bindings/usb/usb-drd.yaml index 1567549b05cec..114fb5dc0498a 100644 --- a/Documentation/devicetree/bindings/usb/usb-drd.yaml +++ b/Documentation/devicetree/bindings/usb/usb-drd.yaml @@ -27,6 +27,7 @@ properties: should default to OTG. $ref: /schemas/types.yaml#/definitions/string enum: [host, peripheral, otg] + default: otg hnp-disable: description: -- GitLab From fff61d4ccf3d1124bf7aa82fa996536833b8204a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 7 Nov 2022 14:42:48 +0100 Subject: [PATCH 0400/1480] dt-bindings: usb: usb251xb: Convert to YAML schema Convert the usb251xb hub DT bindings from text to yaml schema so it is possible to validate DTs against the schema. Adjust the example to describe two different hubs at different I2C bus addresses, to avoid I2C address collission in the example. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Marek Vasut Link: https://lore.kernel.org/r/20221107134248.21899-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/usb251xb.txt | 89 ------ .../devicetree/bindings/usb/usb251xb.yaml | 271 ++++++++++++++++++ 2 files changed, 271 insertions(+), 89 deletions(-) delete mode 100644 Documentation/devicetree/bindings/usb/usb251xb.txt create mode 100644 Documentation/devicetree/bindings/usb/usb251xb.yaml diff --git a/Documentation/devicetree/bindings/usb/usb251xb.txt b/Documentation/devicetree/bindings/usb/usb251xb.txt deleted file mode 100644 index 1a934eab175ee..0000000000000 --- a/Documentation/devicetree/bindings/usb/usb251xb.txt +++ /dev/null @@ -1,89 +0,0 @@ -Microchip USB 2.0 Hi-Speed Hub Controller - -The device node for the configuration of a Microchip USB251x/xBi USB 2.0 -Hi-Speed Controller. - -Required properties : - - compatible : Should be "microchip,usb251xb" or one of the specific types: - "microchip,usb2512b", "microchip,usb2512bi", "microchip,usb2513b", - "microchip,usb2513bi", "microchip,usb2514b", "microchip,usb2514bi", - "microchip,usb2517", "microchip,usb2517i", "microchip,usb2422" - - reg : I2C address on the selected bus (default is <0x2C>) - -Optional properties : - - reset-gpios : Should specify the gpio for hub reset - - vdd-supply : Should specify the phandle to the regulator supplying vdd - - skip-config : Skip Hub configuration, but only send the USB-Attach command - - vendor-id : Set USB Vendor ID of the hub (16 bit, default is 0x0424) - - product-id : Set USB Product ID of the hub (16 bit, default depends on type) - - device-id : Set USB Device ID of the hub (16 bit, default is 0x0bb3) - - language-id : Set USB Language ID (16 bit, default is 0x0000) - - manufacturer : Set USB Manufacturer string (max 31 characters long) - - product : Set USB Product string (max 31 characters long) - - serial : Set USB Serial string (max 31 characters long) - - {bus,self}-powered : selects between self- and bus-powered operation - (boolean, default is self-powered) - - disable-hi-speed : disable USB Hi-Speed support (boolean) - - {multi,single}-tt : selects between multi- and single-transaction-translator - (boolean, default is multi-tt) - - disable-eop : disable End of Packet generation in full-speed mode (boolean) - - {ganged,individual}-sensing : select over-current sense type in self-powered - mode (boolean, default is individual) - - {ganged,individual}-port-switching : select port power switching mode - (boolean, default is individual) - - dynamic-power-switching : enable auto-switching from self- to bus-powered - operation if the local power source is removed or unavailable (boolean) - - oc-delay-us : Delay time (in microseconds) for filtering the over-current - sense inputs. Valid values are 100, 4000, 8000 (default) and 16000. If - an invalid value is given, the default is used instead. - - compound-device : indicate the hub is part of a compound device (boolean) - - port-mapping-mode : enable port mapping mode (boolean) - - led-{usb,speed}-mode : led usb/speed indication mode selection - (boolean, default is speed mode) - - string-support : enable string descriptor support (required for manufacturer, - product and serial string configuration) - - non-removable-ports : Should specify the ports which have a non-removable - device connected. - - sp-disabled-ports : Specifies the ports which will be self-power disabled - - bp-disabled-ports : Specifies the ports which will be bus-power disabled - - sp-max-total-current-microamp: Specifies max current consumed by the hub - from VBUS when operating in self-powered hub. It includes the hub - silicon along with all associated circuitry including a permanently - attached peripheral (range: 0 - 100000 uA, default 1000 uA) - - bp-max-total-current-microamp: Specifies max current consumed by the hub - from VBUS when operating in self-powered hub. It includes the hub - silicon along with all associated circuitry including a permanently - attached peripheral (range: 0 - 510000 uA, default 100000 uA) - - sp-max-removable-current-microamp: Specifies max current consumed by the hub - from VBUS when operating in self-powered hub. It includes the hub - silicon along with all associated circuitry excluding a permanently - attached peripheral (range: 0 - 100000 uA, default 1000 uA) - - bp-max-removable-current-microamp: Specifies max current consumed by the hub - from VBUS when operating in self-powered hub. It includes the hub - silicon along with all associated circuitry excluding a permanently - attached peripheral (range: 0 - 510000 uA, default 100000 uA) - - power-on-time-ms : Specifies the time it takes from the time the host - initiates the power-on sequence to a port until the port has adequate - power. The value is given in ms in a 0 - 510 range (default is 100ms). - - swap-dx-lanes : Specifies the ports which will swap the differential-pair - (D+/D-), default is not-swapped. - -Examples: - usb2512b@2c { - compatible = "microchip,usb2512b"; - reg = <0x2c>; - reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - }; - - usb2514b@2c { - compatible = "microchip,usb2514b"; - reg = <0x2c>; - vendor-id = /bits/ 16 <0x0000>; - product-id = /bits/ 16 <0x0000>; - string-support; - manufacturer = "Foo"; - product = "Foo-Bar"; - serial = "1234567890A"; - /* correct misplaced usb connectors on port 1,2 */ - swap-dx-lanes = <1 2>; - }; diff --git a/Documentation/devicetree/bindings/usb/usb251xb.yaml b/Documentation/devicetree/bindings/usb/usb251xb.yaml new file mode 100644 index 0000000000000..4d15308168178 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb251xb.yaml @@ -0,0 +1,271 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/usb251xb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip USB 2.0 Hi-Speed Hub Controller + +maintainers: + - Richard Leitner + +properties: + compatible: + enum: + - microchip,usb2422 + - microchip,usb2512b + - microchip,usb2512bi + - microchip,usb2513b + - microchip,usb2513bi + - microchip,usb2514b + - microchip,usb2514bi + - microchip,usb2517 + - microchip,usb2517i + - microchip,usb251xb + + reg: + maxItems: 1 + + reset-gpios: + description: | + Should specify the gpio for hub reset + + vdd-supply: + description: | + Should specify the phandle to the regulator supplying vdd + + skip-config: + $ref: /schemas/types.yaml#/definitions/flag + description: | + Skip Hub configuration, but only send the USB-Attach command + + vendor-id: + $ref: /schemas/types.yaml#/definitions/uint16 + default: 0x0424 + description: | + Set USB Vendor ID of the hub + + product-id: + $ref: /schemas/types.yaml#/definitions/uint16 + description: | + Set USB Product ID of the hub + + device-id: + $ref: /schemas/types.yaml#/definitions/uint16 + default: 0x0bb3 + description: | + Set USB Device ID of the hub + + language-id: + $ref: /schemas/types.yaml#/definitions/uint16 + default: 0x0000 + description: | + Set USB Language ID + + manufacturer: + $ref: /schemas/types.yaml#/definitions/string + description: | + Set USB Manufacturer string (max 31 characters long) + + product: + $ref: /schemas/types.yaml#/definitions/string + description: | + Set USB Product string (max 31 characters long) + + serial: + $ref: /schemas/types.yaml#/definitions/string + description: | + Set USB Serial string (max 31 characters long) + + bus-powered: + $ref: /schemas/types.yaml#/definitions/flag + description: | + selects between self- and bus-powered operation + (boolean, default is self-powered) + + self-powered: + $ref: /schemas/types.yaml#/definitions/flag + description: | + selects between self- and bus-powered operation + (boolean, default is self-powered) + + disable-hi-speed: + $ref: /schemas/types.yaml#/definitions/flag + description: | + disable USB Hi-Speed support (boolean) + + multi-tt: + $ref: /schemas/types.yaml#/definitions/flag + description: | + selects between multi- and single-transaction-translator + (boolean, default is multi-tt) + + single-tt: + $ref: /schemas/types.yaml#/definitions/flag + description: | + selects between multi- and single-transaction-translator + (boolean, default is multi-tt) + + disable-eop: + $ref: /schemas/types.yaml#/definitions/flag + description: | + disable End of Packet generation in full-speed mode (boolean) + + ganged-sensing: + $ref: /schemas/types.yaml#/definitions/flag + description: | + select over-current sense type in self-powered mode + (boolean, default is individual) + + individual-sensing: + $ref: /schemas/types.yaml#/definitions/flag + description: | + select over-current sense type in self-powered mode + (boolean, default is individual) + + ganged-port-switching: + $ref: /schemas/types.yaml#/definitions/flag + description: | + select port power switching mode (boolean, default is individual) + + individual-port-switching: + $ref: /schemas/types.yaml#/definitions/flag + description: | + select port power switching mode (boolean, default is individual) + + dynamic-power-switching: + $ref: /schemas/types.yaml#/definitions/flag + description: | + enable auto-switching from self- to bus-powered operation if the + local power source is removed or unavailable (boolean) + + oc-delay-us: + enum: [100, 4000, 8000, 16000] + default: 8000 + description: | + Delay time (in microseconds) for filtering the over-current sense + inputs. If an invalid value is given, the default is used instead. + + compound-device: + $ref: /schemas/types.yaml#/definitions/flag + description: | + indicate the hub is part of a compound device (boolean) + + port-mapping-mode: + $ref: /schemas/types.yaml#/definitions/flag + description: | + enable port mapping mode (boolean) + + led-usb-mode: + $ref: /schemas/types.yaml#/definitions/flag + description: | + led usb/speed indication mode selection (boolean, default is speed mode) + + led-speed-mode: + $ref: /schemas/types.yaml#/definitions/flag + description: | + led usb/speed indication mode selection (boolean, default is speed mode) + + string-support: + $ref: /schemas/types.yaml#/definitions/flag + description: | + enable string descriptor support (required for manufacturer, product + and serial string configuration) + + non-removable-ports: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + Should specify the ports which have a non-removable device connected. + + sp-disabled-ports: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + Specifies the ports which will be self-power disabled + + bp-disabled-ports: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + Specifies the ports which will be bus-power disabled + + sp-max-total-current-microamp: + maximum: 100000 + default: 1000 + description: | + Specifies max current consumed by the hub from VBUS when + operating in self-powered hub. It includes the hub silicon + along with all associated circuitry including a permanently + attached peripheral. + + bp-max-total-current-microamp: + maximum: 510000 + default: 100000 + description: | + Specifies max current consumed by the hub from VBUS when + operating in self-powered hub. It includes the hub silicon + along with all associated circuitry including a permanently + attached peripheral. + + sp-max-removable-current-microamp: + maximum: 100000 + default: 1000 + description: | + Specifies max current consumed by the hub from VBUS when + operating in self-powered hub. It includes the hub silicon + along with all associated circuitry excluding a permanently + attached peripheral. + + bp-max-removable-current-microamp: + maximum: 510000 + default: 100000 + description: | + Specifies max current consumed by the hub from VBUS when + operating in self-powered hub. It includes the hub silicon + along with all associated circuitry excluding a permanently + attached peripheral. + + power-on-time-ms: + maximum: 510 + default: 100 + description: | + Specifies the time it takes from the time the host initiates the + power-on sequence to a port until the port has adequate power. + + swap-dx-lanes: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + Specifies the ports which will swap the differential-pair (D+/D-), + default is not-swapped. + +additionalProperties: false + +required: + - compatible + - reg + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + usb-hub@2c { + compatible = "microchip,usb2512b"; + reg = <0x2c>; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + }; + + usb-hub@2d { + compatible = "microchip,usb2514b"; + reg = <0x2d>; + vendor-id = /bits/ 16 <0x0000>; + product-id = /bits/ 16 <0x0000>; + string-support; + manufacturer = "Foo"; + product = "Foo-Bar"; + serial = "1234567890A"; + /* correct misplaced usb connectors on port 1,2 */ + swap-dx-lanes = <1 2>; + }; + }; -- GitLab From 434d806f077cad81d87a757adc631894bfa01ac2 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 26 Oct 2022 14:12:21 +0800 Subject: [PATCH 0401/1480] dt-bindings: usb: usb-nop-xceiv: add wakeup-source property USB phy may be a system wakeup source, so add wakeup source property to keep its resource (e.g. power domain) active to make USB remote wakeup work. Signed-off-by: Li Jun Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1666764742-4201-1-git-send-email-jun.li@nxp.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-nop-xceiv.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.yaml b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.yaml index 2824c17285eea..326131dcf14d7 100644 --- a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.yaml +++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.yaml @@ -39,6 +39,11 @@ properties: the VBus line. $ref: /schemas/types.yaml#/definitions/phandle + wakeup-source: + description: + Specify if the USB phy can detect the remote wakeup signal + while the system sleep. + required: - compatible - '#phy-cells' -- GitLab From 4567d1a97f5290cb895a564feff0a5c770d6c332 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 26 Oct 2022 14:12:22 +0800 Subject: [PATCH 0402/1480] usb: phy: generic: Add wakeup capability In case USB phy is the wakeup source, enable its wakeup capability. Signed-off-by: Li Jun Link: https://lore.kernel.org/r/1666764742-4201-2-git-send-email-jun.li@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/phy-generic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 8ed9327cc4a52..c1309ea24a52e 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -286,6 +286,7 @@ EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); static int usb_phy_generic_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *dn = dev->of_node; struct usb_phy_generic *nop; int err; @@ -323,6 +324,9 @@ static int usb_phy_generic_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nop); + device_set_wakeup_capable(&pdev->dev, + of_property_read_bool(dn, "wakeup-source")); + return 0; } -- GitLab From ee9834636f9b07fe1dcf3fffbb325318cdb267d5 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 28 Oct 2022 18:45:34 -0700 Subject: [PATCH 0403/1480] usb: ehci-pci: Set PROBE_PREFER_ASYNCHRONOUS This driver often takes on the order of 8ms to start, but every little bit counts. It shouldn't have many cross-device dependencies to race with, nor racy access to shared state with other drivers, so this should be a relatively low risk change. This driver was pinpointed as part of a survey of top slowest initcalls (i.e., are built in, and probing synchronously) on a lab of ChromeOS systems. Signed-off-by: Brian Norris Acked-by: Alan Stern Link: https://lore.kernel.org/r/20221028184507.v2.1.I9a5353f81d1509f85f3a04f0cdc9099f6fe60811@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-pci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 17f8b6ea0c356..4b148fe5e43b2 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -411,11 +411,12 @@ static struct pci_driver ehci_pci_driver = { .remove = ehci_pci_remove, .shutdown = usb_hcd_pci_shutdown, -#ifdef CONFIG_PM .driver = { - .pm = &usb_hcd_pci_pm_ops - }, +#ifdef CONFIG_PM + .pm = &usb_hcd_pci_pm_ops, #endif + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, }; static int __init ehci_pci_init(void) -- GitLab From 4c2604a9a6899bab195edbee35fc8d64ce1444aa Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 28 Oct 2022 18:45:35 -0700 Subject: [PATCH 0404/1480] usb: xhci-pci: Set PROBE_PREFER_ASYNCHRONOUS This driver often takes on the order of 10ms to start, but in some cases takes more than 100ms. It shouldn't have many cross-device dependencies to race with, nor racy access to shared state with other drivers, so this should be a relatively low risk change. This driver was pinpointed as part of a survey of top slowest initcalls (i.e., are built in, and probing synchronously) on a lab of ChromeOS systems. Signed-off-by: Brian Norris Link: https://lore.kernel.org/r/20221028184507.v2.2.I5a309231785d3a4e37118a25e84f5caa0136a343@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7bccbe50bab15..a29b681b562e4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -673,11 +673,12 @@ static struct pci_driver xhci_pci_driver = { /* suspend and resume implemented later */ .shutdown = usb_hcd_pci_shutdown, -#ifdef CONFIG_PM .driver = { - .pm = &usb_hcd_pci_pm_ops - }, +#ifdef CONFIG_PM + .pm = &usb_hcd_pci_pm_ops, #endif + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, }; static int __init xhci_pci_init(void) -- GitLab From 9c3959bb4cbf2b45c5b53bf8a19426e5ddb5c56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 4 Nov 2022 10:58:38 +0100 Subject: [PATCH 0405/1480] usb: chipidea: ci_hdrc_imx: Fix a typo ("regualator") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change "regualator" to "regulator" in this comment. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Mukesh Ojha Link: https://lore.kernel.org/r/20221104095838.2132945-1-j.neuschaefer@gmx.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 923f5c00a1d96..0dc482542d852 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -355,7 +355,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) data->hsic_pad_regulator = devm_regulator_get_optional(dev, "hsic"); if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { - /* no pad regualator is needed */ + /* no pad regulator is needed */ data->hsic_pad_regulator = NULL; } else if (IS_ERR(data->hsic_pad_regulator)) return dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator), -- GitLab From 83045e19feae937c425248824d1dc0fc95583842 Mon Sep 17 00:00:00 2001 From: Henry Tian Date: Mon, 24 Oct 2022 09:48:53 +0000 Subject: [PATCH 0406/1480] usb: gadget: aspeed: fix buffer overflow In ast_vhub_epn_handle_ack() when the received data length exceeds the buffer, it does not check the case and just copies to req.buf and cause a buffer overflow, kernel oops on this case. This issue could be reproduced on a BMC with an OS that enables the lan over USB: 1. In OS, enable the usb eth dev, verify it pings the BMC OK; 2. In OS, set the usb dev mtu to 2000. (Default is 1500); 3. In OS, ping the BMC with `-s 2000` argument. The BMC kernel will get oops with below logs: skbuff: skb_over_panic: text:8058e098 len:2048 put:2048 head:84c678a0 data:84c678c2 tail:0x84c680c2 end:0x84c67f00 dev:usb0 ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:113! Internal error: Oops - BUG: 0 [#1] ARM CPU: 0 PID: 0 Comm: swapper Not tainted 5.15.69-c9fb275-dirty-d1e579a #1 Hardware name: Generic DT based system PC is at skb_panic+0x60/0x6c LR is at irq_work_queue+0x6c/0x94 Fix the issue by checking the length and set `-EOVERFLOW`. Tested: Verify the BMC kernel does not get oops in the above case, and the usb ethernet gets RX packets errors instead. Signed-off-by: Lei YU Signed-off-by: Henry Tian Reviewed-by: Neal Liu Acked-by: Benjamin Herrenschmidt Link: https://lore.kernel.org/r/20221024094853.2877441-1-yulei.sh@bytedance.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/aspeed-vhub/core.c | 2 +- drivers/usb/gadget/udc/aspeed-vhub/epn.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c index 7a635c4997774..ac3ca24f8b045 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c @@ -37,7 +37,7 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req, list_del_init(&req->queue); - if (req->req.status == -EINPROGRESS) + if ((req->req.status == -EINPROGRESS) || (status == -EOVERFLOW)) req->req.status = status; if (req->req.dma) { diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c index b5252880b3894..56e55472daa13 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c @@ -84,6 +84,7 @@ static void ast_vhub_epn_handle_ack(struct ast_vhub_ep *ep) { struct ast_vhub_req *req; unsigned int len; + int status = 0; u32 stat; /* Read EP status */ @@ -119,9 +120,15 @@ static void ast_vhub_epn_handle_ack(struct ast_vhub_ep *ep) len = VHUB_EP_DMA_TX_SIZE(stat); /* If not using DMA, copy data out if needed */ - if (!req->req.dma && !ep->epn.is_in && len) - memcpy(req->req.buf + req->req.actual, ep->buf, len); - + if (!req->req.dma && !ep->epn.is_in && len) { + if (req->req.actual + len > req->req.length) { + req->last_desc = 1; + status = -EOVERFLOW; + goto done; + } else { + memcpy(req->req.buf + req->req.actual, ep->buf, len); + } + } /* Adjust size */ req->req.actual += len; @@ -129,9 +136,10 @@ static void ast_vhub_epn_handle_ack(struct ast_vhub_ep *ep) if (len < ep->ep.maxpacket) req->last_desc = 1; +done: /* That's it ? complete the request and pick a new one */ if (req->last_desc >= 0) { - ast_vhub_done(ep, req, 0); + ast_vhub_done(ep, req, status); req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue); -- GitLab From d119cd95c62ddf6a1d76a006be273f255fd6c5a8 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 31 Oct 2022 09:54:26 +0100 Subject: [PATCH 0407/1480] usb: musb: remove left-over after USB_TI_CPPI_DMA removal Commit 32fee1df5110 ("usb: musb: remove unused davinci support") removes the config USB_TI_CPPI_DMA, but misses some left-over references in drivers/usb/musb/musb_dma.h. Remove the left-over dependent on this removed config. Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20221031085426.17175-1-lukas.bulwahn@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_dma.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 7d67b69df0a07..e2445ca3356d0 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h @@ -61,12 +61,6 @@ struct musb_hw_ep; #define musb_dma_cppi41(musb) 0 #endif -#ifdef CONFIG_USB_TI_CPPI_DMA -#define musb_dma_cppi(musb) (musb->ops->quirks & MUSB_DMA_CPPI) -#else -#define musb_dma_cppi(musb) 0 -#endif - #ifdef CONFIG_USB_TUSB_OMAP_DMA #define tusb_dma_omap(musb) (musb->ops->quirks & MUSB_DMA_TUSB_OMAP) #else @@ -79,11 +73,10 @@ struct musb_hw_ep; #define musb_dma_inventra(musb) 0 #endif -#if defined(CONFIG_USB_TI_CPPI_DMA) || defined(CONFIG_USB_TI_CPPI41_DMA) -#define is_cppi_enabled(musb) \ - (musb_dma_cppi(musb) || musb_dma_cppi41(musb)) +#if defined(CONFIG_USB_TI_CPPI41_DMA) +#define is_cppi_enabled(musb) musb_dma_cppi41(musb) #else -#define is_cppi_enabled(musb) 0 +#define is_cppi_enabled(musb) 0 #endif /* -- GitLab From 77ece8123fed2bef451ef31a34b8327849375d26 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 3 Nov 2022 10:06:25 +0800 Subject: [PATCH 0408/1480] Documentation: devres: add missing PHY helpers Add devm_usb_get_phy_by_phandle() to devres.rst. It's introduced by commit 5d3c28b5a42d ("usb: otg: add device tree support to otg library"). Add devm_usb_get_phy_by_node() to devres.rst. It's introduced by commit e842b84c8e72 ("usb: phy: Add interface to get phy give of device_node.") Fixes: 5d3c28b5a42d ("usb: otg: add device tree support to otg library") Fixes: e842b84c8e72 ("usb: phy: Add interface to get phy give of device_node.") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221103020625.1003759-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/driver-model/devres.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 687adb58048ec..6007ef0704e33 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -387,6 +387,8 @@ PCI PHY devm_usb_get_phy() + devm_usb_get_phy_by_node() + devm_usb_get_phy_by_phandle() devm_usb_put_phy() PINCTRL -- GitLab From dced88922c1179dfa2664690318d4cba57ebffb5 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 26 Oct 2022 20:11:57 +0800 Subject: [PATCH 0409/1480] usb: chipidea: core: wrap ci_handle_power_lost() with CONFIG_PM_SLEEP If CONFIG_PM_SLEEP is not set, the following error will be shown up when build kernel: error: 'ci_handle_power_lost' defined but not used. This will move ci_handle_power_lost() to an area wrapped by CONFIG_PM_SLEEP. Signed-off-by: Xu Yang Fixes: 74494b33211d ("usb: chipidea: core: add controller resume support when controller is powered off") Reported-by: Conor Dooley Tested-by: Conor Dooley Link: https://lore.kernel.org/r/20221026121157.1491302-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 2b170b434d012..484b1cd234317 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -661,25 +661,6 @@ static enum ci_role ci_get_role(struct ci_hdrc *ci) return role; } -static void ci_handle_power_lost(struct ci_hdrc *ci) -{ - enum ci_role role; - - disable_irq_nosync(ci->irq); - if (!ci_otg_is_fsm_mode(ci)) { - role = ci_get_role(ci); - - if (ci->role != role) { - ci_handle_id_switch(ci); - } else if (role == CI_ROLE_GADGET) { - if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV)) - usb_gadget_vbus_connect(&ci->gadget); - } - } - - enable_irq(ci->irq); -} - static struct usb_role_switch_desc ci_role_switch = { .set = ci_usb_role_switch_set, .get = ci_usb_role_switch_get, @@ -1400,6 +1381,25 @@ static int ci_suspend(struct device *dev) return 0; } +static void ci_handle_power_lost(struct ci_hdrc *ci) +{ + enum ci_role role; + + disable_irq_nosync(ci->irq); + if (!ci_otg_is_fsm_mode(ci)) { + role = ci_get_role(ci); + + if (ci->role != role) { + ci_handle_id_switch(ci); + } else if (role == CI_ROLE_GADGET) { + if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV)) + usb_gadget_vbus_connect(&ci->gadget); + } + } + + enable_irq(ci->irq); +} + static int ci_resume(struct device *dev) { struct ci_hdrc *ci = dev_get_drvdata(dev); -- GitLab From c5edb757baa99f6d30180b1a4b4f81f7e7f92217 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Sat, 29 Oct 2022 21:43:12 +0530 Subject: [PATCH 0410/1480] tools: usb: ffs-aio-example: Fix build error with aarch64-*-gnu-gcc toolchain(s) The tools/usb/aio_simple.c file when cross-compiled with aarch64-*-gnu-gcc toolchain(s) leads to the following errors: aio_simple.c:30:10: fatal error: endian.h: No such file or directory 30 | #include | ^~~~~~~~~~ aio_simple.c:88:14: note: (near initialization for 'descriptors.fs_count') aio_simple.c:110:14: error: initializer element is not constant 110 | .hs_count = htole32(3), | ^~~~~~~ aio_simple.c:110:14: note: (near initialization for 'descriptors.hs_count') aio_simple.c:124:22: error: initializer element is not constant 124 | .wMaxPacketSize = htole16(512), | ^~~~~~~ aio_simple.c:124:22: note: (near initialization for 'descriptors.hs_descs.bulk_sink.wMaxPacketSize') Fix these compilation issues by: - Switching to _DEFAULT_SOURCE: _BSD_SOURCE is deprecated and gives a build warning. Let's use _DEFAULT_SOURCE instead. - Currently this file uses library htole16/32 function calls. Replace these with equivalent 'cpu_to_le16/32' calls. Cc: Felipe Balbi Cc: Greg Kroah-Hartman Signed-off-by: Bhupesh Sharma Link: https://lore.kernel.org/r/20221029161312.171165-1-bhupesh.sharma@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../simple/device_app/aio_simple.c | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c index 1f44a29818bf0..96616eb4600b4 100644 --- a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c +++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c @@ -25,7 +25,9 @@ * For more information, please refer to */ -#define _BSD_SOURCE /* for endian.h */ +/* $(CROSS_COMPILE)cc -g -o aio_simple aio_simple.c -laio */ + +#define _DEFAULT_SOURCE /* for endian.h */ #include #include @@ -49,6 +51,22 @@ #define BUF_LEN 8192 +/* + * cpu_to_le16/32 are used when initializing structures, a context where a + * function call is not allowed. To solve this, we code cpu_to_le16/32 in a way + * that allows them to be used when initializing structures. + */ + +#if BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) +#else +#define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)) +#define cpu_to_le32(x) \ + ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \ + (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24)) +#endif + /******************** Descriptors and Strings *******************************/ static const struct { @@ -62,12 +80,12 @@ static const struct { } __attribute__ ((__packed__)) fs_descs, hs_descs; } __attribute__ ((__packed__)) descriptors = { .header = { - .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), - .flags = htole32(FUNCTIONFS_HAS_FS_DESC | + .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), + .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC), - .length = htole32(sizeof(descriptors)), + .length = cpu_to_le32(sizeof(descriptors)), }, - .fs_count = htole32(3), + .fs_count = cpu_to_le32(3), .fs_descs = { .intf = { .bLength = sizeof(descriptors.fs_descs.intf), @@ -89,7 +107,7 @@ static const struct { .bmAttributes = USB_ENDPOINT_XFER_BULK, }, }, - .hs_count = htole32(3), + .hs_count = cpu_to_le32(3), .hs_descs = { .intf = { .bLength = sizeof(descriptors.hs_descs.intf), @@ -103,14 +121,14 @@ static const struct { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = 1 | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = htole16(512), + .wMaxPacketSize = cpu_to_le16(512), }, .bulk_source = { .bLength = sizeof(descriptors.hs_descs.bulk_source), .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = 2 | USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = htole16(512), + .wMaxPacketSize = cpu_to_le16(512), }, }, }; @@ -125,13 +143,13 @@ static const struct { } __attribute__ ((__packed__)) lang0; } __attribute__ ((__packed__)) strings = { .header = { - .magic = htole32(FUNCTIONFS_STRINGS_MAGIC), - .length = htole32(sizeof(strings)), - .str_count = htole32(1), - .lang_count = htole32(1), + .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC), + .length = cpu_to_le32(sizeof(strings)), + .str_count = cpu_to_le32(1), + .lang_count = cpu_to_le32(1), }, .lang0 = { - htole16(0x0409), /* en-us */ + cpu_to_le16(0x0409), /* en-us */ STR_INTERFACE, }, }; -- GitLab From 1dd33a9f1b95ab59cd60f14a7a83fed14697867b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 23 Oct 2022 16:47:06 +0200 Subject: [PATCH 0411/1480] usb: fotg210: Collect pieces of dual mode controller The Faraday FOTG210 is a dual-mode OTG USB controller that can act as host, peripheral or both. To be able to probe from one hardware description and to follow the pattern of other dual- mode controllers such as MUSB or MTU3 we need to collect the two, currently completely separate drivers in the same directory. After this, users need to select the main symbol USB_FOTG210 and then each respective subdriver. We pave the road to compile both drivers into the same kernel and select the one we want to use at probe() time, and possibly add OTG support in the end. This patch doesn't do much more than create the new symbol and collect the drivers in one place. We also add a comment for the section of dual-mode controllers in the Kconfig file so people can see what these selections are about. Also add myself as maintainer as there has been little response on my patches to these drivers. Cc: Fabian Vogt Cc: Yuan-Hsin Chen Cc: Felipe Balbi Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221023144708.3596563-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 ++++ drivers/usb/Kconfig | 4 +++ drivers/usb/Makefile | 2 ++ drivers/usb/fotg210/Kconfig | 36 +++++++++++++++++++ drivers/usb/fotg210/Makefile | 3 ++ drivers/usb/{host => fotg210}/fotg210-hcd.c | 2 +- .../{host/fotg210.h => fotg210/fotg210-hcd.h} | 0 .../usb/{gadget/udc => fotg210}/fotg210-udc.c | 2 +- .../udc/fotg210.h => fotg210/fotg210-udc.h} | 0 drivers/usb/gadget/udc/Kconfig | 11 ------ drivers/usb/gadget/udc/Makefile | 1 - drivers/usb/host/Kconfig | 11 ------ drivers/usb/host/Makefile | 1 - 13 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 drivers/usb/fotg210/Kconfig create mode 100644 drivers/usb/fotg210/Makefile rename drivers/usb/{host => fotg210}/fotg210-hcd.c (99%) rename drivers/usb/{host/fotg210.h => fotg210/fotg210-hcd.h} (100%) rename drivers/usb/{gadget/udc => fotg210}/fotg210-udc.c (99%) rename drivers/usb/{gadget/udc/fotg210.h => fotg210/fotg210-udc.h} (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 379945f82a643..52ddfc938ac91 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7873,6 +7873,12 @@ F: fs/notify/fanotify/ F: include/linux/fanotify.h F: include/uapi/linux/fanotify.h +FARADAY FOTG210 USB2 DUAL-ROLE CONTROLLER +M: Linus Walleij +L: linux-usb@vger.kernel.org +S: Maintained +F: drivers/usb/fotg210/ + FARSYNC SYNCHRONOUS DRIVER M: Kevin Curtis S: Supported diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 578a439e71b57..a871a988829db 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -111,8 +111,12 @@ source "drivers/usb/usbip/Kconfig" endif +comment "USB dual-mode controller drivers" + source "drivers/usb/cdns3/Kconfig" +source "drivers/usb/fotg210/Kconfig" + source "drivers/usb/mtu3/Kconfig" source "drivers/usb/musb/Kconfig" diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 643edf5fe18c6..a81e6ef293af2 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -17,6 +17,8 @@ obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns3/ obj-$(CONFIG_USB_CDNS3) += cdns3/ obj-$(CONFIG_USB_CDNSP_PCI) += cdns3/ +obj-$(CONFIG_USB_FOTG210) += fotg210/ + obj-$(CONFIG_USB_MON) += mon/ obj-$(CONFIG_USB_MTU3) += mtu3/ diff --git a/drivers/usb/fotg210/Kconfig b/drivers/usb/fotg210/Kconfig new file mode 100644 index 0000000000000..e7a106785f5d4 --- /dev/null +++ b/drivers/usb/fotg210/Kconfig @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0 + +config USB_FOTG210 + tristate "Faraday FOTG210 USB2 Dual Role controller" + depends on USB || USB_GADGET + depends on HAS_DMA && HAS_IOMEM + default ARCH_GEMINI + help + Faraday FOTG210 is a dual-mode USB controller that can act + in both host controller and peripheral controller mode. + +if USB_FOTG210 + +config USB_FOTG210_HCD + tristate "Faraday FOTG210 USB Host Controller support" + depends on USB + help + Faraday FOTG210 is an OTG controller which can be configured as + an USB2.0 host. It is designed to meet USB2.0 EHCI specification + with minor modification. + + To compile this driver as a module, choose M here: the + module will be called fotg210-hcd. + +config USB_FOTG210_UDC + depends on USB_GADGET + tristate "Faraday FOTG210 USB Peripheral Controller support" + help + Faraday USB2.0 OTG controller which can be configured as + high speed or full speed USB device. This driver suppports + Bulk Transfer so far. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "fotg210-udc". + +endif diff --git a/drivers/usb/fotg210/Makefile b/drivers/usb/fotg210/Makefile new file mode 100644 index 0000000000000..f4a26ca0e5639 --- /dev/null +++ b/drivers/usb/fotg210/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o +obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/fotg210/fotg210-hcd.c similarity index 99% rename from drivers/usb/host/fotg210-hcd.c rename to drivers/usb/fotg210/fotg210-hcd.c index 3d1dbcf4c0732..8fbf63e76d7d1 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/fotg210/fotg210-hcd.c @@ -77,7 +77,7 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us"); #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) -#include "fotg210.h" +#include "fotg210-hcd.h" #define fotg210_dbg(fotg210, fmt, args...) \ dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args) diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/fotg210/fotg210-hcd.h similarity index 100% rename from drivers/usb/host/fotg210.h rename to drivers/usb/fotg210/fotg210-hcd.h diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c similarity index 99% rename from drivers/usb/gadget/udc/fotg210-udc.c rename to drivers/usb/fotg210/fotg210-udc.c index fdca28e72a3b4..01a4509775b2b 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -16,7 +16,7 @@ #include #include -#include "fotg210.h" +#include "fotg210-udc.h" #define DRIVER_DESC "FOTG210 USB Device Controller Driver" #define DRIVER_VERSION "30-April-2013" diff --git a/drivers/usb/gadget/udc/fotg210.h b/drivers/usb/fotg210/fotg210-udc.h similarity index 100% rename from drivers/usb/gadget/udc/fotg210.h rename to drivers/usb/fotg210/fotg210-udc.h diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 5756acb07b8da..16243964b1cd1 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -108,17 +108,6 @@ config USB_FUSB300 help Faraday usb device controller FUSB300 driver -config USB_FOTG210_UDC - depends on HAS_DMA - tristate "Faraday FOTG210 USB Peripheral Controller" - help - Faraday USB2.0 OTG controller which can be configured as - high speed or full speed USB device. This driver supppors - Bulk Transfer so far. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "fotg210_udc". - config USB_GR_UDC tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver" depends on HAS_DMA diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index 12f9e4c9eb0c5..39daf36a2baa2 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_USB_EG20T) += pch_udc.o obj-$(CONFIG_USB_MV_UDC) += mv_udc.o mv_udc-y := mv_udc_core.o obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o -obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o obj-$(CONFIG_USB_GR_UDC) += gr_udc.o obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8e8db71021a54..8d799d23c476e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -389,17 +389,6 @@ config USB_ISP1362_HCD To compile this driver as a module, choose M here: the module will be called isp1362-hcd. -config USB_FOTG210_HCD - tristate "FOTG210 HCD support" - depends on USB && HAS_DMA && HAS_IOMEM - help - Faraday FOTG210 is an OTG controller which can be configured as - an USB2.0 host. It is designed to meet USB2.0 EHCI specification - with minor modification. - - To compile this driver as a module, choose M here: the - module will be called fotg210-hcd. - config USB_MAX3421_HCD tristate "MAX3421 HCD (USB-over-SPI) support" depends on USB && SPI diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 2c8a61be7e466..6d8ee264c9b2b 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -84,6 +84,5 @@ obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o obj-$(CONFIG_USB_EHCI_MV) += ehci-mv.o obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o -obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o obj-$(CONFIG_USB_MAX3421_HCD) += max3421-hcd.o obj-$(CONFIG_USB_XEN_HCD) += xen-hcd.o -- GitLab From aeffd2c3b09f4f50438ec8960095129798bcb33a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 23 Oct 2022 16:47:07 +0200 Subject: [PATCH 0412/1480] usb: fotg210: Compile into one module It is since ages perfectly possible to compile both of these modules into the same kernel, which makes no sense since it is one piece of hardware. Compile one module named "fotg210.ko" for both HCD and UDC drivers by collecting the init calls into a fotg210-core.c file and start to centralize things handling one and the same piece of hardware. Stub out the initcalls if one or the other part of the driver was not selected. Tested by compiling one or the other or both of the drivers into the kernel and as modules. Cc: Fabian Vogt Cc: Yuan-Hsin Chen Cc: Felipe Balbi Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221023144708.3596563-2-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/Kconfig | 4 +- drivers/usb/fotg210/Makefile | 11 ++++- drivers/usb/fotg210/fotg210-core.c | 79 ++++++++++++++++++++++++++++++ drivers/usb/fotg210/fotg210-hcd.c | 49 +++--------------- drivers/usb/fotg210/fotg210-udc.c | 19 ++----- drivers/usb/fotg210/fotg210.h | 42 ++++++++++++++++ 6 files changed, 142 insertions(+), 62 deletions(-) create mode 100644 drivers/usb/fotg210/fotg210-core.c create mode 100644 drivers/usb/fotg210/fotg210.h diff --git a/drivers/usb/fotg210/Kconfig b/drivers/usb/fotg210/Kconfig index e7a106785f5d4..933c513b5728e 100644 --- a/drivers/usb/fotg210/Kconfig +++ b/drivers/usb/fotg210/Kconfig @@ -12,7 +12,7 @@ config USB_FOTG210 if USB_FOTG210 config USB_FOTG210_HCD - tristate "Faraday FOTG210 USB Host Controller support" + bool "Faraday FOTG210 USB Host Controller support" depends on USB help Faraday FOTG210 is an OTG controller which can be configured as @@ -24,7 +24,7 @@ config USB_FOTG210_HCD config USB_FOTG210_UDC depends on USB_GADGET - tristate "Faraday FOTG210 USB Peripheral Controller support" + bool "Faraday FOTG210 USB Peripheral Controller support" help Faraday USB2.0 OTG controller which can be configured as high speed or full speed USB device. This driver suppports diff --git a/drivers/usb/fotg210/Makefile b/drivers/usb/fotg210/Makefile index f4a26ca0e5639..5aecff21f24b8 100644 --- a/drivers/usb/fotg210/Makefile +++ b/drivers/usb/fotg210/Makefile @@ -1,3 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o -obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o + +# This setup links the different object files into one single +# module so we don't have to EXPORT() a lot of internal symbols +# or create unnecessary submodules. +fotg210-objs-y += fotg210-core.o +fotg210-objs-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o +fotg210-objs-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o +fotg210-objs := $(fotg210-objs-y) +obj-$(CONFIG_USB_FOTG210) += fotg210.o diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c new file mode 100644 index 0000000000000..ab7b8974bc18b --- /dev/null +++ b/drivers/usb/fotg210/fotg210-core.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Central probing code for the FOTG210 dual role driver + * We register one driver for the hardware and then we decide + * whether to proceed with probing the host or the peripheral + * driver. + */ +#include +#include +#include +#include +#include + +#include "fotg210.h" + +static int fotg210_probe(struct platform_device *pdev) +{ + int ret; + + if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) { + ret = fotg210_hcd_probe(pdev); + if (ret) + return ret; + } + if (IS_ENABLED(CONFIG_USB_FOTG210_UDC)) + ret = fotg210_udc_probe(pdev); + + return ret; +} + +static int fotg210_remove(struct platform_device *pdev) +{ + if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) + fotg210_hcd_remove(pdev); + if (IS_ENABLED(CONFIG_USB_FOTG210_UDC)) + fotg210_udc_remove(pdev); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id fotg210_of_match[] = { + { .compatible = "faraday,fotg210" }, + {}, +}; +MODULE_DEVICE_TABLE(of, fotg210_of_match); +#endif + +static struct platform_driver fotg210_driver = { + .driver = { + .name = "fotg210", + .of_match_table = of_match_ptr(fotg210_of_match), + }, + .probe = fotg210_probe, + .remove = fotg210_remove, +}; + +static int __init fotg210_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) + fotg210_hcd_init(); + return platform_driver_register(&fotg210_driver); +} +module_init(fotg210_init); + +static void __exit fotg210_cleanup(void) +{ + platform_driver_unregister(&fotg210_driver); + if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) + fotg210_hcd_cleanup(); +} +module_exit(fotg210_cleanup); + +MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FOTG210 Dual Role Controller Driver"); diff --git a/drivers/usb/fotg210/fotg210-hcd.c b/drivers/usb/fotg210/fotg210-hcd.c index 8fbf63e76d7d1..51ac93a2eb98e 100644 --- a/drivers/usb/fotg210/fotg210-hcd.c +++ b/drivers/usb/fotg210/fotg210-hcd.c @@ -39,8 +39,8 @@ #include #include -#define DRIVER_AUTHOR "Yuan-Hsin Chen" -#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver" +#include "fotg210.h" + static const char hcd_name[] = "fotg210_hcd"; #undef FOTG210_URB_TRACE @@ -5490,9 +5490,6 @@ static int fotg210_get_frame(struct usb_hcd *hcd) * functions and in order to facilitate role switching we cannot * give the fotg210 driver exclusive access to those. */ -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); static const struct hc_driver fotg210_fotg210_hc_driver = { .description = hcd_name, @@ -5560,7 +5557,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210) * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int fotg210_hcd_probe(struct platform_device *pdev) +int fotg210_hcd_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_hcd *hcd; @@ -5652,7 +5649,7 @@ fail_create_hcd: * @dev: USB Host Controller being removed * */ -static int fotg210_hcd_remove(struct platform_device *pdev) +int fotg210_hcd_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd); @@ -5668,27 +5665,8 @@ static int fotg210_hcd_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF -static const struct of_device_id fotg210_of_match[] = { - { .compatible = "faraday,fotg210" }, - {}, -}; -MODULE_DEVICE_TABLE(of, fotg210_of_match); -#endif - -static struct platform_driver fotg210_hcd_driver = { - .driver = { - .name = "fotg210-hcd", - .of_match_table = of_match_ptr(fotg210_of_match), - }, - .probe = fotg210_hcd_probe, - .remove = fotg210_hcd_remove, -}; - -static int __init fotg210_hcd_init(void) +int __init fotg210_hcd_init(void) { - int retval = 0; - if (usb_disabled()) return -ENODEV; @@ -5704,24 +5682,11 @@ static int __init fotg210_hcd_init(void) fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root); - retval = platform_driver_register(&fotg210_hcd_driver); - if (retval < 0) - goto clean; - return retval; - -clean: - debugfs_remove(fotg210_debug_root); - fotg210_debug_root = NULL; - - clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); - return retval; + return 0; } -module_init(fotg210_hcd_init); -static void __exit fotg210_hcd_cleanup(void) +void __exit fotg210_hcd_cleanup(void) { - platform_driver_unregister(&fotg210_hcd_driver); debugfs_remove(fotg210_debug_root); clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); } -module_exit(fotg210_hcd_cleanup); diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 01a4509775b2b..7757aaa11d6f6 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -16,6 +16,7 @@ #include #include +#include "fotg210.h" #include "fotg210-udc.h" #define DRIVER_DESC "FOTG210 USB Device Controller Driver" @@ -1068,7 +1069,7 @@ static const struct usb_gadget_ops fotg210_gadget_ops = { .udc_stop = fotg210_udc_stop, }; -static int fotg210_udc_remove(struct platform_device *pdev) +int fotg210_udc_remove(struct platform_device *pdev) { struct fotg210_udc *fotg210 = platform_get_drvdata(pdev); int i; @@ -1085,7 +1086,7 @@ static int fotg210_udc_remove(struct platform_device *pdev) return 0; } -static int fotg210_udc_probe(struct platform_device *pdev) +int fotg210_udc_probe(struct platform_device *pdev) { struct resource *res, *ires; struct fotg210_udc *fotg210 = NULL; @@ -1208,17 +1209,3 @@ err_alloc: err: return ret; } - -static struct platform_driver fotg210_driver = { - .driver = { - .name = udc_name, - }, - .probe = fotg210_udc_probe, - .remove = fotg210_udc_remove, -}; - -module_platform_driver(fotg210_driver); - -MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/usb/fotg210/fotg210.h b/drivers/usb/fotg210/fotg210.h new file mode 100644 index 0000000000000..ef79d8323d897 --- /dev/null +++ b/drivers/usb/fotg210/fotg210.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __FOTG210_H +#define __FOTG210_H + +#ifdef CONFIG_USB_FOTG210_HCD +int fotg210_hcd_probe(struct platform_device *pdev); +int fotg210_hcd_remove(struct platform_device *pdev); +int fotg210_hcd_init(void); +void fotg210_hcd_cleanup(void); +#else +static inline int fotg210_hcd_probe(struct platform_device *pdev) +{ + return 0; +} +static inline int fotg210_hcd_remove(struct platform_device *pdev) +{ + return 0; +} +static inline int fotg210_hcd_init(void) +{ + return 0; +} +static inline void fotg210_hcd_cleanup(void) +{ +} +#endif + +#ifdef CONFIG_USB_FOTG210_UDC +int fotg210_udc_probe(struct platform_device *pdev); +int fotg210_udc_remove(struct platform_device *pdev); +#else +static inline int fotg210_udc_probe(struct platform_device *pdev) +{ + return 0; +} +static inline int fotg210_udc_remove(struct platform_device *pdev) +{ + return 0; +} +#endif + +#endif /* __FOTG210_H */ -- GitLab From 1fac1c4da8a225ffbfae294ae36e18a3a65cb87e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 23 Oct 2022 16:47:08 +0200 Subject: [PATCH 0413/1480] usb: fotg210: Select subdriver by mode Check which mode the hardware is in, and selecte the peripheral driver if the hardware is in explicit peripheral mode, otherwise select host mode. This should solve the immediate problem that both subdrivers can get probed. Cc: Fabian Vogt Cc: Yuan-Hsin Chen Cc: Felipe Balbi Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221023144708.3596563-3-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-core.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c index ab7b8974bc18b..3d07ee46f6d1d 100644 --- a/drivers/usb/fotg210/fotg210-core.c +++ b/drivers/usb/fotg210/fotg210-core.c @@ -10,30 +10,37 @@ #include #include #include +#include #include "fotg210.h" static int fotg210_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + enum usb_dr_mode mode; int ret; - if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) { - ret = fotg210_hcd_probe(pdev); - if (ret) - return ret; - } - if (IS_ENABLED(CONFIG_USB_FOTG210_UDC)) + mode = usb_get_dr_mode(dev); + + if (mode == USB_DR_MODE_PERIPHERAL) ret = fotg210_udc_probe(pdev); + else + ret = fotg210_hcd_probe(pdev); return ret; } static int fotg210_remove(struct platform_device *pdev) { - if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) - fotg210_hcd_remove(pdev); - if (IS_ENABLED(CONFIG_USB_FOTG210_UDC)) + struct device *dev = &pdev->dev; + enum usb_dr_mode mode; + + mode = usb_get_dr_mode(dev); + + if (mode == USB_DR_MODE_PERIPHERAL) fotg210_udc_remove(pdev); + else + fotg210_hcd_remove(pdev); return 0; } -- GitLab From 21acc656a06e912341d9db66c67b58cc7ed071e7 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:51 +0100 Subject: [PATCH 0414/1480] usb: musb: Add and use inline functions musb_{get,set}_state Instead of manipulating musb->xceiv->otg->state directly, use the newly introduced musb_get_state() and musb_set_state() inline functions. Later, these inline functions will be modified to get rid of the musb->xceiv dependency, which prevents the musb code from using the generic PHY subsystem. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-2-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 62 ++++++++++++++++----------------- drivers/usb/musb/musb_core.h | 11 ++++++ drivers/usb/musb/musb_debugfs.c | 6 ++-- drivers/usb/musb/musb_gadget.c | 28 +++++++-------- drivers/usb/musb/musb_host.c | 6 ++-- drivers/usb/musb/musb_virthub.c | 18 +++++----- 6 files changed, 71 insertions(+), 60 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 03027c6fa3aba..a0fe2516870bf 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -502,7 +502,7 @@ int musb_set_host(struct musb *musb) init_data: musb->is_active = 1; - musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb_set_state(musb, OTG_STATE_A_IDLE); MUSB_HST_MODE(musb); return error; @@ -549,7 +549,7 @@ int musb_set_peripheral(struct musb *musb) init_data: musb->is_active = 0; - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); MUSB_DEV_MODE(musb); return error; @@ -599,12 +599,12 @@ static void musb_otg_timer_func(struct timer_list *t) unsigned long flags; spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_B_WAIT_ACON: musb_dbg(musb, "HNP: b_wait_acon timeout; back to b_peripheral"); musb_g_disconnect(musb); - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb->is_active = 0; break; case OTG_STATE_A_SUSPEND: @@ -612,7 +612,7 @@ static void musb_otg_timer_func(struct timer_list *t) musb_dbg(musb, "HNP: %s timeout", usb_otg_state_string(musb->xceiv->otg->state)); musb_platform_set_vbus(musb, 0); - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; + musb_set_state(musb, OTG_STATE_A_WAIT_VFALL); break; default: musb_dbg(musb, "HNP: Unhandled mode %s", @@ -633,7 +633,7 @@ void musb_hnp_stop(struct musb *musb) musb_dbg(musb, "HNP: stop from %s", usb_otg_state_string(musb->xceiv->otg->state)); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); musb_dbg(musb, "HNP: back to %s", @@ -643,7 +643,7 @@ void musb_hnp_stop(struct musb *musb) musb_dbg(musb, "HNP: Disabling HR"); if (hcd) hcd->self.is_b_host = 0; - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); MUSB_DEV_MODE(musb); reg = musb_readb(mbase, MUSB_POWER); reg |= MUSB_POWER_SUSPENDM; @@ -671,7 +671,7 @@ static void musb_handle_intr_resume(struct musb *musb, u8 devctl) usb_otg_state_string(musb->xceiv->otg->state)); if (devctl & MUSB_DEVCTL_HM) { - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: /* remote wakeup? */ musb->port1_status |= @@ -679,14 +679,14 @@ static void musb_handle_intr_resume(struct musb *musb, u8 devctl) | MUSB_PORT_STAT_RESUME; musb->rh_timer = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); - musb->xceiv->otg->state = OTG_STATE_A_HOST; + musb_set_state(musb, OTG_STATE_A_HOST); musb->is_active = 1; musb_host_resume_root_hub(musb); schedule_delayed_work(&musb->finish_resume_work, msecs_to_jiffies(USB_RESUME_TIMEOUT)); break; case OTG_STATE_B_WAIT_ACON: - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb->is_active = 1; MUSB_DEV_MODE(musb); break; @@ -696,10 +696,10 @@ static void musb_handle_intr_resume(struct musb *musb, u8 devctl) usb_otg_state_string(musb->xceiv->otg->state)); } } else { - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: /* possibly DISCONNECT is upcoming */ - musb->xceiv->otg->state = OTG_STATE_A_HOST; + musb_set_state(musb, OTG_STATE_A_HOST); musb_host_resume_root_hub(musb); break; case OTG_STATE_B_WAIT_ACON: @@ -750,7 +750,7 @@ static irqreturn_t musb_handle_intr_sessreq(struct musb *musb, u8 devctl) */ musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); musb->ep0_stage = MUSB_EP0_START; - musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb_set_state(musb, OTG_STATE_A_IDLE); MUSB_HST_MODE(musb); musb_platform_set_vbus(musb, 1); @@ -777,7 +777,7 @@ static void musb_handle_intr_vbuserr(struct musb *musb, u8 devctl) * REVISIT: do delays from lots of DEBUG_KERNEL checks * make trouble here, keeping VBUS < 4.4V ? */ - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: /* recovery is dicey once we've gotten past the * initial stages of enumeration, but if VBUS @@ -833,7 +833,7 @@ static void musb_handle_intr_suspend(struct musb *musb, u8 devctl) musb_dbg(musb, "SUSPEND (%s) devctl %02x", usb_otg_state_string(musb->xceiv->otg->state), devctl); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_PERIPHERAL: /* We also come here if the cable is removed, since * this silicon doesn't report ID-no-longer-grounded. @@ -858,7 +858,7 @@ static void musb_handle_intr_suspend(struct musb *musb, u8 devctl) musb_g_suspend(musb); musb->is_active = musb->g.b_hnp_enable; if (musb->is_active) { - musb->xceiv->otg->state = OTG_STATE_B_WAIT_ACON; + musb_set_state(musb, OTG_STATE_B_WAIT_ACON); musb_dbg(musb, "HNP: Setting timer for b_ase0_brst"); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies( @@ -871,7 +871,7 @@ static void musb_handle_intr_suspend(struct musb *musb, u8 devctl) + msecs_to_jiffies(musb->a_wait_bcon)); break; case OTG_STATE_A_HOST: - musb->xceiv->otg->state = OTG_STATE_A_SUSPEND; + musb_set_state(musb, OTG_STATE_A_SUSPEND); musb->is_active = musb->hcd->self.b_hnp_enable; break; case OTG_STATE_B_HOST: @@ -909,7 +909,7 @@ static void musb_handle_intr_connect(struct musb *musb, u8 devctl, u8 int_usb) musb->port1_status |= USB_PORT_STAT_LOW_SPEED; /* indicate new connection to OTG machine */ - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_B_PERIPHERAL: if (int_usb & MUSB_INTR_SUSPEND) { musb_dbg(musb, "HNP: SUSPEND+CONNECT, now b_host"); @@ -921,7 +921,7 @@ static void musb_handle_intr_connect(struct musb *musb, u8 devctl, u8 int_usb) case OTG_STATE_B_WAIT_ACON: musb_dbg(musb, "HNP: CONNECT, now b_host"); b_host: - musb->xceiv->otg->state = OTG_STATE_B_HOST; + musb_set_state(musb, OTG_STATE_B_HOST); if (musb->hcd) musb->hcd->self.is_b_host = 1; del_timer(&musb->otg_timer); @@ -929,7 +929,7 @@ b_host: default: if ((devctl & MUSB_DEVCTL_VBUS) == (3 << MUSB_DEVCTL_VBUS_SHIFT)) { - musb->xceiv->otg->state = OTG_STATE_A_HOST; + musb_set_state(musb, OTG_STATE_A_HOST); if (hcd) hcd->self.is_b_host = 0; } @@ -948,7 +948,7 @@ static void musb_handle_intr_disconnect(struct musb *musb, u8 devctl) usb_otg_state_string(musb->xceiv->otg->state), MUSB_MODE(musb), devctl); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: case OTG_STATE_A_SUSPEND: musb_host_resume_root_hub(musb); @@ -966,7 +966,7 @@ static void musb_handle_intr_disconnect(struct musb *musb, u8 devctl) musb_root_disconnect(musb); if (musb->hcd) musb->hcd->self.is_b_host = 0; - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); MUSB_DEV_MODE(musb); musb_g_disconnect(musb); break; @@ -1006,7 +1006,7 @@ static void musb_handle_intr_reset(struct musb *musb) } else { musb_dbg(musb, "BUS RESET as %s", usb_otg_state_string(musb->xceiv->otg->state)); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: musb_g_reset(musb); fallthrough; @@ -1025,11 +1025,11 @@ static void musb_handle_intr_reset(struct musb *musb) case OTG_STATE_B_WAIT_ACON: musb_dbg(musb, "HNP: RESET (%s), to b_peripheral", usb_otg_state_string(musb->xceiv->otg->state)); - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb_g_reset(musb); break; case OTG_STATE_B_IDLE: - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); fallthrough; case OTG_STATE_B_PERIPHERAL: musb_g_reset(musb); @@ -1216,8 +1216,8 @@ void musb_start(struct musb *musb) * (c) peripheral initiates, using SRP */ if (musb->port_mode != MUSB_HOST && - musb->xceiv->otg->state != OTG_STATE_A_WAIT_BCON && - (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { + musb_get_state(musb) != OTG_STATE_A_WAIT_BCON && + (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { musb->is_active = 1; } else { devctl |= MUSB_DEVCTL_SESSION; @@ -1908,7 +1908,7 @@ vbus_store(struct device *dev, struct device_attribute *attr, spin_lock_irqsave(&musb->lock, flags); /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; - if (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON) + if (musb_get_state(musb) == OTG_STATE_A_WAIT_BCON) musb->is_active = 0; musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); spin_unlock_irqrestore(&musb->lock, flags); @@ -2089,8 +2089,8 @@ static void musb_irq_work(struct work_struct *data) musb_pm_runtime_check_session(musb); - if (musb->xceiv->otg->state != musb->xceiv_old_state) { - musb->xceiv_old_state = musb->xceiv->otg->state; + if (musb_get_state(musb) != musb->xceiv_old_state) { + musb->xceiv_old_state = musb_get_state(musb); sysfs_notify(&musb->controller->kobj, NULL, "mode"); } @@ -2532,7 +2532,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) } MUSB_DEV_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); switch (musb->port_mode) { case MUSB_HOST: diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index a8a65effe68b5..4a4d485d37bd3 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -592,6 +592,17 @@ static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum) musb->ops->clear_ep_rxintr(musb, epnum); } +static inline void musb_set_state(struct musb *musb, + enum usb_otg_state otg_state) +{ + musb->xceiv->otg->state = otg_state; +} + +static inline enum usb_otg_state musb_get_state(struct musb *musb) +{ + return musb->xceiv->otg->state; +} + /* * gets the "dr_mode" property from DT and converts it into musb_mode * if the property is not found or not recognized returns MUSB_OTG diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 30a89aa8a3e7a..78c726a71b177 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -235,7 +235,7 @@ static int musb_softconnect_show(struct seq_file *s, void *unused) u8 reg; int connect; - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: case OTG_STATE_A_WAIT_BCON: pm_runtime_get_sync(musb->controller); @@ -275,7 +275,7 @@ static ssize_t musb_softconnect_write(struct file *file, pm_runtime_get_sync(musb->controller); if (!strncmp(buf, "0", 1)) { - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: musb_root_disconnect(musb); reg = musb_readb(musb->mregs, MUSB_DEVCTL); @@ -286,7 +286,7 @@ static ssize_t musb_softconnect_write(struct file *file, break; } } else if (!strncmp(buf, "1", 1)) { - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_WAIT_BCON: /* * musb_save_context() called in musb_runtime_suspend() diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6704a62a16659..b5c7deb288d25 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1523,7 +1523,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_B_PERIPHERAL: /* NOTE: OTG state machine doesn't include B_SUSPENDED; * that's part of the standard usb 1.1 state machine, and @@ -1787,7 +1787,7 @@ int musb_gadget_setup(struct musb *musb) musb->g.speed = USB_SPEED_UNKNOWN; MUSB_DEV_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); /* this "gadget" abstracts/virtualizes the controller */ musb->g.name = musb_driver_name; @@ -1852,7 +1852,7 @@ static int musb_gadget_start(struct usb_gadget *g, musb->is_active = 1; otg_set_peripheral(otg, &musb->g); - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); spin_unlock_irqrestore(&musb->lock, flags); musb_start(musb); @@ -1897,7 +1897,7 @@ static int musb_gadget_stop(struct usb_gadget *g) (void) musb_gadget_vbus_draw(&musb->g, 0); - musb->xceiv->otg->state = OTG_STATE_UNDEFINED; + musb_set_state(musb, OTG_STATE_UNDEFINED); musb_stop(musb); otg_set_peripheral(musb->xceiv->otg, NULL); @@ -1926,7 +1926,7 @@ static int musb_gadget_stop(struct usb_gadget *g) void musb_g_resume(struct musb *musb) { musb->is_suspended = 0; - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_B_IDLE: break; case OTG_STATE_B_WAIT_ACON: @@ -1952,10 +1952,10 @@ void musb_g_suspend(struct musb *musb) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); musb_dbg(musb, "musb_g_suspend: devctl %02x", devctl); - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_B_IDLE: if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); break; case OTG_STATE_B_PERIPHERAL: musb->is_suspended = 1; @@ -2001,22 +2001,22 @@ void musb_g_disconnect(struct musb *musb) spin_lock(&musb->lock); } - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { default: musb_dbg(musb, "Unhandled disconnect %s, setting a_idle", usb_otg_state_string(musb->xceiv->otg->state)); - musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb_set_state(musb, OTG_STATE_A_IDLE); MUSB_HST_MODE(musb); break; case OTG_STATE_A_PERIPHERAL: - musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; + musb_set_state(musb, OTG_STATE_A_WAIT_BCON); MUSB_HST_MODE(musb); break; case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_IDLE: - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); break; case OTG_STATE_B_SRP_INIT: break; @@ -2080,13 +2080,13 @@ __acquires(musb->lock) * In that case, do not rely on devctl for setting * peripheral mode. */ - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb->g.is_a_peripheral = 0; } else if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; + musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb->g.is_a_peripheral = 0; } else { - musb->xceiv->otg->state = OTG_STATE_A_PERIPHERAL; + musb_set_state(musb, OTG_STATE_A_PERIPHERAL); musb->g.is_a_peripheral = 1; } diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 9ff7d891b4b76..ed631447a253c 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2501,7 +2501,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (!is_host_active(musb)) return 0; - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: return 0; case OTG_STATE_A_WAIT_VRISE: @@ -2511,7 +2511,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) */ devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) - musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; + musb_set_state(musb, OTG_STATE_A_WAIT_BCON); break; default: break; @@ -2720,7 +2720,7 @@ int musb_host_setup(struct musb *musb, int power_budget) if (musb->port_mode == MUSB_HOST) { MUSB_HST_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb_set_state(musb, OTG_STATE_A_IDLE); } otg_set_host(musb->xceiv->otg, &hcd->self); /* don't support otg protocols */ diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index cafc69536e1d7..d1cfd45d69e36 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -43,7 +43,7 @@ void musb_host_finish_resume(struct work_struct *work) musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; usb_hcd_poll_rh_status(musb->hcd); /* NOTE: it might really be A_WAIT_BCON ... */ - musb->xceiv->otg->state = OTG_STATE_A_HOST; + musb_set_state(musb, OTG_STATE_A_HOST); spin_unlock_irqrestore(&musb->lock, flags); } @@ -85,9 +85,9 @@ int musb_port_suspend(struct musb *musb, bool do_suspend) musb_dbg(musb, "Root port suspended, power %02x", power); musb->port1_status |= USB_PORT_STAT_SUSPEND; - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: - musb->xceiv->otg->state = OTG_STATE_A_SUSPEND; + musb_set_state(musb, OTG_STATE_A_SUSPEND); musb->is_active = otg->host->b_hnp_enable; if (musb->is_active) mod_timer(&musb->otg_timer, jiffies @@ -96,7 +96,7 @@ int musb_port_suspend(struct musb *musb, bool do_suspend) musb_platform_try_idle(musb, 0); break; case OTG_STATE_B_HOST: - musb->xceiv->otg->state = OTG_STATE_B_WAIT_ACON; + musb_set_state(musb, OTG_STATE_B_WAIT_ACON); musb->is_active = otg->host->b_hnp_enable; musb_platform_try_idle(musb, 0); break; @@ -123,7 +123,7 @@ void musb_port_reset(struct musb *musb, bool do_reset) u8 power; void __iomem *mbase = musb->mregs; - if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) { + if (musb_get_state(musb) == OTG_STATE_B_IDLE) { musb_dbg(musb, "HNP: Returning from HNP; no hub reset from b_idle"); musb->port1_status &= ~USB_PORT_STAT_RESET; return; @@ -204,20 +204,20 @@ void musb_root_disconnect(struct musb *musb) usb_hcd_poll_rh_status(musb->hcd); musb->is_active = 0; - switch (musb->xceiv->otg->state) { + switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: if (otg->host->b_hnp_enable) { - musb->xceiv->otg->state = OTG_STATE_A_PERIPHERAL; + musb_set_state(musb, OTG_STATE_A_PERIPHERAL); musb->g.is_a_peripheral = 1; break; } fallthrough; case OTG_STATE_A_HOST: - musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; + musb_set_state(musb, OTG_STATE_A_WAIT_BCON); musb->is_active = 0; break; case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->otg->state = OTG_STATE_B_IDLE; + musb_set_state(musb, OTG_STATE_B_IDLE); break; default: musb_dbg(musb, "host disconnect (%s)", -- GitLab From 285f28bfed89a56ed619054f21125b0bd2f0d4d6 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:52 +0100 Subject: [PATCH 0415/1480] usb: musb: Add and use inline function musb_otg_state_string The musb_otg_state_string() simply calls usb_otg_state_string(). This will make it easier to get rid of the musb->xceiv dependency later. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-3-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 43 +++++++++++++++------------------ drivers/usb/musb/musb_core.h | 5 ++++ drivers/usb/musb/musb_gadget.c | 8 +++--- drivers/usb/musb/musb_host.c | 2 +- drivers/usb/musb/musb_virthub.c | 4 +-- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index a0fe2516870bf..9bf0ebaa3b7cf 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -610,13 +610,13 @@ static void musb_otg_timer_func(struct timer_list *t) case OTG_STATE_A_SUSPEND: case OTG_STATE_A_WAIT_BCON: musb_dbg(musb, "HNP: %s timeout", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); musb_platform_set_vbus(musb, 0); musb_set_state(musb, OTG_STATE_A_WAIT_VFALL); break; default: musb_dbg(musb, "HNP: Unhandled mode %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } spin_unlock_irqrestore(&musb->lock, flags); } @@ -630,14 +630,12 @@ void musb_hnp_stop(struct musb *musb) void __iomem *mbase = musb->mregs; u8 reg; - musb_dbg(musb, "HNP: stop from %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_dbg(musb, "HNP: stop from %s", musb_otg_state_string(musb)); switch (musb_get_state(musb)) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); - musb_dbg(musb, "HNP: back to %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_dbg(musb, "HNP: back to %s", musb_otg_state_string(musb)); break; case OTG_STATE_B_HOST: musb_dbg(musb, "HNP: Disabling HR"); @@ -652,7 +650,7 @@ void musb_hnp_stop(struct musb *musb) break; default: musb_dbg(musb, "HNP: Stopping in unknown state %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } /* @@ -667,8 +665,7 @@ static void musb_recover_from_babble(struct musb *musb); static void musb_handle_intr_resume(struct musb *musb, u8 devctl) { - musb_dbg(musb, "RESUME (%s)", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_dbg(musb, "RESUME (%s)", musb_otg_state_string(musb)); if (devctl & MUSB_DEVCTL_HM) { switch (musb_get_state(musb)) { @@ -693,7 +690,7 @@ static void musb_handle_intr_resume(struct musb *musb, u8 devctl) default: WARNING("bogus %s RESUME (%s)\n", "host", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } else { switch (musb_get_state(musb)) { @@ -722,7 +719,7 @@ static void musb_handle_intr_resume(struct musb *musb, u8 devctl) default: WARNING("bogus %s RESUME (%s)\n", "peripheral", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } } @@ -738,8 +735,7 @@ static irqreturn_t musb_handle_intr_sessreq(struct musb *musb, u8 devctl) return IRQ_HANDLED; } - musb_dbg(musb, "SESSION_REQUEST (%s)", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_dbg(musb, "SESSION_REQUEST (%s)", musb_otg_state_string(musb)); /* IRQ arrives from ID pin sense or (later, if VBUS power * is removed) SRP. responses are time critical: @@ -806,7 +802,7 @@ static void musb_handle_intr_vbuserr(struct musb *musb, u8 devctl) dev_printk(ignore ? KERN_DEBUG : KERN_ERR, musb->controller, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n", - usb_otg_state_string(musb->xceiv->otg->state), + musb_otg_state_string(musb), devctl, ({ char *s; switch (devctl & MUSB_DEVCTL_VBUS) { @@ -831,7 +827,7 @@ static void musb_handle_intr_vbuserr(struct musb *musb, u8 devctl) static void musb_handle_intr_suspend(struct musb *musb, u8 devctl) { musb_dbg(musb, "SUSPEND (%s) devctl %02x", - usb_otg_state_string(musb->xceiv->otg->state), devctl); + musb_otg_state_string(musb), devctl); switch (musb_get_state(musb)) { case OTG_STATE_A_PERIPHERAL: @@ -939,13 +935,13 @@ b_host: musb_host_poke_root_hub(musb); musb_dbg(musb, "CONNECT (%s) devctl %02x", - usb_otg_state_string(musb->xceiv->otg->state), devctl); + musb_otg_state_string(musb), devctl); } static void musb_handle_intr_disconnect(struct musb *musb, u8 devctl) { musb_dbg(musb, "DISCONNECT (%s) as %s, devctl %02x", - usb_otg_state_string(musb->xceiv->otg->state), + musb_otg_state_string(musb), MUSB_MODE(musb), devctl); switch (musb_get_state(musb)) { @@ -981,7 +977,7 @@ static void musb_handle_intr_disconnect(struct musb *musb, u8 devctl) break; default: WARNING("unhandled DISCONNECT transition (%s)\n", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); break; } } @@ -1004,8 +1000,7 @@ static void musb_handle_intr_reset(struct musb *musb) dev_err(musb->controller, "Babble\n"); musb_recover_from_babble(musb); } else { - musb_dbg(musb, "BUS RESET as %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_dbg(musb, "BUS RESET as %s", musb_otg_state_string(musb)); switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: musb_g_reset(musb); @@ -1013,7 +1008,7 @@ static void musb_handle_intr_reset(struct musb *musb) case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ /* never use invalid T(a_wait_bcon) */ musb_dbg(musb, "HNP: in %s, %d msec timeout", - usb_otg_state_string(musb->xceiv->otg->state), + musb_otg_state_string(musb), TA_WAIT_BCON(musb)); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies(TA_WAIT_BCON(musb))); @@ -1024,7 +1019,7 @@ static void musb_handle_intr_reset(struct musb *musb) break; case OTG_STATE_B_WAIT_ACON: musb_dbg(musb, "HNP: RESET (%s), to b_peripheral", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); musb_set_state(musb, OTG_STATE_B_PERIPHERAL); musb_g_reset(musb); break; @@ -1036,7 +1031,7 @@ static void musb_handle_intr_reset(struct musb *musb) break; default: musb_dbg(musb, "Unhandled BUS RESET as %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } } @@ -1863,7 +1858,7 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf) int ret; spin_lock_irqsave(&musb->lock, flags); - ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->otg->state)); + ret = sprintf(buf, "%s\n", musb_otg_state_string(musb)); spin_unlock_irqrestore(&musb->lock, flags); return ret; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 4a4d485d37bd3..a497c44ab0dae 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -603,6 +603,11 @@ static inline enum usb_otg_state musb_get_state(struct musb *musb) return musb->xceiv->otg->state; } +static inline const char *musb_otg_state_string(struct musb *musb) +{ + return usb_otg_state_string(musb_get_state(musb)); +} + /* * gets the "dr_mode" property from DT and converts it into musb_mode * if the property is not found or not recognized returns MUSB_OTG diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b5c7deb288d25..9f5c531de3872 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1564,7 +1564,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) goto done; default: musb_dbg(musb, "Unhandled wake: %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); goto done; } @@ -1940,7 +1940,7 @@ void musb_g_resume(struct musb *musb) break; default: WARNING("unhandled RESUME transition (%s)\n", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } @@ -1970,7 +1970,7 @@ void musb_g_suspend(struct musb *musb) * A_PERIPHERAL may need care too */ WARNING("unhandled SUSPEND transition (%s)", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } @@ -2004,7 +2004,7 @@ void musb_g_disconnect(struct musb *musb) switch (musb_get_state(musb)) { default: musb_dbg(musb, "Unhandled disconnect %s, setting a_idle", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); musb_set_state(musb, OTG_STATE_A_IDLE); MUSB_HST_MODE(musb); break; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ed631447a253c..b7553da7f4bc8 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2519,7 +2519,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (musb->is_active) { WARNING("trying to suspend as %s while active\n", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); return -EBUSY; } else return 0; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index d1cfd45d69e36..7eb929d75280c 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -102,7 +102,7 @@ int musb_port_suspend(struct musb *musb, bool do_suspend) break; default: musb_dbg(musb, "bogus rh suspend? %s", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } else if (power & MUSB_POWER_SUSPENDM) { power &= ~MUSB_POWER_SUSPENDM; @@ -221,7 +221,7 @@ void musb_root_disconnect(struct musb *musb) break; default: musb_dbg(musb, "host disconnect (%s)", - usb_otg_state_string(musb->xceiv->otg->state)); + musb_otg_state_string(musb)); } } EXPORT_SYMBOL_GPL(musb_root_disconnect); -- GitLab From a6d45ea063f0a9272f62925c8150439af5640e74 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:53 +0100 Subject: [PATCH 0416/1480] usb: musb: Allow running without CONFIG_USB_PHY Modify the core so that musb->xceiv is never deferenced without being checked first. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-4-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_core.h | 12 ++++++++++-- drivers/usb/musb/musb_gadget.c | 21 +++++++++++++-------- drivers/usb/musb/musb_host.c | 8 ++++++-- drivers/usb/musb/musb_virthub.c | 11 +++++------ 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 9bf0ebaa3b7cf..648bb6021c5ef 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2448,7 +2448,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) else musb->io.set_toggle = musb_default_set_toggle; - if (!musb->xceiv->io_ops) { + if (IS_ENABLED(CONFIG_USB_PHY) && musb->xceiv && !musb->xceiv->io_ops) { musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index a497c44ab0dae..b7588d11cfc59 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -339,6 +339,8 @@ struct musb { struct usb_phy *xceiv; struct phy *phy; + enum usb_otg_state otg_state; + int nIrq; unsigned irq_wake:1; @@ -595,12 +597,18 @@ static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum) static inline void musb_set_state(struct musb *musb, enum usb_otg_state otg_state) { - musb->xceiv->otg->state = otg_state; + if (musb->xceiv) + musb->xceiv->otg->state = otg_state; + else + musb->otg_state = otg_state; } static inline enum usb_otg_state musb_get_state(struct musb *musb) { - return musb->xceiv->otg->state; + if (musb->xceiv) + return musb->xceiv->otg->state; + + return musb->otg_state; } static inline const char *musb_otg_state_string(struct musb *musb) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 9f5c531de3872..66c8b32b16bb4 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1552,9 +1552,11 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) break; } - spin_unlock_irqrestore(&musb->lock, flags); - otg_start_srp(musb->xceiv->otg); - spin_lock_irqsave(&musb->lock, flags); + if (musb->xceiv) { + spin_unlock_irqrestore(&musb->lock, flags); + otg_start_srp(musb->xceiv->otg); + spin_lock_irqsave(&musb->lock, flags); + } /* Block idling for at least 1s */ musb_platform_try_idle(musb, @@ -1628,7 +1630,7 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) { struct musb *musb = gadget_to_musb(gadget); - if (!musb->xceiv->set_power) + if (!musb->xceiv || !musb->xceiv->set_power) return -EOPNOTSUPP; return usb_phy_set_power(musb->xceiv, mA); } @@ -1834,7 +1836,6 @@ static int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { struct musb *musb = gadget_to_musb(g); - struct usb_otg *otg = musb->xceiv->otg; unsigned long flags; int retval = 0; @@ -1851,7 +1852,9 @@ static int musb_gadget_start(struct usb_gadget *g, spin_lock_irqsave(&musb->lock, flags); musb->is_active = 1; - otg_set_peripheral(otg, &musb->g); + if (musb->xceiv) + otg_set_peripheral(musb->xceiv->otg, &musb->g); + musb_set_state(musb, OTG_STATE_B_IDLE); spin_unlock_irqrestore(&musb->lock, flags); @@ -1861,7 +1864,7 @@ static int musb_gadget_start(struct usb_gadget *g, * handles power budgeting ... this way also * ensures HdrcStart is indirectly called. */ - if (musb->xceiv->last_event == USB_EVENT_ID) + if (musb->xceiv && musb->xceiv->last_event == USB_EVENT_ID) musb_platform_set_vbus(musb, 1); pm_runtime_mark_last_busy(musb->controller); @@ -1899,7 +1902,9 @@ static int musb_gadget_stop(struct usb_gadget *g) musb_set_state(musb, OTG_STATE_UNDEFINED); musb_stop(musb); - otg_set_peripheral(musb->xceiv->otg, NULL); + + if (musb->xceiv) + otg_set_peripheral(musb->xceiv->otg, NULL); musb->is_active = 0; musb->gadget_driver = NULL; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index b7553da7f4bc8..8ad39ecd3b6fc 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2722,10 +2722,14 @@ int musb_host_setup(struct musb *musb, int power_budget) MUSB_HST_MODE(musb); musb_set_state(musb, OTG_STATE_A_IDLE); } - otg_set_host(musb->xceiv->otg, &hcd->self); + + if (musb->xceiv) { + otg_set_host(musb->xceiv->otg, &hcd->self); + musb->xceiv->otg->host = &hcd->self; + } + /* don't support otg protocols */ hcd->self.otg_port = 0; - musb->xceiv->otg->host = &hcd->self; hcd->power_budget = 2 * (power_budget ? : 250); hcd->skip_phy_initialization = 1; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 7eb929d75280c..2b2164e028b31 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -50,7 +50,6 @@ void musb_host_finish_resume(struct work_struct *work) int musb_port_suspend(struct musb *musb, bool do_suspend) { - struct usb_otg *otg = musb->xceiv->otg; u8 power; void __iomem *mbase = musb->mregs; @@ -88,7 +87,8 @@ int musb_port_suspend(struct musb *musb, bool do_suspend) switch (musb_get_state(musb)) { case OTG_STATE_A_HOST: musb_set_state(musb, OTG_STATE_A_SUSPEND); - musb->is_active = otg->host->b_hnp_enable; + musb->is_active = musb->xceiv && + musb->xceiv->otg->host->b_hnp_enable; if (musb->is_active) mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies( @@ -97,7 +97,8 @@ int musb_port_suspend(struct musb *musb, bool do_suspend) break; case OTG_STATE_B_HOST: musb_set_state(musb, OTG_STATE_B_WAIT_ACON); - musb->is_active = otg->host->b_hnp_enable; + musb->is_active = musb->xceiv && + musb->xceiv->otg->host->b_hnp_enable; musb_platform_try_idle(musb, 0); break; default: @@ -196,8 +197,6 @@ void musb_port_reset(struct musb *musb, bool do_reset) void musb_root_disconnect(struct musb *musb) { - struct usb_otg *otg = musb->xceiv->otg; - musb->port1_status = USB_PORT_STAT_POWER | (USB_PORT_STAT_C_CONNECTION << 16); @@ -206,7 +205,7 @@ void musb_root_disconnect(struct musb *musb) switch (musb_get_state(musb)) { case OTG_STATE_A_SUSPEND: - if (otg->host->b_hnp_enable) { + if (musb->xceiv && musb->xceiv->otg->host->b_hnp_enable) { musb_set_state(musb, OTG_STATE_A_PERIPHERAL); musb->g.is_a_peripheral = 1; break; -- GitLab From 0afddf1e49d1172a87c7a73002e62aa66b6af677 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:54 +0100 Subject: [PATCH 0417/1480] usb: musb: Support setting OTG mode using generic PHY When musb->xceiv is not provided but musb->phy is, support setting the OTG mode (host, peripheral) using the generic PHY framework. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-5-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 4 ++++ drivers/usb/musb/musb_host.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 66c8b32b16bb4..6cb9514ef3405 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1854,6 +1854,8 @@ static int musb_gadget_start(struct usb_gadget *g, if (musb->xceiv) otg_set_peripheral(musb->xceiv->otg, &musb->g); + else + phy_set_mode(musb->phy, PHY_MODE_USB_DEVICE); musb_set_state(musb, OTG_STATE_B_IDLE); spin_unlock_irqrestore(&musb->lock, flags); @@ -1905,6 +1907,8 @@ static int musb_gadget_stop(struct usb_gadget *g) if (musb->xceiv) otg_set_peripheral(musb->xceiv->otg, NULL); + else + phy_set_mode(musb->phy, PHY_MODE_INVALID); musb->is_active = 0; musb->gadget_driver = NULL; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 8ad39ecd3b6fc..a02c29216955a 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2726,6 +2726,8 @@ int musb_host_setup(struct musb *musb, int power_budget) if (musb->xceiv) { otg_set_host(musb->xceiv->otg, &hcd->self); musb->xceiv->otg->host = &hcd->self; + } else { + phy_set_mode(musb->phy, PHY_MODE_USB_HOST); } /* don't support otg protocols */ -- GitLab From d9b324307777404f978660b5752fb264ee344a22 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:55 +0100 Subject: [PATCH 0418/1480] usb: musb: jz4740: Don't disable external hubs The jz4740-musb driver does not really support OTG, so it has no reason to disable external hubs, especially since it's a system-wide setting and we don't want external hubs to be disabled for other USB host controllers. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-6-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index f9eec666103cb..290df4d5d5ce8 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -107,7 +107,6 @@ config USB_MUSB_JZ4740 depends on OF depends on MIPS || COMPILE_TEST depends on USB_MUSB_GADGET - depends on USB=n || USB_OTG_DISABLE_EXTERNAL_HUB select USB_ROLE_SWITCH config USB_MUSB_MEDIATEK -- GitLab From 9cd074798ef6bf9c361c78084abc2c30e551ecdc Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:56 +0100 Subject: [PATCH 0419/1480] usb: musb: jz4740: Support the generic PHY framework Support PHYs implemented using the generic PHY framework instead of the deprecated USB-PHY framework. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-7-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/jz4740.c | 62 ++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index d1e4e0deb7535..c7b1d2a394d9a 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -81,6 +82,9 @@ static int jz4740_musb_role_switch_set(struct usb_role_switch *sw, struct jz4740_glue *glue = usb_role_switch_get_drvdata(sw); struct usb_phy *phy = glue->musb->xceiv; + if (!phy) + return 0; + switch (role) { case USB_ROLE_NONE: atomic_notifier_call_chain(&phy->notifier, USB_EVENT_NONE, phy); @@ -105,21 +109,51 @@ static int jz4740_musb_init(struct musb *musb) .driver_data = glue, .fwnode = dev_fwnode(dev), }; + int err; glue->musb = musb; - if (dev->of_node) - musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); - else - musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR(musb->xceiv)) - return dev_err_probe(dev, PTR_ERR(musb->xceiv), - "No transceiver configured\n"); + if (IS_ENABLED(CONFIG_GENERIC_PHY)) { + musb->phy = devm_of_phy_get_by_index(dev, dev->of_node, 0); + if (IS_ERR(musb->phy)) { + err = PTR_ERR(musb->phy); + if (err != -ENODEV) { + dev_err(dev, "Unable to get PHY\n"); + return err; + } + + musb->phy = NULL; + } + } + + if (musb->phy) { + err = phy_init(musb->phy); + if (err) { + dev_err(dev, "Failed to init PHY\n"); + return err; + } + + err = phy_power_on(musb->phy); + if (err) { + dev_err(dev, "Unable to power on PHY\n"); + goto err_phy_shutdown; + } + } else { + if (dev->of_node) + musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); + else + musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + if (IS_ERR(musb->xceiv)) { + dev_err(dev, "No transceiver configured\n"); + return PTR_ERR(musb->xceiv); + } + } glue->role_sw = usb_role_switch_register(dev, &role_sw_desc); if (IS_ERR(glue->role_sw)) { dev_err(dev, "Failed to register USB role switch\n"); - return PTR_ERR(glue->role_sw); + err = PTR_ERR(glue->role_sw); + goto err_phy_power_down; } /* @@ -131,6 +165,14 @@ static int jz4740_musb_init(struct musb *musb) musb->isr = jz4740_musb_interrupt; return 0; + +err_phy_power_down: + if (musb->phy) + phy_power_off(musb->phy); +err_phy_shutdown: + if (musb->phy) + phy_exit(musb->phy); + return err; } static int jz4740_musb_exit(struct musb *musb) @@ -138,6 +180,10 @@ static int jz4740_musb_exit(struct musb *musb) struct jz4740_glue *glue = dev_get_drvdata(musb->controller->parent); usb_role_switch_unregister(glue->role_sw); + if (musb->phy) { + phy_power_off(musb->phy); + phy_exit(musb->phy); + } return 0; } -- GitLab From 3f2d1f2e40666d6536b663c5050a3a23ca5d9ce8 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 26 Oct 2022 19:26:57 +0100 Subject: [PATCH 0420/1480] usb: phy: jz4770: Remove driver This driver has been replaced by the Ingenic PHY driver that uses the generic PHY framework. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20221026182657.146630-8-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/Kconfig | 8 - drivers/usb/phy/Makefile | 1 - drivers/usb/phy/phy-jz4770.c | 353 ----------------------------------- 3 files changed, 362 deletions(-) delete mode 100644 drivers/usb/phy/phy-jz4770.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index efdcafdbe46d7..915df5726a5cc 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -189,12 +189,4 @@ config USB_ULPI_VIEWPORT Provides read/write operations to the ULPI phy register set for controllers with a viewport register (e.g. Chipidea/ARC controllers). -config JZ4770_PHY - tristate "Ingenic SoCs Transceiver Driver" - depends on MIPS || COMPILE_TEST - select USB_PHY - help - This driver provides PHY support for the USB controller found - on the JZ-series and X-series SoCs from Ingenic. - endmenu diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index b352bdbe87121..df1d99010079f 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -24,4 +24,3 @@ obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o obj-$(CONFIG_USB_ULPI) += phy-ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o -obj-$(CONFIG_JZ4770_PHY) += phy-jz4770.o diff --git a/drivers/usb/phy/phy-jz4770.c b/drivers/usb/phy/phy-jz4770.c deleted file mode 100644 index f16adcacdce3f..0000000000000 --- a/drivers/usb/phy/phy-jz4770.c +++ /dev/null @@ -1,353 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Ingenic SoCs USB PHY driver - * Copyright (c) Paul Cercueil - * Copyright (c) 漆鹏振 (Qi Pengzhen) - * Copyright (c) 周琰杰 (Zhou Yanjie) - */ - -#include -#include -#include -#include -#include -#include -#include - -/* OTGPHY register offsets */ -#define REG_USBPCR_OFFSET 0x00 -#define REG_USBRDT_OFFSET 0x04 -#define REG_USBVBFIL_OFFSET 0x08 -#define REG_USBPCR1_OFFSET 0x0c - -/* bits within the USBPCR register */ -#define USBPCR_USB_MODE BIT(31) -#define USBPCR_AVLD_REG BIT(30) -#define USBPCR_COMMONONN BIT(25) -#define USBPCR_VBUSVLDEXT BIT(24) -#define USBPCR_VBUSVLDEXTSEL BIT(23) -#define USBPCR_POR BIT(22) -#define USBPCR_SIDDQ BIT(21) -#define USBPCR_OTG_DISABLE BIT(20) -#define USBPCR_TXPREEMPHTUNE BIT(6) - -#define USBPCR_IDPULLUP_LSB 28 -#define USBPCR_IDPULLUP_MASK GENMASK(29, USBPCR_IDPULLUP_LSB) -#define USBPCR_IDPULLUP_ALWAYS (0x2 << USBPCR_IDPULLUP_LSB) -#define USBPCR_IDPULLUP_SUSPEND (0x1 << USBPCR_IDPULLUP_LSB) -#define USBPCR_IDPULLUP_OTG (0x0 << USBPCR_IDPULLUP_LSB) - -#define USBPCR_COMPDISTUNE_LSB 17 -#define USBPCR_COMPDISTUNE_MASK GENMASK(19, USBPCR_COMPDISTUNE_LSB) -#define USBPCR_COMPDISTUNE_DFT (0x4 << USBPCR_COMPDISTUNE_LSB) - -#define USBPCR_OTGTUNE_LSB 14 -#define USBPCR_OTGTUNE_MASK GENMASK(16, USBPCR_OTGTUNE_LSB) -#define USBPCR_OTGTUNE_DFT (0x4 << USBPCR_OTGTUNE_LSB) - -#define USBPCR_SQRXTUNE_LSB 11 -#define USBPCR_SQRXTUNE_MASK GENMASK(13, USBPCR_SQRXTUNE_LSB) -#define USBPCR_SQRXTUNE_DCR_20PCT (0x7 << USBPCR_SQRXTUNE_LSB) -#define USBPCR_SQRXTUNE_DFT (0x3 << USBPCR_SQRXTUNE_LSB) - -#define USBPCR_TXFSLSTUNE_LSB 7 -#define USBPCR_TXFSLSTUNE_MASK GENMASK(10, USBPCR_TXFSLSTUNE_LSB) -#define USBPCR_TXFSLSTUNE_DCR_50PPT (0xf << USBPCR_TXFSLSTUNE_LSB) -#define USBPCR_TXFSLSTUNE_DCR_25PPT (0x7 << USBPCR_TXFSLSTUNE_LSB) -#define USBPCR_TXFSLSTUNE_DFT (0x3 << USBPCR_TXFSLSTUNE_LSB) -#define USBPCR_TXFSLSTUNE_INC_25PPT (0x1 << USBPCR_TXFSLSTUNE_LSB) -#define USBPCR_TXFSLSTUNE_INC_50PPT (0x0 << USBPCR_TXFSLSTUNE_LSB) - -#define USBPCR_TXHSXVTUNE_LSB 4 -#define USBPCR_TXHSXVTUNE_MASK GENMASK(5, USBPCR_TXHSXVTUNE_LSB) -#define USBPCR_TXHSXVTUNE_DFT (0x3 << USBPCR_TXHSXVTUNE_LSB) -#define USBPCR_TXHSXVTUNE_DCR_15MV (0x1 << USBPCR_TXHSXVTUNE_LSB) - -#define USBPCR_TXRISETUNE_LSB 4 -#define USBPCR_TXRISETUNE_MASK GENMASK(5, USBPCR_TXRISETUNE_LSB) -#define USBPCR_TXRISETUNE_DFT (0x3 << USBPCR_TXRISETUNE_LSB) - -#define USBPCR_TXVREFTUNE_LSB 0 -#define USBPCR_TXVREFTUNE_MASK GENMASK(3, USBPCR_TXVREFTUNE_LSB) -#define USBPCR_TXVREFTUNE_INC_25PPT (0x7 << USBPCR_TXVREFTUNE_LSB) -#define USBPCR_TXVREFTUNE_DFT (0x5 << USBPCR_TXVREFTUNE_LSB) - -/* bits within the USBRDTR register */ -#define USBRDT_UTMI_RST BIT(27) -#define USBRDT_HB_MASK BIT(26) -#define USBRDT_VBFIL_LD_EN BIT(25) -#define USBRDT_IDDIG_EN BIT(24) -#define USBRDT_IDDIG_REG BIT(23) -#define USBRDT_VBFIL_EN BIT(2) - -/* bits within the USBPCR1 register */ -#define USBPCR1_BVLD_REG BIT(31) -#define USBPCR1_DPPD BIT(29) -#define USBPCR1_DMPD BIT(28) -#define USBPCR1_USB_SEL BIT(28) -#define USBPCR1_WORD_IF_16BIT BIT(19) - -enum ingenic_usb_phy_version { - ID_JZ4770, - ID_JZ4780, - ID_X1000, - ID_X1830, -}; - -struct ingenic_soc_info { - enum ingenic_usb_phy_version version; - - void (*usb_phy_init)(struct usb_phy *phy); -}; - -struct jz4770_phy { - const struct ingenic_soc_info *soc_info; - - struct usb_phy phy; - struct usb_otg otg; - struct device *dev; - void __iomem *base; - struct clk *clk; - struct regulator *vcc_supply; -}; - -static inline struct jz4770_phy *otg_to_jz4770_phy(struct usb_otg *otg) -{ - return container_of(otg, struct jz4770_phy, otg); -} - -static inline struct jz4770_phy *phy_to_jz4770_phy(struct usb_phy *phy) -{ - return container_of(phy, struct jz4770_phy, phy); -} - -static int ingenic_usb_phy_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct jz4770_phy *priv = otg_to_jz4770_phy(otg); - u32 reg; - - if (priv->soc_info->version >= ID_X1000) { - reg = readl(priv->base + REG_USBPCR1_OFFSET); - reg |= USBPCR1_BVLD_REG; - writel(reg, priv->base + REG_USBPCR1_OFFSET); - } - - reg = readl(priv->base + REG_USBPCR_OFFSET); - reg &= ~USBPCR_USB_MODE; - reg |= USBPCR_VBUSVLDEXT | USBPCR_VBUSVLDEXTSEL | USBPCR_OTG_DISABLE; - writel(reg, priv->base + REG_USBPCR_OFFSET); - - return 0; -} - -static int ingenic_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct jz4770_phy *priv = otg_to_jz4770_phy(otg); - u32 reg; - - reg = readl(priv->base + REG_USBPCR_OFFSET); - reg &= ~(USBPCR_VBUSVLDEXT | USBPCR_VBUSVLDEXTSEL | USBPCR_OTG_DISABLE); - reg |= USBPCR_USB_MODE; - writel(reg, priv->base + REG_USBPCR_OFFSET); - - return 0; -} - -static int ingenic_usb_phy_init(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - int err; - u32 reg; - - err = regulator_enable(priv->vcc_supply); - if (err) { - dev_err(priv->dev, "Unable to enable VCC: %d\n", err); - return err; - } - - err = clk_prepare_enable(priv->clk); - if (err) { - dev_err(priv->dev, "Unable to start clock: %d\n", err); - return err; - } - - priv->soc_info->usb_phy_init(phy); - - /* Wait for PHY to reset */ - usleep_range(30, 300); - reg = readl(priv->base + REG_USBPCR_OFFSET); - writel(reg & ~USBPCR_POR, priv->base + REG_USBPCR_OFFSET); - usleep_range(300, 1000); - - return 0; -} - -static void ingenic_usb_phy_shutdown(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - - clk_disable_unprepare(priv->clk); - regulator_disable(priv->vcc_supply); -} - -static void ingenic_usb_phy_remove(void *phy) -{ - usb_remove_phy(phy); -} - -static void jz4770_usb_phy_init(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - u32 reg; - - reg = USBPCR_AVLD_REG | USBPCR_COMMONONN | USBPCR_IDPULLUP_ALWAYS | - USBPCR_COMPDISTUNE_DFT | USBPCR_OTGTUNE_DFT | USBPCR_SQRXTUNE_DFT | - USBPCR_TXFSLSTUNE_DFT | USBPCR_TXRISETUNE_DFT | USBPCR_TXVREFTUNE_DFT | - USBPCR_POR; - writel(reg, priv->base + REG_USBPCR_OFFSET); -} - -static void jz4780_usb_phy_init(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - u32 reg; - - reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL | - USBPCR1_WORD_IF_16BIT; - writel(reg, priv->base + REG_USBPCR1_OFFSET); - - reg = USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR; - writel(reg, priv->base + REG_USBPCR_OFFSET); -} - -static void x1000_usb_phy_init(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - u32 reg; - - reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT; - writel(reg, priv->base + REG_USBPCR1_OFFSET); - - reg = USBPCR_SQRXTUNE_DCR_20PCT | USBPCR_TXPREEMPHTUNE | - USBPCR_TXHSXVTUNE_DCR_15MV | USBPCR_TXVREFTUNE_INC_25PPT | - USBPCR_COMMONONN | USBPCR_POR; - writel(reg, priv->base + REG_USBPCR_OFFSET); -} - -static void x1830_usb_phy_init(struct usb_phy *phy) -{ - struct jz4770_phy *priv = phy_to_jz4770_phy(phy); - u32 reg; - - /* rdt */ - writel(USBRDT_VBFIL_EN | USBRDT_UTMI_RST, priv->base + REG_USBRDT_OFFSET); - - reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT | - USBPCR1_DMPD | USBPCR1_DPPD; - writel(reg, priv->base + REG_USBPCR1_OFFSET); - - reg = USBPCR_IDPULLUP_OTG | USBPCR_VBUSVLDEXT | USBPCR_TXPREEMPHTUNE | - USBPCR_COMMONONN | USBPCR_POR; - writel(reg, priv->base + REG_USBPCR_OFFSET); -} - -static const struct ingenic_soc_info jz4770_soc_info = { - .version = ID_JZ4770, - - .usb_phy_init = jz4770_usb_phy_init, -}; - -static const struct ingenic_soc_info jz4780_soc_info = { - .version = ID_JZ4780, - - .usb_phy_init = jz4780_usb_phy_init, -}; - -static const struct ingenic_soc_info x1000_soc_info = { - .version = ID_X1000, - - .usb_phy_init = x1000_usb_phy_init, -}; - -static const struct ingenic_soc_info x1830_soc_info = { - .version = ID_X1830, - - .usb_phy_init = x1830_usb_phy_init, -}; - -static const struct of_device_id ingenic_usb_phy_of_matches[] = { - { .compatible = "ingenic,jz4770-phy", .data = &jz4770_soc_info }, - { .compatible = "ingenic,jz4780-phy", .data = &jz4780_soc_info }, - { .compatible = "ingenic,x1000-phy", .data = &x1000_soc_info }, - { .compatible = "ingenic,x1830-phy", .data = &x1830_soc_info }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, ingenic_usb_phy_of_matches); - -static int jz4770_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct jz4770_phy *priv; - int err; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->soc_info = device_get_match_data(&pdev->dev); - if (!priv->soc_info) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } - - platform_set_drvdata(pdev, priv); - priv->dev = dev; - priv->phy.dev = dev; - priv->phy.otg = &priv->otg; - priv->phy.label = "ingenic-usb-phy"; - priv->phy.init = ingenic_usb_phy_init; - priv->phy.shutdown = ingenic_usb_phy_shutdown; - - priv->otg.state = OTG_STATE_UNDEFINED; - priv->otg.usb_phy = &priv->phy; - priv->otg.set_host = ingenic_usb_phy_set_host; - priv->otg.set_peripheral = ingenic_usb_phy_set_peripheral; - - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) { - dev_err(dev, "Failed to map registers\n"); - return PTR_ERR(priv->base); - } - - priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) - return dev_err_probe(dev, PTR_ERR(priv->clk), - "Failed to get clock\n"); - - priv->vcc_supply = devm_regulator_get(dev, "vcc"); - if (IS_ERR(priv->vcc_supply)) - return dev_err_probe(dev, PTR_ERR(priv->vcc_supply), - "Failed to get regulator\n"); - - err = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); - if (err) - return dev_err_probe(dev, err, "Unable to register PHY\n"); - - return devm_add_action_or_reset(dev, ingenic_usb_phy_remove, &priv->phy); -} - -static struct platform_driver ingenic_phy_driver = { - .probe = jz4770_phy_probe, - .driver = { - .name = "jz4770-phy", - .of_match_table = ingenic_usb_phy_of_matches, - }, -}; -module_platform_driver(ingenic_phy_driver); - -MODULE_AUTHOR("周琰杰 (Zhou Yanjie) "); -MODULE_AUTHOR("漆鹏振 (Qi Pengzhen) "); -MODULE_AUTHOR("Paul Cercueil "); -MODULE_DESCRIPTION("Ingenic SoCs USB PHY driver"); -MODULE_LICENSE("GPL"); -- GitLab From 321b59870f850a10dbb211ecd2bd87b41497ea6f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Nov 2022 14:10:30 +0100 Subject: [PATCH 0421/1480] usb: gadget: u_ether: Do not make UDC parent of the net device The UDC is not a suitable parent of the net device as the UDC can change or vanish during the lifecycle of the ethernet gadget. This can be illustrated with the following: mkdir -p /sys/kernel/config/usb_gadget/mygadget cd /sys/kernel/config/usb_gadget/mygadget mkdir -p configs/c.1/strings/0x409 echo "C1:Composite Device" > configs/c.1/strings/0x409/configuration mkdir -p functions/ecm.usb0 ln -s functions/ecm.usb0 configs/c.1/ echo "dummy_udc.0" > UDC rmmod dummy_hcd The 'rmmod' removes the UDC from the just created gadget, leaving the still existing net device with a no longer existing parent. Accessing the ethernet device with commands like: ip --details link show usb0 will result in a KASAN splat: ================================================================== BUG: KASAN: use-after-free in if_nlmsg_size+0x3e8/0x528 Read of size 4 at addr c5c84754 by task ip/357 CPU: 3 PID: 357 Comm: ip Not tainted 6.1.0-rc3-00013-gd14953726b24-dirty #324 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x58/0x70 dump_stack_lvl from print_report+0x134/0x4d4 print_report from kasan_report+0x78/0x10c kasan_report from if_nlmsg_size+0x3e8/0x528 if_nlmsg_size from rtnl_getlink+0x2b4/0x4d0 rtnl_getlink from rtnetlink_rcv_msg+0x1f4/0x674 rtnetlink_rcv_msg from netlink_rcv_skb+0xb4/0x1f8 netlink_rcv_skb from netlink_unicast+0x294/0x478 netlink_unicast from netlink_sendmsg+0x328/0x640 netlink_sendmsg from ____sys_sendmsg+0x2a4/0x3b4 ____sys_sendmsg from ___sys_sendmsg+0xc8/0x12c ___sys_sendmsg from sys_sendmsg+0xa0/0x120 sys_sendmsg from ret_fast_syscall+0x0/0x1c Solve this by not setting the parent of the ethernet device. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20221104131031.850850-2-s.hauer@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/u_ether.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index e06022873df16..8f12f3f8f6eeb 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -798,7 +798,6 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, net->max_mtu = GETHER_MAX_MTU_SIZE; dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); @@ -873,8 +872,6 @@ int gether_register_netdev(struct net_device *net) struct usb_gadget *g; int status; - if (!net->dev.parent) - return -EINVAL; dev = netdev_priv(net); g = dev->gadget; @@ -905,7 +902,6 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g) dev = netdev_priv(net); dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); } EXPORT_SYMBOL_GPL(gether_set_gadget); -- GitLab From d65e6b6e884a38360fc1cadf8ff31858151da57f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Nov 2022 14:10:31 +0100 Subject: [PATCH 0422/1480] usb: gadget: f_ecm: Always set current gadget in ecm_bind() The gadget may change over bind/unbind cycles, so set it each time during bind, not only the first time. Without it we get a use-after-free with the following example: cd /sys/kernel/config/usb_gadget/; mkdir -p mygadget; cd mygadget mkdir -p configs/c.1/strings/0x409 echo "C1:Composite Device" > configs/c.1/strings/0x409/configuration mkdir -p functions/ecm.usb0 ln -s functions/ecm.usb0 configs/c.1/ rmmod dummy_hcd modprobe dummy_hcd KASAN will complain shortly after the 'modprobe': usb 2-1: New USB device found, idVendor=0000, idProduct=0000, bcdDevice= 6.01 usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 ================================================================== BUG: KASAN: use-after-free in gether_connect+0xb8/0x30c Read of size 4 at addr cbef170c by task swapper/3/0 CPU: 3 PID: 0 Comm: swapper/3 Not tainted 6.1.0-rc3-00014-g41ff012f50cb-dirty #322 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x58/0x70 dump_stack_lvl from print_report+0x134/0x4d4 print_report from kasan_report+0x78/0x10c kasan_report from gether_connect+0xb8/0x30c gether_connect from ecm_set_alt+0x124/0x254 ecm_set_alt from composite_setup+0xb98/0x2b18 composite_setup from configfs_composite_setup+0x80/0x98 configfs_composite_setup from dummy_timer+0x8f0/0x14a0 [dummy_hcd] ... Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20221104131031.850850-3-s.hauer@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_ecm.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index ffe2486fce71c..a7ab30e603e20 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -685,7 +685,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_ecm *ecm = func_to_ecm(f); struct usb_string *us; - int status; + int status = 0; struct usb_ep *ep; struct f_ecm_opts *ecm_opts; @@ -695,23 +695,19 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst); - /* - * in drivers/usb/gadget/configfs.c:configfs_composite_bind() - * configurations are bound in sequence with list_for_each_entry, - * in each configuration its functions are bound in sequence - * with list_for_each_entry, so we assume no race condition - * with regard to ecm_opts->bound access - */ + mutex_lock(&ecm_opts->lock); + + gether_set_gadget(ecm_opts->net, cdev->gadget); + if (!ecm_opts->bound) { - mutex_lock(&ecm_opts->lock); - gether_set_gadget(ecm_opts->net, cdev->gadget); status = gether_register_netdev(ecm_opts->net); - mutex_unlock(&ecm_opts->lock); - if (status) - return status; ecm_opts->bound = true; } + mutex_unlock(&ecm_opts->lock); + if (status) + return status; + ecm_string_defs[1].s = ecm->ethaddr; us = usb_gstrings_attach(cdev, ecm_strings, -- GitLab From 2e2b4b896159f9d47d063ccf4ed0a7af9a40f1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Wed, 19 Oct 2022 13:55:03 +0300 Subject: [PATCH 0423/1480] tty: Convert tty_buffer flags to bool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The struct tty_buffer has flags which is only used for storing TTYB_NORMAL. There is also a few quite confusing operations for checking the presense of TTYB_NORMAL. Simplify things by converting flags to bool. Despite the name remaining the same, the meaning of "flags" is altered slightly by this change. Previously it referred to flags of the buffer (only TTYB_NORMAL being used as a flag). After this change, flags tell whether the buffer contains/should be allocated with flags array along with character data array. It is much more suitable name that TTYB_NORMAL was for this purpose, thus the name remains. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221019105504.16800-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 28 ++++++++++++++-------------- include/linux/tty_buffer.h | 5 +---- include/linux/tty_flip.h | 4 ++-- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 3f057805560fe..2df86ed905742 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -107,7 +107,7 @@ static void tty_buffer_reset(struct tty_buffer *p, size_t size) p->commit = 0; p->lookahead = 0; p->read = 0; - p->flags = 0; + p->flags = true; } /** @@ -249,7 +249,7 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) * __tty_buffer_request_room - grow tty buffer if needed * @port: tty port * @size: size desired - * @flags: buffer flags if new buffer allocated (default = 0) + * @flags: buffer has to store flags along character data * * Make at least @size bytes of linear space available for the tty buffer. * @@ -260,19 +260,19 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) * Returns: the size we managed to find. */ static int __tty_buffer_request_room(struct tty_port *port, size_t size, - int flags) + bool flags) { struct tty_bufhead *buf = &port->buf; struct tty_buffer *b, *n; int left, change; b = buf->tail; - if (b->flags & TTYB_NORMAL) + if (!b->flags) left = 2 * b->size - b->used; else left = b->size - b->used; - change = (b->flags & TTYB_NORMAL) && (~flags & TTYB_NORMAL); + change = !b->flags && flags; if (change || left < size) { /* This is the slow path - looking for new buffers to use */ n = tty_buffer_alloc(port, size); @@ -300,7 +300,7 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, int tty_buffer_request_room(struct tty_port *port, size_t size) { - return __tty_buffer_request_room(port, size, 0); + return __tty_buffer_request_room(port, size, true); } EXPORT_SYMBOL_GPL(tty_buffer_request_room); @@ -320,17 +320,17 @@ int tty_insert_flip_string_fixed_flag(struct tty_port *port, const unsigned char *chars, char flag, size_t size) { int copied = 0; + bool flags = flag != TTY_NORMAL; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); - int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; int space = __tty_buffer_request_room(port, goal, flags); struct tty_buffer *tb = port->buf.tail; if (unlikely(space == 0)) break; memcpy(char_buf_ptr(tb, tb->used), chars, space); - if (~tb->flags & TTYB_NORMAL) + if (tb->flags) memset(flag_buf_ptr(tb, tb->used), flag, space); tb->used += space; copied += space; @@ -393,13 +393,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) { struct tty_buffer *tb; - int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; + bool flags = flag != TTY_NORMAL; if (!__tty_buffer_request_room(port, 1, flags)) return 0; tb = port->buf.tail; - if (~tb->flags & TTYB_NORMAL) + if (tb->flags) *flag_buf_ptr(tb, tb->used) = flag; *char_buf_ptr(tb, tb->used++) = ch; @@ -424,13 +424,13 @@ EXPORT_SYMBOL(__tty_insert_flip_char); int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, size_t size) { - int space = __tty_buffer_request_room(port, size, TTYB_NORMAL); + int space = __tty_buffer_request_room(port, size, false); if (likely(space)) { struct tty_buffer *tb = port->buf.tail; *chars = char_buf_ptr(tb, tb->used); - if (~tb->flags & TTYB_NORMAL) + if (tb->flags) memset(flag_buf_ptr(tb, tb->used), TTY_NORMAL, space); tb->used += space; } @@ -492,7 +492,7 @@ static void lookahead_bufs(struct tty_port *port, struct tty_buffer *head) unsigned char *p, *f = NULL; p = char_buf_ptr(head, head->lookahead); - if (~head->flags & TTYB_NORMAL) + if (head->flags) f = flag_buf_ptr(head, head->lookahead); port->client_ops->lookahead_buf(port, p, f, count); @@ -509,7 +509,7 @@ receive_buf(struct tty_port *port, struct tty_buffer *head, int count) const char *f = NULL; int n; - if (~head->flags & TTYB_NORMAL) + if (head->flags) f = flag_buf_ptr(head, head->read); n = port->client_ops->receive_buf(port, p, f, count); diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index 1796648c29073..6ceb2789e6c81 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -17,14 +17,11 @@ struct tty_buffer { int commit; int lookahead; /* Lazy update on recv, can become less than "read" */ int read; - int flags; + bool flags; /* Data points here */ unsigned long data[]; }; -/* Values for .flags field of tty_buffer */ -#define TTYB_NORMAL 1 /* buffer has no flags buffer */ - static inline unsigned char *char_buf_ptr(struct tty_buffer *b, int ofs) { return ((unsigned char *)b->data) + ofs; diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 483d41cbcbb70..bfaaeee61a050 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -25,9 +25,9 @@ static inline int tty_insert_flip_char(struct tty_port *port, struct tty_buffer *tb = port->buf.tail; int change; - change = (tb->flags & TTYB_NORMAL) && (flag != TTY_NORMAL); + change = !tb->flags && (flag != TTY_NORMAL); if (!change && tb->used < tb->size) { - if (~tb->flags & TTYB_NORMAL) + if (tb->flags) *flag_buf_ptr(tb, tb->used) = flag; *char_buf_ptr(tb, tb->used++) = ch; return 1; -- GitLab From c6d30576bd6ce33095d39fe66a51ea821e953ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 4 Nov 2022 11:37:19 +0100 Subject: [PATCH 0424/1480] serial: Fix a typo ("ignorning") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the two instances of this typo present in the MSM and VT8500 serial drivers. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Mukesh Ojha Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20221104103719.2234098-1-j.neuschaefer@gmx.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 2 +- drivers/tty/serial/vt8500_serial.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 2b2e0f74b75a0..843798e630844 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -816,7 +816,7 @@ static void msm_handle_rx(struct uart_port *port) port->icount.rx++; } - /* Mask conditions we're ignorning. */ + /* Mask conditions we're ignoring. */ sr &= port->read_status_mask; if (sr & MSM_UART_SR_RX_BREAK) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index deedb65131606..cc9157df732f4 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -168,7 +168,7 @@ static void handle_rx(struct uart_port *port) c = readw(port->membase + VT8500_RXFIFO) & 0x3ff; - /* Mask conditions we're ignorning. */ + /* Mask conditions we're ignoring. */ c &= ~port->read_status_mask; if (c & FER) { -- GitLab From 56dc5074cbec02a6922c4bbce11de9827640bb4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Mon, 7 Nov 2022 12:21:26 +0200 Subject: [PATCH 0425/1480] serial: 8250_dma: Rearm DMA Rx if more data is pending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When DMA Rx completes, the current behavior is to just exit the DMA completion handler without future actions. If the transfer is still on-going, UART will trigger an interrupt and that eventually rearms the DMA Rx. The extra interrupt round-trip has an inherent latency cost that increases the risk of FIFO overrun. In such situations, the latency margin tends to already be less due to FIFO not being empty. Add check into DMA Rx completion handler to detect if LSR has DR (Data Ready) still set. DR indicates there will be more characters pending and DMA Rx can be rearmed right away to handle them. Cc: Gilles BULOZ Signed-off-by: Ilpo Järvinen Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221107102126.56481-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dma.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index b85c82616e8cb..37d6af2ec4272 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -38,9 +38,8 @@ static void __dma_tx_complete(void *param) spin_unlock_irqrestore(&p->port.lock, flags); } -static void __dma_rx_complete(void *param) +static void __dma_rx_complete(struct uart_8250_port *p) { - struct uart_8250_port *p = param; struct uart_8250_dma *dma = p->dma; struct tty_port *tty_port = &p->port.state->port; struct dma_tx_state state; @@ -57,6 +56,20 @@ static void __dma_rx_complete(void *param) tty_flip_buffer_push(tty_port); } +static void dma_rx_complete(void *param) +{ + struct uart_8250_port *p = param; + struct uart_8250_dma *dma = p->dma; + unsigned long flags; + + __dma_rx_complete(p); + + spin_lock_irqsave(&p->port.lock, flags); + if (!dma->rx_running && (serial_lsr_in(p) & UART_LSR_DR)) + p->dma->rx_dma(p); + spin_unlock_irqrestore(&p->port.lock, flags); +} + int serial8250_tx_dma(struct uart_8250_port *p) { struct uart_8250_dma *dma = p->dma; @@ -130,7 +143,7 @@ int serial8250_rx_dma(struct uart_8250_port *p) return -EBUSY; dma->rx_running = 1; - desc->callback = __dma_rx_complete; + desc->callback = dma_rx_complete; desc->callback_param = p; dma->rx_cookie = dmaengine_submit(desc); -- GitLab From 6a3ff858915fa8ca36c7eb02c87c9181ae2fc333 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Wed, 9 Nov 2022 07:21:10 +0000 Subject: [PATCH 0426/1480] serial: 8250_bcm7271: Fix error handling in brcmuart_init() A problem about 8250_bcm7271 create debugfs failed is triggered with the following log given: [ 324.516635] debugfs: Directory 'bcm7271-uart' with parent '/' already present! The reason is that brcmuart_init() returns platform_driver_register() directly without checking its return value, if platform_driver_register() failed, it returns without destroy the newly created debugfs, resulting the debugfs of 8250_bcm7271 can never be created later. brcmuart_init() debugfs_create_dir() # create debugfs directory platform_driver_register() driver_register() bus_add_driver() priv = kzalloc(...) # OOM happened # return without destroy debugfs directory Fix by removing debugfs when platform_driver_register() returns error. Fixes: 41a469482de2 ("serial: 8250: Add new 8250-core based Broadcom STB driver") Signed-off-by: Yuan Can Link: https://lore.kernel.org/r/20221109072110.117291-2-yuancan@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_bcm7271.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index 062177b64d21f..ed5a947476920 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -1210,9 +1210,17 @@ static struct platform_driver brcmuart_platform_driver = { static int __init brcmuart_init(void) { + int ret; + brcmuart_debugfs_root = debugfs_create_dir( brcmuart_platform_driver.driver.name, NULL); - return platform_driver_register(&brcmuart_platform_driver); + ret = platform_driver_register(&brcmuart_platform_driver); + if (ret) { + debugfs_remove_recursive(brcmuart_debugfs_root); + return ret; + } + + return 0; } module_init(brcmuart_init); -- GitLab From d85bf5105853d57ed27c6c21ac35424cc44a0fbb Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 9 Nov 2022 08:04:34 +0100 Subject: [PATCH 0427/1480] serial: 8250: 8250_omap: Fix calculation of RS485 delays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 801954d1210a ("serial: 8250: 8250_omap: Support native RS485") calculates RS485 delays from the baudrate. The baudrate is generated with either a 16x or 13x divisor. The divisor is set in the Mode Definition Register 1 (MDR1). The commit erroneously assumes that the register stores the divisor as a bitmask and uses a logical AND to differentiate between 16x and 13x divisors. However the divisor is really stored as a 3-bit mode (see lines 363ff in include/uapi/linux/serial_reg.h). The logical AND operation is performed with UART_OMAP_MDR1_16X_MODE, which is defined as 0x0 and hence yields false. So the commit always assumes a 13x divisor. Fix by using an equal comparison. This works because we never set any of the other 5 bits in the register. (They pertain to IrDA mode, which is not supported by the driver). Fixes: 801954d1210a ("serial: 8250: 8250_omap: Support native RS485") Link: https://lore.kernel.org/linux-serial/202211070440.8hWunFUN-lkp@intel.com/ Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Lukas Wunner Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/7d5b04da13d89b8708b9543a0b125f2b6062a77b.1667977259.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 1c8a48fdc8f24..7bb9da7558a1d 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -822,7 +822,7 @@ static int omap8250_rs485_config(struct uart_port *port, * of the AM65 TRM: https://www.ti.com/lit/ug/spruid7e/spruid7e.pdf */ if (priv->quot) { - if (priv->mdr1 & UART_OMAP_MDR1_16X_MODE) + if (priv->mdr1 == UART_OMAP_MDR1_16X_MODE) baud = port->uartclk / (16 * priv->quot); else baud = port->uartclk / (13 * priv->quot); -- GitLab From 7a1212475f5e313c11300272f34ffa32462bbeef Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 3 Nov 2022 10:17:41 +0100 Subject: [PATCH 0428/1480] tty: n_gsm: introduce macro for minimal unit size n_gsm has a minimal protocol overhead of 7 bytes. The current code already checks whether the configured MRU/MTU size is at least one byte more than this. Introduce the macro MIN_MTU to make this value more obvious. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20221103091743.2119-1-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 5e516f5cac5a3..570c40a3d78f2 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -89,6 +89,7 @@ module_param(debug, int, 0600); */ #define MAX_MRU 1500 #define MAX_MTU 1500 +#define MIN_MTU (PROT_OVERHEAD + 1) /* SOF, ADDR, CTRL, LEN1, LEN2, ..., FCS, EOF */ #define PROT_OVERHEAD 7 #define GSM_NET_TX_TIMEOUT (HZ*10) @@ -2712,7 +2713,9 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) if ((c->adaption != 1 && c->adaption != 2) || c->k) return -EOPNOTSUPP; /* Check the MRU/MTU range looks sane */ - if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) + if (c->mru < MIN_MTU || c->mtu < MIN_MTU) + return -EINVAL; + if (c->mru > MAX_MRU || c->mtu > MAX_MTU) return -EINVAL; if (c->n2 > 255) return -EINVAL; @@ -3296,7 +3299,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc) return -ENOMEM; } net->mtu = dlci->gsm->mtu; - net->min_mtu = 8; + net->min_mtu = MIN_MTU; net->max_mtu = dlci->gsm->mtu; mux_net = netdev_priv(net); mux_net->dlci = dlci; -- GitLab From 2ec7a802a04c545ceea96bf67ee818d8bb0349e2 Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 3 Nov 2022 10:17:42 +0100 Subject: [PATCH 0429/1480] tty: n_gsm: add parameters used with parameter negotiation n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapter 5.4.6.3.1 describes the encoding of the parameter negotiation messages. Add the parameters used there to 'gsm_mux' and 'gsm_dlci' and initialize both according to the value ranges and recommended defaults defined in chapter 5.7. Replace the use of the DLC default values from the 'gsm_mux' fields with the DLC specific values from the 'gsm_dlci' fields where applicable. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20221103091743.2119-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 58 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 570c40a3d78f2..c217013b3e164 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,12 @@ module_param(debug, int, 0600); #define T1 10 /* 100mS */ #define T2 34 /* 333mS */ +#define T3 10 /* 10s */ #define N2 3 /* Retry 3 times */ +#define K 2 /* outstanding I frames */ + +#define MAX_T3 255 /* In seconds. */ +#define MAX_WINDOW_SIZE 7 /* Limit of K in error recovery mode. */ /* Use long timers for testing at low speed with debug on */ #ifdef DEBUG_TIMING @@ -160,7 +166,12 @@ struct gsm_dlci { int prev_adaption; u32 modem_rx; /* Our incoming virtual modem lines */ u32 modem_tx; /* Our outgoing modem lines */ + unsigned int mtu; bool dead; /* Refuse re-open */ + /* Configuration */ + u8 prio; /* Priority */ + u8 ftype; /* Frame type */ + u8 k; /* Window size */ /* Flow control */ bool throttled; /* Private copy of throttle state */ bool constipated; /* Throttle status for outgoing */ @@ -283,7 +294,9 @@ struct gsm_mux { int adaption; /* 1 or 2 supported */ u8 ftype; /* UI or UIH */ int t1, t2; /* Timers in 1/100th of a sec */ + unsigned int t3; /* Power wake-up timer in seconds. */ int n2; /* Retry count */ + u8 k; /* Window size */ /* Statistics (not currently exposed) */ unsigned long bad_fcs; @@ -1075,12 +1088,12 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) return 0; /* MTU/MRU count only the data bits but watch adaption mode */ - if ((len + h) > gsm->mtu) - len = gsm->mtu - h; + if ((len + h) > dlci->mtu) + len = dlci->mtu - h; size = len + h; - msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); + msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype); if (!msg) return -ENOMEM; dp = msg->data; @@ -1144,19 +1157,19 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, len = dlci->skb->len + overhead; /* MTU/MRU count only the data bits */ - if (len > gsm->mtu) { + if (len > dlci->mtu) { if (dlci->adaption == 3) { /* Over long frame, bin it */ dev_kfree_skb_any(dlci->skb); dlci->skb = NULL; return 0; } - len = gsm->mtu; + len = dlci->mtu; } else last = 1; size = len + overhead; - msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); + msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype); if (msg == NULL) { skb_queue_tail(&dlci->skb_list, dlci->skb); dlci->skb = NULL; @@ -1213,7 +1226,7 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci, return -EINVAL; } - msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); + msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype); if (!msg) { pr_err("%s: gsm_data_alloc error", __func__); return -ENOMEM; @@ -1338,8 +1351,9 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci) static int gsm_control_command(struct gsm_mux *gsm, int cmd, const u8 *data, int dlen) { - struct gsm_msg *msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); + struct gsm_msg *msg; + msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype); if (msg == NULL) return -ENOMEM; @@ -1365,7 +1379,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data, int dlen) { struct gsm_msg *msg; - msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); + + msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype); if (msg == NULL) return; msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ @@ -2075,6 +2090,13 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) dlci->gsm = gsm; dlci->addr = addr; dlci->adaption = gsm->adaption; + dlci->mtu = gsm->mtu; + if (addr == 0) + dlci->prio = 0; + else + dlci->prio = roundup(addr + 1, 8) - 1; + dlci->ftype = gsm->ftype; + dlci->k = gsm->k; dlci->state = DLCI_CLOSED; if (addr) { dlci->data = gsm_dlci_data; @@ -2650,7 +2672,9 @@ static struct gsm_mux *gsm_alloc_mux(void) gsm->t1 = T1; gsm->t2 = T2; + gsm->t3 = T3; gsm->n2 = N2; + gsm->k = K; gsm->ftype = UIH; gsm->adaption = 1; gsm->encoding = GSM_ADV_OPT; @@ -2691,7 +2715,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm, c->initiator = gsm->initiator; c->t1 = gsm->t1; c->t2 = gsm->t2; - c->t3 = 0; /* Not supported */ + c->t3 = gsm->t3; c->n2 = gsm->n2; if (gsm->ftype == UIH) c->i = 1; @@ -2700,7 +2724,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm, pr_debug("Ftype %d i %d\n", gsm->ftype, c->i); c->mru = gsm->mru; c->mtu = gsm->mtu; - c->k = 0; + c->k = gsm->k; } static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) @@ -2717,12 +2741,16 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) return -EINVAL; if (c->mru > MAX_MRU || c->mtu > MAX_MTU) return -EINVAL; + if (c->t3 > MAX_T3) + return -EINVAL; if (c->n2 > 255) return -EINVAL; if (c->encapsulation > 1) /* Basic, advanced, no I */ return -EINVAL; if (c->initiator > 1) return -EINVAL; + if (c->k > MAX_WINDOW_SIZE) + return -EINVAL; if (c->i == 0 || c->i > 2) /* UIH and UI only */ return -EINVAL; /* @@ -2770,6 +2798,10 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) gsm->t1 = c->t1; if (c->t2) gsm->t2 = c->t2; + if (c->t3) + gsm->t3 = c->t3; + if (c->k) + gsm->k = c->k; /* * FIXME: We need to separate activation/deactivation from adding @@ -3298,9 +3330,9 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc) pr_err("alloc_netdev failed\n"); return -ENOMEM; } - net->mtu = dlci->gsm->mtu; + net->mtu = dlci->mtu; net->min_mtu = MIN_MTU; - net->max_mtu = dlci->gsm->mtu; + net->max_mtu = dlci->mtu; mux_net = netdev_priv(net); mux_net->dlci = dlci; kref_init(&mux_net->ref); -- GitLab From 92f1f0c3290d994d753dde588698daf1ef91504b Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 3 Nov 2022 10:17:43 +0100 Subject: [PATCH 0430/1480] tty: n_gsm: add parameter negotiation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapter 5.1.8.1.1 describes the parameter negotiation messages and parameters. Chapter 5.4.1 states that the default parameters are to be used if no negotiation is performed. Chapter 5.4.6.3.1 describes the encoding of the parameter negotiation message. The meaning of the parameters and allowed value ranges can be found in chapter 5.7. Add parameter negotiation support accordingly. DLCI specific parameter configuration by the user requires additional ioctls. This is subject to another patch. Signed-off-by: Daniel Starke Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221103091743.2119-3-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 335 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 327 insertions(+), 8 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c217013b3e164..cde1e846c81e3 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,7 @@ struct gsm_msg { enum gsm_dlci_state { DLCI_CLOSED, + DLCI_CONFIGURE, /* Sending PN (for adaption > 1) */ DLCI_OPENING, /* Sending SABM not seen UA */ DLCI_OPEN, /* SABM/UA complete */ DLCI_CLOSING, /* Sending DISC not seen UA/DM */ @@ -184,6 +186,32 @@ struct gsm_dlci { struct net_device *net; /* network interface, if created */ }; +/* + * Parameter bits used for parameter negotiation according to 3GPP 27.010 + * chapter 5.4.6.3.1. + */ + +struct gsm_dlci_param_bits { + u8 d_bits; + u8 i_cl_bits; + u8 p_bits; + u8 t_bits; + __le16 n_bits; + u8 na_bits; + u8 k_bits; +}; + +static_assert(sizeof(struct gsm_dlci_param_bits) == 8); + +#define PN_D_FIELD_DLCI GENMASK(5, 0) +#define PN_I_CL_FIELD_FTYPE GENMASK(3, 0) +#define PN_I_CL_FIELD_ADAPTION GENMASK(7, 4) +#define PN_P_FIELD_PRIO GENMASK(5, 0) +#define PN_T_FIELD_T1 GENMASK(7, 0) +#define PN_N_FIELD_N1 GENMASK(15, 0) +#define PN_NA_FIELD_N2 GENMASK(7, 0) +#define PN_K_FIELD_K GENMASK(2, 0) + /* Total number of supported devices */ #define GSM_TTY_MINORS 256 @@ -411,6 +439,7 @@ static const u8 gsm_fcs8[256] = { #define INIT_FCS 0xFF #define GOOD_FCS 0xCF +static void gsm_dlci_close(struct gsm_dlci *dlci); static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len); static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk); static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, @@ -533,6 +562,57 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data, kfree(prefix); } +/** + * gsm_encode_params - encode DLCI parameters + * @dlci: DLCI to encode from + * @params: buffer to fill with the encoded parameters + * + * Encodes the parameters according to GSM 07.10 section 5.4.6.3.1 + * table 3. + */ +static int gsm_encode_params(const struct gsm_dlci *dlci, + struct gsm_dlci_param_bits *params) +{ + const struct gsm_mux *gsm = dlci->gsm; + unsigned int i, cl; + + switch (dlci->ftype) { + case UIH: + i = 0; /* UIH */ + break; + case UI: + i = 1; /* UI */ + break; + default: + pr_debug("unsupported frame type %d\n", dlci->ftype); + return -EINVAL; + } + + switch (dlci->adaption) { + case 1: /* Unstructured */ + cl = 0; /* convergence layer type 1 */ + break; + case 2: /* Unstructured with modem bits. */ + cl = 1; /* convergence layer type 2 */ + break; + default: + pr_debug("unsupported adaption %d\n", dlci->adaption); + return -EINVAL; + } + + params->d_bits = FIELD_PREP(PN_D_FIELD_DLCI, dlci->addr); + /* UIH, convergence layer type 1 */ + params->i_cl_bits = FIELD_PREP(PN_I_CL_FIELD_FTYPE, i) | + FIELD_PREP(PN_I_CL_FIELD_ADAPTION, cl); + params->p_bits = FIELD_PREP(PN_P_FIELD_PRIO, dlci->prio); + params->t_bits = FIELD_PREP(PN_T_FIELD_T1, gsm->t1); + params->n_bits = cpu_to_le16(FIELD_PREP(PN_N_FIELD_N1, dlci->mtu)); + params->na_bits = FIELD_PREP(PN_NA_FIELD_N2, gsm->n2); + params->k_bits = FIELD_PREP(PN_K_FIELD_K, dlci->k); + + return 0; +} + /** * gsm_register_devices - register all tty devices for a given mux index * @@ -1450,6 +1530,116 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, dlci->modem_rx = mlines; } +/** + * gsm_process_negotiation - process received parameters + * @gsm: GSM channel + * @addr: DLCI address + * @cr: command/response + * @params: encoded parameters from the parameter negotiation message + * + * Used when the response for our parameter negotiation command was + * received. + */ +static int gsm_process_negotiation(struct gsm_mux *gsm, unsigned int addr, + unsigned int cr, + const struct gsm_dlci_param_bits *params) +{ + struct gsm_dlci *dlci = gsm->dlci[addr]; + unsigned int ftype, i, adaption, prio, n1, k; + + i = FIELD_GET(PN_I_CL_FIELD_FTYPE, params->i_cl_bits); + adaption = FIELD_GET(PN_I_CL_FIELD_ADAPTION, params->i_cl_bits) + 1; + prio = FIELD_GET(PN_P_FIELD_PRIO, params->p_bits); + n1 = FIELD_GET(PN_N_FIELD_N1, get_unaligned_le16(¶ms->n_bits)); + k = FIELD_GET(PN_K_FIELD_K, params->k_bits); + + if (n1 < MIN_MTU) { + if (debug & DBG_ERRORS) + pr_info("%s N1 out of range in PN\n", __func__); + return -EINVAL; + } + + switch (i) { + case 0x00: + ftype = UIH; + break; + case 0x01: + ftype = UI; + break; + case 0x02: /* I frames are not supported */ + if (debug & DBG_ERRORS) + pr_info("%s unsupported I frame request in PN\n", + __func__); + return -EINVAL; + default: + if (debug & DBG_ERRORS) + pr_info("%s i out of range in PN\n", __func__); + return -EINVAL; + } + + if (!cr && gsm->initiator) { + if (adaption != dlci->adaption) { + if (debug & DBG_ERRORS) + pr_info("%s invalid adaption %d in PN\n", + __func__, adaption); + return -EINVAL; + } + if (prio != dlci->prio) { + if (debug & DBG_ERRORS) + pr_info("%s invalid priority %d in PN", + __func__, prio); + return -EINVAL; + } + if (n1 > gsm->mru || n1 > dlci->mtu) { + /* We requested a frame size but the other party wants + * to send larger frames. The standard allows only a + * smaller response value than requested (5.4.6.3.1). + */ + if (debug & DBG_ERRORS) + pr_info("%s invalid N1 %d in PN\n", __func__, + n1); + return -EINVAL; + } + dlci->mtu = n1; + if (ftype != dlci->ftype) { + if (debug & DBG_ERRORS) + pr_info("%s invalid i %d in PN\n", __func__, i); + return -EINVAL; + } + if (ftype != UI && ftype != UIH && k > dlci->k) { + if (debug & DBG_ERRORS) + pr_info("%s invalid k %d in PN\n", __func__, k); + return -EINVAL; + } + dlci->k = k; + } else if (cr && !gsm->initiator) { + /* Only convergence layer type 1 and 2 are supported. */ + if (adaption != 1 && adaption != 2) { + if (debug & DBG_ERRORS) + pr_info("%s invalid adaption %d in PN\n", + __func__, adaption); + return -EINVAL; + } + dlci->adaption = adaption; + if (n1 > gsm->mru) { + /* Propose a smaller value */ + dlci->mtu = gsm->mru; + } else if (n1 > MAX_MTU) { + /* Propose a smaller value */ + dlci->mtu = MAX_MTU; + } else { + dlci->mtu = n1; + } + dlci->prio = prio; + dlci->ftype = ftype; + dlci->k = k; + } else { + return -EINVAL; + } + + return 0; +} + /** * gsm_control_modem - modem status received * @gsm: GSM channel @@ -1503,6 +1693,65 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen) gsm_control_reply(gsm, CMD_MSC, data, clen); } +/** + * gsm_control_negotiation - parameter negotiation received + * @gsm: GSM channel + * @cr: command/response flag + * @data: data following command + * @dlen: data length + * + * We have received a parameter negotiation message. This is used by + * the GSM mux protocol to configure protocol parameters for a new DLCI. + */ +static void gsm_control_negotiation(struct gsm_mux *gsm, unsigned int cr, + const u8 *data, unsigned int dlen) +{ + unsigned int addr; + struct gsm_dlci_param_bits pn_reply; + struct gsm_dlci *dlci; + struct gsm_dlci_param_bits *params; + + if (dlen < sizeof(struct gsm_dlci_param_bits)) + return; + + /* Invalid DLCI? */ + params = (struct gsm_dlci_param_bits *)data; + addr = FIELD_GET(PN_D_FIELD_DLCI, params->d_bits); + if (addr == 0 || addr >= NUM_DLCI || !gsm->dlci[addr]) + return; + dlci = gsm->dlci[addr]; + + /* Too late for parameter negotiation? */ + if ((!cr && dlci->state == DLCI_OPENING) || dlci->state == DLCI_OPEN) + return; + + /* Process the received parameters */ + if (gsm_process_negotiation(gsm, addr, cr, params) != 0) { + /* Negotiation failed. Close the link. */ + if (debug & DBG_ERRORS) + pr_info("%s PN failed\n", __func__); + gsm_dlci_close(dlci); + return; + } + + if (cr) { + /* Reply command with accepted parameters. */ + if (gsm_encode_params(dlci, &pn_reply) == 0) + gsm_control_reply(gsm, CMD_PN, (const u8 *)&pn_reply, + sizeof(pn_reply)); + else if (debug & DBG_ERRORS) + pr_info("%s PN invalid\n", __func__); + } else if (dlci->state == DLCI_CONFIGURE) { + /* Proceed with link setup by sending SABM before UA */ + dlci->state = DLCI_OPENING; + gsm_command(gsm, dlci->addr, SABM|PF); + mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); + } else { + if (debug & DBG_ERRORS) + pr_info("%s PN in invalid state\n", __func__); + } +} + /** * gsm_control_rls - remote line status * @gsm: GSM channel @@ -1612,8 +1861,12 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, /* Modem wishes to enter power saving state */ gsm_control_reply(gsm, CMD_PSC, NULL, 0); break; + /* Optional commands */ + case CMD_PN: + /* Modem sends a parameter negotiation command */ + gsm_control_negotiation(gsm, 1, data, clen); + break; /* Optional unsupported commands */ - case CMD_PN: /* Parameter negotiation */ case CMD_RPN: /* Remote port negotiation */ case CMD_SNC: /* Service negotiation command */ default: @@ -1646,8 +1899,8 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, spin_lock_irqsave(&gsm->control_lock, flags); ctrl = gsm->pending_cmd; - /* Does the reply match our command */ command |= 1; + /* Does the reply match our command */ if (ctrl != NULL && (command == ctrl->cmd || command == CMD_NSC)) { /* Our command was replied to, kill the retry timer */ del_timer(&gsm->t2_timer); @@ -1657,6 +1910,9 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, ctrl->error = -EOPNOTSUPP; ctrl->done = 1; wake_up(&gsm->event); + /* Or did we receive the PN response to our PN command */ + } else if (command == CMD_PN) { + gsm_control_negotiation(gsm, 0, data, clen); } spin_unlock_irqrestore(&gsm->control_lock, flags); } @@ -1834,6 +2090,32 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) wake_up(&dlci->gsm->event); } +/** + * gsm_dlci_negotiate - start parameter negotiation + * @dlci: DLCI to open + * + * Starts the parameter negotiation for the new DLCI. This needs to be done + * before the DLCI initialized the channel via SABM. + */ +static int gsm_dlci_negotiate(struct gsm_dlci *dlci) +{ + struct gsm_mux *gsm = dlci->gsm; + struct gsm_dlci_param_bits params; + int ret; + + ret = gsm_encode_params(dlci, ¶ms); + if (ret != 0) + return ret; + + /* We cannot asynchronous wait for the command response with + * gsm_command() and gsm_control_wait() at this point. + */ + ret = gsm_control_command(gsm, CMD_PN, (const u8 *)¶ms, + sizeof(params)); + + return ret; +} + /** * gsm_dlci_t1 - T1 timer expiry * @t: timer contained in the DLCI that opened @@ -1855,6 +2137,14 @@ static void gsm_dlci_t1(struct timer_list *t) struct gsm_mux *gsm = dlci->gsm; switch (dlci->state) { + case DLCI_CONFIGURE: + if (dlci->retries && gsm_dlci_negotiate(dlci) == 0) { + dlci->retries--; + mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); + } else { + gsm_dlci_begin_close(dlci); /* prevent half open link */ + } + break; case DLCI_OPENING: if (dlci->retries) { dlci->retries--; @@ -1893,17 +2183,46 @@ static void gsm_dlci_t1(struct timer_list *t) * to the modem which should then reply with a UA or ADM, at which point * we will move into open state. Opening is done asynchronously with retry * running off timers and the responses. + * Parameter negotiation is performed before SABM if required. */ static void gsm_dlci_begin_open(struct gsm_dlci *dlci) { - struct gsm_mux *gsm = dlci->gsm; - if (dlci->state == DLCI_OPEN || dlci->state == DLCI_OPENING) + struct gsm_mux *gsm = dlci ? dlci->gsm : NULL; + bool need_pn = false; + + if (!gsm) return; - dlci->retries = gsm->n2; - dlci->state = DLCI_OPENING; - gsm_command(dlci->gsm, dlci->addr, SABM|PF); - mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); + + if (dlci->addr != 0) { + if (gsm->adaption != 1 || gsm->adaption != dlci->adaption) + need_pn = true; + if (dlci->prio != (roundup(dlci->addr + 1, 8) - 1)) + need_pn = true; + if (gsm->ftype != dlci->ftype) + need_pn = true; + } + + switch (dlci->state) { + case DLCI_CLOSED: + case DLCI_CLOSING: + dlci->retries = gsm->n2; + if (!need_pn) { + dlci->state = DLCI_OPENING; + gsm_command(gsm, dlci->addr, SABM|PF); + } else { + /* Configure DLCI before setup */ + dlci->state = DLCI_CONFIGURE; + if (gsm_dlci_negotiate(dlci) != 0) { + gsm_dlci_close(dlci); + return; + } + } + mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); + break; + default: + break; + } } /** -- GitLab From a3be423f0657e603b45998ef2bb9e5d27dc226c3 Mon Sep 17 00:00:00 2001 From: Shaomin Deng Date: Sat, 5 Nov 2022 11:26:56 -0400 Subject: [PATCH 0431/1480] tty: n_gsm: Delete unneeded semicolon Delete the unneeded semicolon after curly braces. Signed-off-by: Shaomin Deng Link: https://lore.kernel.org/r/20221105152656.4638-1-dengshaomin@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index cde1e846c81e3..4ef88e6b18705 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1379,7 +1379,7 @@ static int gsm_dlci_data_sweep(struct gsm_mux *gsm) } if (!sent) break; - }; + } return ret; } -- GitLab From ce8cc75c7419ad54cb99437543a54c97c7446db5 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 18 Oct 2022 16:34:24 +0800 Subject: [PATCH 0432/1480] drivers: staging: r8188eu: Fix sleep-in-atomic-context bug in rtw_join_timeout_handler The rtw_join_timeout_handler() is a timer handler that runs in atomic context, but it could call msleep(). As a result, the sleep-in-atomic-context bug will happen. The process is shown below: (atomic context) rtw_join_timeout_handler _rtw_join_timeout_handler rtw_do_join rtw_select_and_join_from_scanned_queue rtw_indicate_disconnect rtw_lps_ctrl_wk_cmd lps_ctrl_wk_hdl LPS_Leave LPS_RF_ON_check msleep //sleep in atomic context Fix by removing msleep() and replacing with mdelay(). Fixes: 15865124feed ("staging: r8188eu: introduce new core dir for RTL8188eu driver") Signed-off-by: Duoming Zhou Link: https://lore.kernel.org/r/20221018083424.79741-1-duoming@zju.edu.cn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_pwrctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c index 870d81735b8dc..5290ac36f08c1 100644 --- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c @@ -273,7 +273,7 @@ static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) err = -1; break; } - msleep(1); + mdelay(1); } return err; -- GitLab From 8ce256540f41c84cb910a681c2cb84e8c80ab8db Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Nov 2022 14:34:46 -0600 Subject: [PATCH 0433/1480] staging: ks7010: Avoid clashing function prototypes When built with Control Flow Integrity, function prototypes between caller and function declaration must match. These mismatches are visible at compile time with the new -Wcast-function-type-strict in Clang[1]. Fix a total of 27 warnings like these: drivers/staging/ks7010/ks_wlan_net.c:2415:2: warning: cast from 'int (*)(struct net_device *, struct iw_request_info *, struct iw_point *, char *)' to 'iw_handler' (aka 'int (*)(struct net_device *, struct iw_request_info *, union iwreq_data *, char *)') converts to incompatible function type [-Wcast-function-type-strict] (iw_handler)ks_wlan_get_firmware_version,/* 3 KS_WLAN_GET_FIRM_VERSION */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ks_wlan_net Wireless Extension handler callbacks (iw_handler) use a union for the data argument. Actually use the union and perform explicit member selection in the function body instead of having a function prototype mismatch. There are no resulting binary differences before/after changes. These changes were made partly manually and partly with the help of Coccinelle. Link: https://reviews.llvm.org/D134831 [1] Signed-off-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/8d2ceee1248b5a76e9b6c379f578e65482c91168.1667934775.git.gustavoars@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ks7010/ks_wlan_net.c | 248 ++++++++++++++------------- 1 file changed, 126 insertions(+), 122 deletions(-) diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index 7e8d37c169f0f..044c807ca0223 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -1763,8 +1763,8 @@ static struct iw_statistics *ks_get_wireless_stats(struct net_device *dev) } static int ks_wlan_set_stop_request(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); @@ -1772,7 +1772,7 @@ static int ks_wlan_set_stop_request(struct net_device *dev, return -EPERM; /* for SLEEP MODE */ - if (!(*uwrq)) + if (!(uwrq->mode)) return -EINVAL; hostif_sme_enqueue(priv, SME_STOP_REQUEST); @@ -1786,7 +1786,9 @@ static int ks_wlan_set_mlme(struct net_device *dev, { struct ks_wlan_private *priv = netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *)extra; - __u32 mode = 1; + union iwreq_data uwrq; + + uwrq.mode = 1; if (priv->sleep_mode == SLP_SLEEP) return -EPERM; @@ -1799,13 +1801,14 @@ static int ks_wlan_set_mlme(struct net_device *dev, mlme->reason_code == WLAN_REASON_MIC_FAILURE) return 0; - return ks_wlan_set_stop_request(dev, NULL, &mode, NULL); + return ks_wlan_set_stop_request(dev, NULL, &uwrq, NULL); } static int ks_wlan_get_firmware_version(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) + union iwreq_data *uwrq, char *extra) { + struct iw_point *dwrq = &uwrq->data; struct ks_wlan_private *priv = netdev_priv(dev); dwrq->length = priv->version_size + 1; @@ -1814,8 +1817,8 @@ static int ks_wlan_get_firmware_version(struct net_device *dev, } static int ks_wlan_set_preamble(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); @@ -1823,17 +1826,17 @@ static int ks_wlan_set_preamble(struct net_device *dev, return -EPERM; /* for SLEEP MODE */ - if (*uwrq != LONG_PREAMBLE && *uwrq != SHORT_PREAMBLE) + if (uwrq->mode != LONG_PREAMBLE && uwrq->mode != SHORT_PREAMBLE) return -EINVAL; - priv->reg.preamble = *uwrq; + priv->reg.preamble = uwrq->mode; priv->need_commit |= SME_MODE_SET; return -EINPROGRESS; /* Call commit handler */ } static int ks_wlan_get_preamble(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); @@ -1841,37 +1844,37 @@ static int ks_wlan_get_preamble(struct net_device *dev, return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.preamble; + uwrq->mode = priv->reg.preamble; return 0; } static int ks_wlan_set_power_mgmt(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; - if (*uwrq != POWER_MGMT_ACTIVE && - *uwrq != POWER_MGMT_SAVE1 && - *uwrq != POWER_MGMT_SAVE2) + if (uwrq->mode != POWER_MGMT_ACTIVE && + uwrq->mode != POWER_MGMT_SAVE1 && + uwrq->mode != POWER_MGMT_SAVE2) return -EINVAL; - if ((*uwrq == POWER_MGMT_SAVE1 || *uwrq == POWER_MGMT_SAVE2) && + if ((uwrq->mode == POWER_MGMT_SAVE1 || uwrq->mode == POWER_MGMT_SAVE2) && (priv->reg.operation_mode != MODE_INFRASTRUCTURE)) return -EINVAL; - priv->reg.power_mgmt = *uwrq; + priv->reg.power_mgmt = uwrq->mode; hostif_sme_enqueue(priv, SME_POW_MNGMT_REQUEST); return 0; } static int ks_wlan_get_power_mgmt(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); @@ -1879,13 +1882,13 @@ static int ks_wlan_get_power_mgmt(struct net_device *dev, return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.power_mgmt; + uwrq->mode = priv->reg.power_mgmt; return 0; } static int ks_wlan_set_scan_type(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); @@ -1893,39 +1896,39 @@ static int ks_wlan_set_scan_type(struct net_device *dev, return -EPERM; /* for SLEEP MODE */ - if (*uwrq != ACTIVE_SCAN && *uwrq != PASSIVE_SCAN) + if (uwrq->mode != ACTIVE_SCAN && uwrq->mode != PASSIVE_SCAN) return -EINVAL; - priv->reg.scan_type = *uwrq; + priv->reg.scan_type = uwrq->mode; return 0; } static int ks_wlan_get_scan_type(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.scan_type; + uwrq->mode = priv->reg.scan_type; return 0; } static int ks_wlan_set_beacon_lost(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - if (*uwrq > BEACON_LOST_COUNT_MAX) + if (uwrq->mode > BEACON_LOST_COUNT_MAX) return -EINVAL; - priv->reg.beacon_lost_count = *uwrq; + priv->reg.beacon_lost_count = uwrq->mode; if (priv->reg.operation_mode == MODE_INFRASTRUCTURE) { priv->need_commit |= SME_MODE_SET; @@ -1936,101 +1939,101 @@ static int ks_wlan_set_beacon_lost(struct net_device *dev, } static int ks_wlan_get_beacon_lost(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.beacon_lost_count; + uwrq->mode = priv->reg.beacon_lost_count; return 0; } static int ks_wlan_set_phy_type(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; - if (*uwrq != D_11B_ONLY_MODE && - *uwrq != D_11G_ONLY_MODE && - *uwrq != D_11BG_COMPATIBLE_MODE) + if (uwrq->mode != D_11B_ONLY_MODE && + uwrq->mode != D_11G_ONLY_MODE && + uwrq->mode != D_11BG_COMPATIBLE_MODE) return -EINVAL; /* for SLEEP MODE */ - priv->reg.phy_type = *uwrq; + priv->reg.phy_type = uwrq->mode; priv->need_commit |= SME_MODE_SET; return -EINPROGRESS; /* Call commit handler */ } static int ks_wlan_get_phy_type(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.phy_type; + uwrq->mode = priv->reg.phy_type; return 0; } static int ks_wlan_set_cts_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - if (*uwrq != CTS_MODE_FALSE && *uwrq != CTS_MODE_TRUE) + if (uwrq->mode != CTS_MODE_FALSE && uwrq->mode != CTS_MODE_TRUE) return -EINVAL; - priv->reg.cts_mode = (*uwrq == CTS_MODE_FALSE) ? *uwrq : + priv->reg.cts_mode = (uwrq->mode == CTS_MODE_FALSE) ? uwrq->mode : (priv->reg.phy_type == D_11G_ONLY_MODE || priv->reg.phy_type == D_11BG_COMPATIBLE_MODE) ? - *uwrq : !*uwrq; + uwrq->mode : !uwrq->mode; priv->need_commit |= SME_MODE_SET; return -EINPROGRESS; /* Call commit handler */ } static int ks_wlan_get_cts_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->reg.cts_mode; + uwrq->mode = priv->reg.cts_mode; return 0; } static int ks_wlan_set_sleep_mode(struct net_device *dev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); - if (*uwrq != SLP_SLEEP && - *uwrq != SLP_ACTIVE) { - netdev_err(dev, "SET_SLEEP_MODE %d error\n", *uwrq); + if (uwrq->mode != SLP_SLEEP && + uwrq->mode != SLP_ACTIVE) { + netdev_err(dev, "SET_SLEEP_MODE %d error\n", uwrq->mode); return -EINVAL; } - priv->sleep_mode = *uwrq; + priv->sleep_mode = uwrq->mode; netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode); - if (*uwrq == SLP_SLEEP) + if (uwrq->mode == SLP_SLEEP) hostif_sme_enqueue(priv, SME_STOP_REQUEST); hostif_sme_enqueue(priv, SME_SLEEP_REQUEST); @@ -2040,52 +2043,53 @@ static int ks_wlan_set_sleep_mode(struct net_device *dev, static int ks_wlan_get_sleep_mode(struct net_device *dev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); - *uwrq = priv->sleep_mode; + uwrq->mode = priv->sleep_mode; return 0; } static int ks_wlan_set_wps_enable(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - if (*uwrq != 0 && *uwrq != 1) + if (uwrq->mode != 0 && uwrq->mode != 1) return -EINVAL; - priv->wps.wps_enabled = *uwrq; + priv->wps.wps_enabled = uwrq->mode; hostif_sme_enqueue(priv, SME_WPS_ENABLE_REQUEST); return 0; } static int ks_wlan_get_wps_enable(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->wps.wps_enabled; - netdev_info(dev, "return=%d\n", *uwrq); + uwrq->mode = priv->wps.wps_enabled; + netdev_info(dev, "return=%d\n", uwrq->mode); return 0; } static int ks_wlan_set_wps_probe_req(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) + union iwreq_data *uwrq, char *extra) { + struct iw_point *dwrq = &uwrq->data; u8 *p = extra; unsigned char len; struct ks_wlan_private *priv = netdev_priv(dev); @@ -2114,76 +2118,76 @@ static int ks_wlan_set_wps_probe_req(struct net_device *dev, } static int ks_wlan_set_tx_gain(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - if (*uwrq > 0xFF) + if (uwrq->mode > 0xFF) return -EINVAL; - priv->gain.tx_gain = (u8)*uwrq; + priv->gain.tx_gain = (u8)uwrq->mode; priv->gain.tx_mode = (priv->gain.tx_gain < 0xFF) ? 1 : 0; hostif_sme_enqueue(priv, SME_SET_GAIN); return 0; } static int ks_wlan_get_tx_gain(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->gain.tx_gain; + uwrq->mode = priv->gain.tx_gain; hostif_sme_enqueue(priv, SME_GET_GAIN); return 0; } static int ks_wlan_set_rx_gain(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - if (*uwrq > 0xFF) + if (uwrq->mode > 0xFF) return -EINVAL; - priv->gain.rx_gain = (u8)*uwrq; + priv->gain.rx_gain = (u8)uwrq->mode; priv->gain.rx_mode = (priv->gain.rx_gain < 0xFF) ? 1 : 0; hostif_sme_enqueue(priv, SME_SET_GAIN); return 0; } static int ks_wlan_get_rx_gain(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); if (priv->sleep_mode == SLP_SLEEP) return -EPERM; /* for SLEEP MODE */ - *uwrq = priv->gain.rx_gain; + uwrq->mode = priv->gain.rx_gain; hostif_sme_enqueue(priv, SME_GET_GAIN); return 0; } static int ks_wlan_get_eeprom_cksum(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) { struct ks_wlan_private *priv = netdev_priv(dev); - *uwrq = priv->eeprom_checksum; + uwrq->mode = priv->eeprom_checksum; return 0; } @@ -2302,7 +2306,7 @@ static void print_hif_event(struct net_device *dev, int event) /* get host command history */ static int ks_wlan_hostt(struct net_device *dev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + union iwreq_data *uwrq, char *extra) { int i, event; struct ks_wlan_private *priv = netdev_priv(dev); @@ -2409,38 +2413,38 @@ static const iw_handler ks_wlan_handler[] = { /* private_handler */ static const iw_handler ks_wlan_private_handler[] = { - (iw_handler)NULL, /* 0 */ - (iw_handler)NULL, /* 1, KS_WLAN_GET_DRIVER_VERSION */ - (iw_handler)NULL, /* 2 */ - (iw_handler)ks_wlan_get_firmware_version,/* 3 KS_WLAN_GET_FIRM_VERSION */ - (iw_handler)ks_wlan_set_wps_enable, /* 4 KS_WLAN_SET_WPS_ENABLE */ - (iw_handler)ks_wlan_get_wps_enable, /* 5 KS_WLAN_GET_WPS_ENABLE */ - (iw_handler)ks_wlan_set_wps_probe_req, /* 6 KS_WLAN_SET_WPS_PROBE_REQ */ - (iw_handler)ks_wlan_get_eeprom_cksum, /* 7 KS_WLAN_GET_CONNECT */ - (iw_handler)ks_wlan_set_preamble, /* 8 KS_WLAN_SET_PREAMBLE */ - (iw_handler)ks_wlan_get_preamble, /* 9 KS_WLAN_GET_PREAMBLE */ - (iw_handler)ks_wlan_set_power_mgmt, /* 10 KS_WLAN_SET_POWER_SAVE */ - (iw_handler)ks_wlan_get_power_mgmt, /* 11 KS_WLAN_GET_POWER_SAVE */ - (iw_handler)ks_wlan_set_scan_type, /* 12 KS_WLAN_SET_SCAN_TYPE */ - (iw_handler)ks_wlan_get_scan_type, /* 13 KS_WLAN_GET_SCAN_TYPE */ - (iw_handler)ks_wlan_set_rx_gain, /* 14 KS_WLAN_SET_RX_GAIN */ - (iw_handler)ks_wlan_get_rx_gain, /* 15 KS_WLAN_GET_RX_GAIN */ - (iw_handler)ks_wlan_hostt, /* 16 KS_WLAN_HOSTT */ - (iw_handler)NULL, /* 17 */ - (iw_handler)ks_wlan_set_beacon_lost, /* 18 KS_WLAN_SET_BECAN_LOST */ - (iw_handler)ks_wlan_get_beacon_lost, /* 19 KS_WLAN_GET_BECAN_LOST */ - (iw_handler)ks_wlan_set_tx_gain, /* 20 KS_WLAN_SET_TX_GAIN */ - (iw_handler)ks_wlan_get_tx_gain, /* 21 KS_WLAN_GET_TX_GAIN */ - (iw_handler)ks_wlan_set_phy_type, /* 22 KS_WLAN_SET_PHY_TYPE */ - (iw_handler)ks_wlan_get_phy_type, /* 23 KS_WLAN_GET_PHY_TYPE */ - (iw_handler)ks_wlan_set_cts_mode, /* 24 KS_WLAN_SET_CTS_MODE */ - (iw_handler)ks_wlan_get_cts_mode, /* 25 KS_WLAN_GET_CTS_MODE */ - (iw_handler)NULL, /* 26 */ - (iw_handler)NULL, /* 27 */ - (iw_handler)ks_wlan_set_sleep_mode, /* 28 KS_WLAN_SET_SLEEP_MODE */ - (iw_handler)ks_wlan_get_sleep_mode, /* 29 KS_WLAN_GET_SLEEP_MODE */ - (iw_handler)NULL, /* 30 */ - (iw_handler)NULL, /* 31 */ + NULL, /* 0 */ + NULL, /* 1, KS_WLAN_GET_DRIVER_VERSION */ + NULL, /* 2 */ + ks_wlan_get_firmware_version, /* 3 KS_WLAN_GET_FIRM_VERSION */ + ks_wlan_set_wps_enable, /* 4 KS_WLAN_SET_WPS_ENABLE */ + ks_wlan_get_wps_enable, /* 5 KS_WLAN_GET_WPS_ENABLE */ + ks_wlan_set_wps_probe_req, /* 6 KS_WLAN_SET_WPS_PROBE_REQ */ + ks_wlan_get_eeprom_cksum, /* 7 KS_WLAN_GET_CONNECT */ + ks_wlan_set_preamble, /* 8 KS_WLAN_SET_PREAMBLE */ + ks_wlan_get_preamble, /* 9 KS_WLAN_GET_PREAMBLE */ + ks_wlan_set_power_mgmt, /* 10 KS_WLAN_SET_POWER_SAVE */ + ks_wlan_get_power_mgmt, /* 11 KS_WLAN_GET_POWER_SAVE */ + ks_wlan_set_scan_type, /* 12 KS_WLAN_SET_SCAN_TYPE */ + ks_wlan_get_scan_type, /* 13 KS_WLAN_GET_SCAN_TYPE */ + ks_wlan_set_rx_gain, /* 14 KS_WLAN_SET_RX_GAIN */ + ks_wlan_get_rx_gain, /* 15 KS_WLAN_GET_RX_GAIN */ + ks_wlan_hostt, /* 16 KS_WLAN_HOSTT */ + NULL, /* 17 */ + ks_wlan_set_beacon_lost, /* 18 KS_WLAN_SET_BECAN_LOST */ + ks_wlan_get_beacon_lost, /* 19 KS_WLAN_GET_BECAN_LOST */ + ks_wlan_set_tx_gain, /* 20 KS_WLAN_SET_TX_GAIN */ + ks_wlan_get_tx_gain, /* 21 KS_WLAN_GET_TX_GAIN */ + ks_wlan_set_phy_type, /* 22 KS_WLAN_SET_PHY_TYPE */ + ks_wlan_get_phy_type, /* 23 KS_WLAN_GET_PHY_TYPE */ + ks_wlan_set_cts_mode, /* 24 KS_WLAN_SET_CTS_MODE */ + ks_wlan_get_cts_mode, /* 25 KS_WLAN_GET_CTS_MODE */ + NULL, /* 26 */ + NULL, /* 27 */ + ks_wlan_set_sleep_mode, /* 28 KS_WLAN_SET_SLEEP_MODE */ + ks_wlan_get_sleep_mode, /* 29 KS_WLAN_GET_SLEEP_MODE */ + NULL, /* 30 */ + NULL, /* 31 */ }; static const struct iw_handler_def ks_wlan_handler_def = { @@ -2461,7 +2465,7 @@ static int ks_wlan_netdev_ioctl(struct net_device *dev, struct ifreq *rq, switch (cmd) { case SIOCIWFIRSTPRIV + 20: /* KS_WLAN_SET_STOP_REQ */ - ret = ks_wlan_set_stop_request(dev, NULL, &wrq->u.mode, NULL); + ret = ks_wlan_set_stop_request(dev, NULL, &wrq->u, NULL); break; // All other calls are currently unsupported default: -- GitLab From fb7d5ebea988899500e9a067d950034dbe8a0fbd Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 9 Nov 2022 16:12:43 +0530 Subject: [PATCH 0434/1480] staging: fieldbus: use sysfs_emit() in show functions The show() methods should only use sysfs_emit() when formatting values to be returned to the user space. Ref: Documentation/filesystems/sysfs.rst Issue identified by coccicheck. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y2uEIzebbM/Fs5Jz@qemulion Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fieldbus/dev_core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/fieldbus/dev_core.c b/drivers/staging/fieldbus/dev_core.c index 5aab734606eae..5f54f2674bd19 100644 --- a/drivers/staging/fieldbus/dev_core.c +++ b/drivers/staging/fieldbus/dev_core.c @@ -28,7 +28,7 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr, { struct fieldbus_dev *fb = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", !!fb->online); + return sysfs_emit(buf, "%d\n", !!fb->online); } static DEVICE_ATTR_RO(online); @@ -39,7 +39,7 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, if (!fb->enable_get) return -EINVAL; - return sprintf(buf, "%d\n", !!fb->enable_get(fb)); + return sysfs_emit(buf, "%d\n", !!fb->enable_get(fb)); } static ssize_t enabled_store(struct device *dev, struct device_attribute *attr, @@ -66,11 +66,8 @@ static ssize_t card_name_show(struct device *dev, struct device_attribute *attr, { struct fieldbus_dev *fb = dev_get_drvdata(dev); - /* - * card_name was provided by child driver, could potentially be long. - * protect against buffer overrun. - */ - return snprintf(buf, PAGE_SIZE, "%s\n", fb->card_name); + /* card_name was provided by child driver. */ + return sysfs_emit(buf, "%s\n", fb->card_name); } static DEVICE_ATTR_RO(card_name); @@ -79,7 +76,7 @@ static ssize_t read_area_size_show(struct device *dev, { struct fieldbus_dev *fb = dev_get_drvdata(dev); - return sprintf(buf, "%zu\n", fb->read_area_sz); + return sysfs_emit(buf, "%zu\n", fb->read_area_sz); } static DEVICE_ATTR_RO(read_area_size); @@ -88,7 +85,7 @@ static ssize_t write_area_size_show(struct device *dev, { struct fieldbus_dev *fb = dev_get_drvdata(dev); - return sprintf(buf, "%zu\n", fb->write_area_sz); + return sysfs_emit(buf, "%zu\n", fb->write_area_sz); } static DEVICE_ATTR_RO(write_area_size); @@ -116,7 +113,7 @@ static ssize_t fieldbus_type_show(struct device *dev, break; } - return sprintf(buf, "%s\n", t); + return sysfs_emit(buf, "%s\n", t); } static DEVICE_ATTR_RO(fieldbus_type); -- GitLab From 335140116703920ddcbd9a09ae9edfb02902f3d1 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Tue, 8 Nov 2022 23:39:56 +0530 Subject: [PATCH 0435/1480] staging: rtl8192u: remove redundant macro definitions Several ieee80211_* symbol names are extended with _rsl tag using macros. This is done to avoid a conflict when a similar symbol is already in use in another part of kernel and may lead to conflicts. However, most of these base symbol names are not found to being used anywhere in the code and hence are not useful today. These symbols are not used outside of the module and hence can be safely removed. The code continues to use the original symbol names. Suggested-by: Greg Kroah-Hartman Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/17f69a042e215c484931a0327fdf7775eea5f918.1667930292.git.drv@mailo.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192u/ieee80211/ieee80211.h | 61 ------------------- 1 file changed, 61 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 00c07455cbb3b..c5c43d2fb93eb 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -223,71 +223,10 @@ struct cb_desc { #define MAX_IE_LEN 0xff // added for kernel conflict -#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl -#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl -#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl -#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rsl -#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl -#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rsl - -#define ieee80211_ccmp_null ieee80211_ccmp_null_rsl - -#define free_ieee80211 free_ieee80211_rsl -#define alloc_ieee80211 alloc_ieee80211_rsl - -#define ieee80211_rx ieee80211_rx_rsl -#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl - -#define ieee80211_get_beacon ieee80211_get_beacon_rsl #define ieee80211_wake_queue ieee80211_wake_queue_rsl #define ieee80211_stop_queue ieee80211_stop_queue_rsl -#define ieee80211_reset_queue ieee80211_reset_queue_rsl -#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl -#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl -#define ieee80211_is_shortslot ieee80211_is_shortslot_rsl -#define ieee80211_is_54g ieee80211_is_54g_rsl -#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl -#define ieee80211_ps_tx_ack ieee80211_ps_tx_ack_rsl -#define ieee80211_softmac_xmit ieee80211_softmac_xmit_rsl -#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rsl #define notify_wx_assoc_event notify_wx_assoc_event_rsl #define SendDisassociation SendDisassociation_rsl -#define ieee80211_disassociate ieee80211_disassociate_rsl -#define ieee80211_start_send_beacons ieee80211_start_send_beacons_rsl -#define ieee80211_stop_scan ieee80211_stop_scan_rsl -#define ieee80211_send_probe_requests ieee80211_send_probe_requests_rsl -#define ieee80211_softmac_scan_syncro ieee80211_softmac_scan_syncro_rsl -#define ieee80211_start_scan_syncro ieee80211_start_scan_syncro_rsl - -#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rsl -#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rsl -#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rsl -#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rsl -#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rsl -#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rsl -#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rsl -#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rsl -#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rsl -#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rsl -#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rsl -#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rsl -#define ieee80211_wx_get_name ieee80211_wx_get_name_rsl -#define ieee80211_wx_set_power ieee80211_wx_set_power_rsl -#define ieee80211_wx_get_power ieee80211_wx_get_power_rsl -#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rsl -#define ieee80211_wx_set_rts ieee80211_wx_set_rts_rsl -#define ieee80211_wx_get_rts ieee80211_wx_get_rts_rsl - -#define ieee80211_txb_free ieee80211_txb_free_rsl - -#define ieee80211_wx_set_gen_ie ieee80211_wx_set_gen_ie_rsl -#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl -#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl -#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl -#define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl -#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl -#define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl -#define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl struct ieee_param { -- GitLab From 8c3e8a6bdb5253b97ad532570f8b5db5f7a06407 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 26 Oct 2022 16:28:03 +0800 Subject: [PATCH 0436/1480] class: fix possible memory leak in __class_register() If class_add_groups() returns error, the 'cp->subsys' need be unregister, and the 'cp' need be freed. We can not call kset_unregister() here, because the 'cls' will be freed in callback function class_release() and it's also freed in caller's error path, it will cause double free. So fix this by calling kobject_del() and kfree_const(name) to cleanup kobject. Besides, call kfree() to free the 'cp'. Fault injection test can trigger this: unreferenced object 0xffff888102fa8190 (size 8): comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s) hex dump (first 8 bytes): 70 6b 74 63 64 76 64 00 pktcdvd. backtrace: [<00000000e7c7703d>] __kmalloc_track_caller+0x1ae/0x320 [<000000005e4d70bc>] kstrdup+0x3a/0x70 [<00000000c2e5e85a>] kstrdup_const+0x68/0x80 [<000000000049a8c7>] kvasprintf_const+0x10b/0x190 [<0000000029123163>] kobject_set_name_vargs+0x56/0x150 [<00000000747219c9>] kobject_set_name+0xab/0xe0 [<0000000005f1ea4e>] __class_register+0x15c/0x49a unreferenced object 0xffff888037274000 (size 1024): comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s) hex dump (first 32 bytes): 00 40 27 37 80 88 ff ff 00 40 27 37 80 88 ff ff .@'7.....@'7.... 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... backtrace: [<00000000151f9600>] kmem_cache_alloc_trace+0x17c/0x2f0 [<00000000ecf3dd95>] __class_register+0x86/0x49a Fixes: ced6473e7486 ("driver core: class: add class_groups support") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221026082803.3458760-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/base/class.c b/drivers/base/class.c index 64f7b9a0970f7..8ceafb7d0203b 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key) } error = class_add_groups(class_get(cls), cls->class_groups); class_put(cls); + if (error) { + kobject_del(&cp->subsys.kobj); + kfree_const(cp->subsys.kobj.name); + kfree(cp); + } return error; } EXPORT_SYMBOL_GPL(__class_register); -- GitLab From 9e6002ad9e28209dcefa342977ac683779556dbd Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 2 Nov 2022 10:55:34 +0800 Subject: [PATCH 0437/1480] Documentation: devres: add missing MEM helper Add missing devm_kstrdup_const() to devres.rst. It's introduce by commit 09d1ea1c7309 ("devres: provide devm_kstrdup_const()"). Fixes: 09d1ea1c7309 ("devres: provide devm_kstrdup_const()") Cc: Bartosz Golaszewski Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Jonathan Corbet Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221102025534.1450337-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/driver-model/devres.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 687adb58048ec..ac9b9ff37f50e 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -357,6 +357,7 @@ MEM devm_kmemdup() devm_krealloc() devm_kstrdup() + devm_kstrdup_const() devm_kvasprintf() devm_kzalloc() -- GitLab From 6fcd7e702d3d91cc2c3194acffd7d67b2c10b81f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 18 Oct 2022 02:04:10 -0700 Subject: [PATCH 0438/1480] devres: Use kmalloc_size_roundup() to match ksize() usage Round up allocations with kmalloc_size_roundup() so that devres's use of ksize() is always accurate and no special handling of the memory is needed by KASAN, UBSAN_BOUNDS, nor FORTIFY_SOURCE. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221018090406.never.856-kees@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 4ab2b50ee38f4..c0e100074aa39 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -101,6 +101,9 @@ static bool check_dr_size(size_t size, size_t *tot_size) size, tot_size))) return false; + /* Actually allocate the full kmalloc bucket size. */ + *tot_size = kmalloc_size_roundup(*tot_size); + return true; } -- GitLab From e63e99397b2613d50a5f4f02ed07307e67a190f1 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 9 Nov 2022 14:40:36 +0800 Subject: [PATCH 0439/1480] drivers: dio: fix possible memory leak in dio_init() If device_register() returns error, the 'dev' and name needs be freed. Add a release function, and then call put_device() in the error path, so the name is freed in kobject_cleanup() and to the 'dev' is freed in release function. Fixes: 2e4c77bea3d8 ("m68k: dio - Kill warn_unused_result warnings") Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221109064036.1835346-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/dio/dio.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c index 0e5a5662d5a40..0a051d6568800 100644 --- a/drivers/dio/dio.c +++ b/drivers/dio/dio.c @@ -109,6 +109,12 @@ static char dio_no_name[] = { 0 }; #endif /* CONFIG_DIO_CONSTANTS */ +static void dio_dev_release(struct device *dev) +{ + struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev); + kfree(ddev); +} + int __init dio_find(int deviceid) { /* Called to find a DIO device before the full bus scan has run. @@ -225,6 +231,7 @@ static int __init dio_init(void) dev->bus = &dio_bus; dev->dev.parent = &dio_bus.dev; dev->dev.bus = &dio_bus_type; + dev->dev.release = dio_dev_release; dev->scode = scode; dev->resource.start = pa; dev->resource.end = pa + DIO_SIZE(scode, va); @@ -252,6 +259,7 @@ static int __init dio_init(void) if (error) { pr_err("DIO: Error registering device %s\n", dev->name); + put_device(&dev->dev); continue; } error = dio_create_sysfs_dev_files(dev); -- GitLab From 92cf87051894921ab6b14e9ad60dbae2d669bf15 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 3 Nov 2022 17:38:35 -0700 Subject: [PATCH 0440/1480] debugfs: small Documentation cleaning Fix punctuation in a parenthetical phrase. Add 2 article adjectives and change one from "an" to "a". Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20221104003835.29472-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/debugfs.rst b/Documentation/filesystems/debugfs.rst index 71b1fee56d2a8..dc35da8b8792c 100644 --- a/Documentation/filesystems/debugfs.rst +++ b/Documentation/filesystems/debugfs.rst @@ -155,8 +155,8 @@ any code which does so in the mainline. Note that all files created with debugfs_create_blob() are read-only. If you want to dump a block of registers (something that happens quite -often during development, even if little such code reaches mainline. -Debugfs offers two functions: one to make a registers-only file, and +often during development, even if little such code reaches mainline), +debugfs offers two functions: one to make a registers-only file, and another to insert a register block in the middle of another sequential file:: @@ -183,7 +183,7 @@ The "base" argument may be 0, but you may want to build the reg32 array using __stringify, and a number of register names (macros) are actually byte offsets over a base for the register block. -If you want to dump an u32 array in debugfs, you can create file with:: +If you want to dump a u32 array in debugfs, you can create a file with:: struct debugfs_u32_array { u32 *array; @@ -197,7 +197,7 @@ If you want to dump an u32 array in debugfs, you can create file with:: The "array" argument wraps a pointer to the array's data and the number of its elements. Note: Once array is created its size can not be changed. -There is a helper function to create device related seq_file:: +There is a helper function to create a device-related seq_file:: void debugfs_create_devm_seqfile(struct device *dev, const char *name, -- GitLab From 9a6800d1b9da21302758fb37e58b3ab1cadfc643 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 3 Nov 2022 17:39:21 -0700 Subject: [PATCH 0441/1480] sysfs: update Documentation Make editing corrections and updates to sysfs.rst: - spell "sysfs" consistently (vs. "Sysfs") - align field names in a struct - fix some punctuation and grammar - list more /sys top-level subdirectories - change 'fuse.txt' to 'fuse.rst' (although I don't see where the example is) Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20221104003921.31616-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/sysfs.rst | 41 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/Documentation/filesystems/sysfs.rst b/Documentation/filesystems/sysfs.rst index 8bba676b1365d..f8187d466b97b 100644 --- a/Documentation/filesystems/sysfs.rst +++ b/Documentation/filesystems/sysfs.rst @@ -12,10 +12,10 @@ Mike Murphy :Original: 10 January 2003 -What it is: -~~~~~~~~~~~ +What it is +~~~~~~~~~~ -sysfs is a ram-based filesystem initially based on ramfs. It provides +sysfs is a RAM-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace. @@ -43,7 +43,7 @@ userspace. Top-level directories in sysfs represent the common ancestors of object hierarchies; i.e. the subsystems the objects belong to. -Sysfs internally stores a pointer to the kobject that implements a +sysfs internally stores a pointer to the kobject that implements a directory in the kernfs_node object associated with the directory. In the past this kobject pointer has been used by sysfs to do reference counting directly on the kobject whenever the file is opened or closed. @@ -55,7 +55,7 @@ Attributes ~~~~~~~~~~ Attributes can be exported for kobjects in the form of regular files in -the filesystem. Sysfs forwards file I/O operations to methods defined +the filesystem. sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes. @@ -72,8 +72,8 @@ you publicly humiliated and your code rewritten without notice. An attribute definition is simply:: struct attribute { - char * name; - struct module *owner; + char *name; + struct module *owner; umode_t mode; }; @@ -138,7 +138,7 @@ __ATTR_WO(name): assumes a name_store only and is restricted to mode 0200 that is root write access only. __ATTR_RO_MODE(name, mode): - fore more restrictive RO access currently + for more restrictive RO access; currently only use case is the EFI System Resource Table (see drivers/firmware/efi/esrt.c) __ATTR_RW(name): @@ -207,7 +207,7 @@ IOW, they should take only an object, an attribute, and a buffer as parameters. sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the -method. Sysfs will call the method exactly once for each read or +method. sysfs will call the method exactly once for each read or write. This forces the following behavior on the method implementations: @@ -221,7 +221,7 @@ implementations: be called again, rearmed, to fill the buffer. - On write(2), sysfs expects the entire buffer to be passed during the - first write. Sysfs then passes the entire buffer to the store() method. + first write. sysfs then passes the entire buffer to the store() method. A terminating null is added after the data on stores. This makes functions like sysfs_streq() safe to use. @@ -237,7 +237,7 @@ Other notes: - Writing causes the show() method to be rearmed regardless of current file position. -- The buffer will always be PAGE_SIZE bytes in length. On i386, this +- The buffer will always be PAGE_SIZE bytes in length. On x86, this is 4096. - show() methods should return the number of bytes printed into the @@ -253,7 +253,7 @@ Other notes: through, be sure to return an error. - The object passed to the methods will be pinned in memory via sysfs - referencing counting its embedded object. However, the physical + reference counting its embedded object. However, the physical entity (e.g. device) the object represents may not be present. Be sure to have a way to check this, if necessary. @@ -295,8 +295,12 @@ The top level sysfs directory looks like:: dev/ devices/ firmware/ - net/ fs/ + hypervisor/ + kernel/ + module/ + net/ + power/ devices/ contains a filesystem representation of the device tree. It maps directly to the internal kernel device tree, which is a hierarchy of @@ -317,15 +321,18 @@ span multiple bus types). fs/ contains a directory for some filesystems. Currently each filesystem wanting to export attributes must create its own hierarchy -below fs/ (see ./fuse.txt for an example). +below fs/ (see ./fuse.rst for an example). + +module/ contains parameter values and state information for all +loaded system modules, for both builtin and loadable modules. -dev/ contains two directories char/ and block/. Inside these two +dev/ contains two directories: char/ and block/. Inside these two directories there are symlinks named :. These symlinks point to the sysfs directory for the given device. /sys/dev provides a quick way to lookup the sysfs interface for a device from the result of a stat(2) operation. -More information can driver-model specific features can be found in +More information on driver-model specific features can be found in Documentation/driver-api/driver-model/. @@ -335,7 +342,7 @@ TODO: Finish this section. Current Interfaces ~~~~~~~~~~~~~~~~~~ -The following interface layers currently exist in sysfs: +The following interface layers currently exist in sysfs. devices (include/linux/device.h) -- GitLab From fa627348cfc7fb174468d88756b83c2d97890b07 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 Oct 2022 18:54:26 +0200 Subject: [PATCH 0442/1480] driver core: class: make namespace and get_ownership take const * The callbacks in struct class namespace() and get_ownership() do not modify the struct device passed to them, so mark the pointer as constant and fix up all callbacks in the kernel to have the correct function signature. This helps make it more obvious what calls and callbacks do, and do not, modify structures passed to them. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20221001165426.2690912-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- drivers/infiniband/core/device.c | 4 ++-- drivers/net/ipvlan/ipvtap.c | 4 ++-- drivers/net/macvtap.c | 4 ++-- include/linux/device/class.h | 4 ++-- net/core/net-sysfs.c | 8 ++++---- net/wireless/sysfs.c | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index d02501933467d..f07b1c349f791 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2336,7 +2336,7 @@ static void device_release(struct kobject *kobj) static const void *device_namespace(struct kobject *kobj) { - struct device *dev = kobj_to_dev(kobj); + const struct device *dev = kobj_to_dev(kobj); const void *ns = NULL; if (dev->class && dev->class->ns_type) @@ -2347,7 +2347,7 @@ static const void *device_namespace(struct kobject *kobj) static void device_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) { - struct device *dev = kobj_to_dev(kobj); + const struct device *dev = kobj_to_dev(kobj); if (dev->class && dev->class->get_ownership) dev->class->get_ownership(dev, uid, gid); diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index ae60c73babcc5..3893b65174215 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -524,9 +524,9 @@ static int ib_device_uevent(struct device *device, return 0; } -static const void *net_namespace(struct device *d) +static const void *net_namespace(const struct device *d) { - struct ib_core_device *coredev = + const struct ib_core_device *coredev = container_of(d, struct ib_core_device, dev); return read_pnet(&coredev->rdma_net); diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index cbabca167a078..dde272586e80b 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -30,9 +30,9 @@ static dev_t ipvtap_major; static struct cdev ipvtap_cdev; -static const void *ipvtap_net_namespace(struct device *d) +static const void *ipvtap_net_namespace(const struct device *d) { - struct net_device *dev = to_net_dev(d->parent); + const struct net_device *dev = to_net_dev(d->parent); return dev_net(dev); } diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index d1f435788e902..031344239f271 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -35,9 +35,9 @@ struct macvtap_dev { */ static dev_t macvtap_major; -static const void *macvtap_net_namespace(struct device *d) +static const void *macvtap_net_namespace(const struct device *d) { - struct net_device *dev = to_net_dev(d->parent); + const struct net_device *dev = to_net_dev(d->parent); return dev_net(dev); } diff --git a/include/linux/device/class.h b/include/linux/device/class.h index e61ec55020197..20103e0b03c34 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -68,9 +68,9 @@ struct class { int (*shutdown_pre)(struct device *dev); const struct kobj_ns_type_operations *ns_type; - const void *(*namespace)(struct device *dev); + const void *(*namespace)(const struct device *dev); - void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid); + void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid); const struct dev_pm_ops *pm; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 8409d41405dfe..a8c5a7cd9701d 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1910,16 +1910,16 @@ static void netdev_release(struct device *d) netdev_freemem(dev); } -static const void *net_namespace(struct device *d) +static const void *net_namespace(const struct device *d) { - struct net_device *dev = to_net_dev(d); + const struct net_device *dev = to_net_dev(d); return dev_net(dev); } -static void net_get_ownership(struct device *d, kuid_t *uid, kgid_t *gid) +static void net_get_ownership(const struct device *d, kuid_t *uid, kgid_t *gid) { - struct net_device *dev = to_net_dev(d); + const struct net_device *dev = to_net_dev(d); const struct net *net = dev_net(dev); net_ns_get_ownership(net, uid, gid); diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 0c3f05c9be27a..cdb638647e0b6 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -148,7 +148,7 @@ static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, wiphy_suspend, wiphy_resume); #define WIPHY_PM_OPS NULL #endif -static const void *wiphy_namespace(struct device *d) +static const void *wiphy_namespace(const struct device *d) { struct wiphy *wiphy = container_of(d, struct wiphy, dev); -- GitLab From 5d0557c75b2f2c7a868742d21a3ad94813ca97f4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 4 Nov 2022 14:18:03 +0200 Subject: [PATCH 0443/1480] perf intel-pt: Start turning intel-pt-pkt-decoder-test.c into a suite of intel-pt subtests In preparation for adding more Intel PT testing, rename intel-pt-pkt-decoder-test.c to intel-pt-test.c. Subtests will later be added to intel-pt-test.c. Signed-off-by: Adrian Hunter Acked-by: Namhyung Kim Cc: Ian Rogers Cc: Jiri Olsa Link: https://lore.kernel.org/r/20221104121805.5264-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/Build | 2 +- .../x86/tests/{intel-pt-pkt-decoder-test.c => intel-pt-test.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tools/perf/arch/x86/tests/{intel-pt-pkt-decoder-test.c => intel-pt-test.c} (100%) diff --git a/tools/perf/arch/x86/tests/Build b/tools/perf/arch/x86/tests/Build index 70b5bcbc15df7..6f4e8636c3bf7 100644 --- a/tools/perf/arch/x86/tests/Build +++ b/tools/perf/arch/x86/tests/Build @@ -3,5 +3,5 @@ perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o perf-y += arch-tests.o perf-y += sample-parsing.o -perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-pkt-decoder-test.o +perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-test.o perf-$(CONFIG_X86_64) += bp-modify.o diff --git a/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c b/tools/perf/arch/x86/tests/intel-pt-test.c similarity index 100% rename from tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c rename to tools/perf/arch/x86/tests/intel-pt-test.c -- GitLab From 828143f8da2856014df3102f63f7e4e4dc2d1c22 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 4 Nov 2022 14:18:04 +0200 Subject: [PATCH 0444/1480] perf intel-pt: Redefine test_suite to allow for adding more subtests In preparation for adding more Intel PT testing, redefine the test_suite to allow for adding more subtests. Signed-off-by: Adrian Hunter Acked-by: Namhyung Kim Cc: Ian Rogers Cc: Jiri Olsa Link: https://lore.kernel.org/r/20221104121805.5264-3-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/arch-tests.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 04018b8aa85b9..8d5e4a0831d54 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -5,7 +5,17 @@ #ifdef HAVE_AUXTRACE_SUPPORT DEFINE_SUITE("x86 instruction decoder - new instructions", insn_x86); -DEFINE_SUITE("Intel PT packet decoder", intel_pt_pkt_decoder); + +static struct test_case intel_pt_tests[] = { + TEST_CASE("Intel PT packet decoder", intel_pt_pkt_decoder), + { .name = NULL, } +}; + +struct test_suite suite__intel_pt = { + .desc = "Intel PT packet decoder", + .test_cases = intel_pt_tests, +}; + #endif #if defined(__x86_64__) DEFINE_SUITE("x86 bp modify", bp_modify); @@ -18,7 +28,7 @@ struct test_suite *arch_tests[] = { #endif #ifdef HAVE_AUXTRACE_SUPPORT &suite__insn_x86, - &suite__intel_pt_pkt_decoder, + &suite__intel_pt, #endif #if defined(__x86_64__) &suite__bp_modify, -- GitLab From 44a037f54b97e4215a282d39d0f7f28c588f185c Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 4 Nov 2022 14:18:05 +0200 Subject: [PATCH 0445/1480] perf intel-pt: Add hybrid CPU compatibility test The kernel driver assumes hybrid CPUs will have Intel PT capabilities that are compatible with the boot CPU. Add a test to check that is the case. Signed-off-by: Adrian Hunter Acked-by: Namhyung Kim Cc: Ian Rogers Cc: Jiri Olsa Link: https://lore.kernel.org/r/20221104121805.5264-4-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/include/arch-tests.h | 1 + tools/perf/arch/x86/tests/arch-tests.c | 3 +- tools/perf/arch/x86/tests/intel-pt-test.c | 154 ++++++++++++++++++++++ 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index 6a1a1b3c08275..902e9ea9b99ed 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -8,6 +8,7 @@ struct test_suite; int test__rdpmc(struct test_suite *test, int subtest); int test__insn_x86(struct test_suite *test, int subtest); int test__intel_pt_pkt_decoder(struct test_suite *test, int subtest); +int test__intel_pt_hybrid_compat(struct test_suite *test, int subtest); int test__bp_modify(struct test_suite *test, int subtest); int test__x86_sample_parsing(struct test_suite *test, int subtest); diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 8d5e4a0831d54..aae6ea0fe52b7 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -8,11 +8,12 @@ DEFINE_SUITE("x86 instruction decoder - new instructions", insn_x86); static struct test_case intel_pt_tests[] = { TEST_CASE("Intel PT packet decoder", intel_pt_pkt_decoder), + TEST_CASE("Intel PT hybrid CPU compatibility", intel_pt_hybrid_compat), { .name = NULL, } }; struct test_suite suite__intel_pt = { - .desc = "Intel PT packet decoder", + .desc = "Intel PT", .test_cases = intel_pt_tests, }; diff --git a/tools/perf/arch/x86/tests/intel-pt-test.c b/tools/perf/arch/x86/tests/intel-pt-test.c index 42237656f4539..70b7f79396b18 100644 --- a/tools/perf/arch/x86/tests/intel-pt-test.c +++ b/tools/perf/arch/x86/tests/intel-pt-test.c @@ -1,12 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include #include +#include +#include #include "intel-pt-decoder/intel-pt-pkt-decoder.h" #include "debug.h" #include "tests/tests.h" #include "arch-tests.h" +#include "cpumap.h" /** * struct test_data - Test data. @@ -313,3 +318,152 @@ int test__intel_pt_pkt_decoder(struct test_suite *test __maybe_unused, int subte return TEST_OK; } + +static int setaffinity(int cpu) +{ + cpu_set_t cpu_set; + + CPU_ZERO(&cpu_set); + CPU_SET(cpu, &cpu_set); + if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set)) { + pr_debug("sched_setaffinity() failed for CPU %d\n", cpu); + return -1; + } + return 0; +} + +#define INTEL_PT_ADDR_FILT_CNT_MASK GENMASK(2, 0) +#define INTEL_PT_SUBLEAF_CNT 2 +#define CPUID_REG_CNT 4 + +struct cpuid_result { + union { + struct { + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + }; + unsigned int reg[CPUID_REG_CNT]; + }; +}; + +struct pt_caps { + struct cpuid_result subleaf[INTEL_PT_SUBLEAF_CNT]; +}; + +static int get_pt_caps(int cpu, struct pt_caps *caps) +{ + struct cpuid_result r; + int i; + + if (setaffinity(cpu)) + return -1; + + memset(caps, 0, sizeof(*caps)); + + for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) { + __get_cpuid_count(20, i, &r.eax, &r.ebx, &r.ecx, &r.edx); + pr_debug("CPU %d CPUID leaf 20 subleaf %d\n", cpu, i); + pr_debug("eax = 0x%08x\n", r.eax); + pr_debug("ebx = 0x%08x\n", r.ebx); + pr_debug("ecx = 0x%08x\n", r.ecx); + pr_debug("edx = 0x%08x\n", r.edx); + caps->subleaf[i] = r; + } + + return 0; +} + +static bool is_hydrid(void) +{ + unsigned int eax, ebx, ecx, edx = 0; + bool result; + + __get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx); + result = edx & BIT(15); + pr_debug("Is %shybrid : CPUID leaf 7 subleaf 0 edx %#x (bit-15 indicates hybrid)\n", + result ? "" : "not ", edx); + return result; +} + +static int compare_caps(int cpu, struct pt_caps *caps, struct pt_caps *caps0) +{ + struct pt_caps mask = { /* Mask of bits to check*/ + .subleaf = { + [0] = { + .ebx = GENMASK(8, 0), + .ecx = GENMASK(3, 0), + }, + [1] = { + .eax = GENMASK(31, 16), + .ebx = GENMASK(31, 0), + } + } + }; + unsigned int m, reg, reg0; + int ret = 0; + int i, j; + + for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) { + for (j = 0; j < CPUID_REG_CNT; j++) { + m = mask.subleaf[i].reg[j]; + reg = m & caps->subleaf[i].reg[j]; + reg0 = m & caps0->subleaf[i].reg[j]; + if ((reg & reg0) != reg0) { + pr_debug("CPU %d subleaf %d reg %d FAIL %#x vs %#x\n", + cpu, i, j, reg, reg0); + ret = -1; + } + } + } + + m = INTEL_PT_ADDR_FILT_CNT_MASK; + reg = m & caps->subleaf[1].eax; + reg0 = m & caps0->subleaf[1].eax; + if (reg < reg0) { + pr_debug("CPU %d subleaf 1 reg 0 FAIL address filter count %#x vs %#x\n", + cpu, reg, reg0); + ret = -1; + } + + if (!ret) + pr_debug("CPU %d OK\n", cpu); + + return ret; +} + +int test__intel_pt_hybrid_compat(struct test_suite *test, int subtest) +{ + int max_cpu = cpu__max_cpu().cpu; + struct pt_caps last_caps; + struct pt_caps caps0; + int ret = TEST_OK; + int cpu; + + if (!is_hydrid()) { + test->test_cases[subtest].skip_reason = "not hybrid"; + return TEST_SKIP; + } + + if (get_pt_caps(0, &caps0)) + return TEST_FAIL; + + for (cpu = 1, last_caps = caps0; cpu < max_cpu; cpu++) { + struct pt_caps caps; + + if (get_pt_caps(cpu, &caps)) { + pr_debug("CPU %d not found\n", cpu); + continue; + } + if (!memcmp(&caps, &last_caps, sizeof(caps))) { + pr_debug("CPU %d same caps as previous CPU\n", cpu); + continue; + } + if (compare_caps(cpu, &caps, &caps0)) + ret = TEST_FAIL; + last_caps = caps; + } + + return ret; +} -- GitLab From a39a1466dae5e3ed0dd7c03334a60894e4d1f334 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Thu, 13 Oct 2022 14:46:36 -0700 Subject: [PATCH 0446/1480] MAINTAINERS: git://github -> https://github.com for awilliam MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Github deprecated the git:// links about a year ago, so let's move to the https:// URLs instead. Reported-by: Conor Dooley Link: https://github.blog/2021-09-01-improving-git-protocol-security-github/ Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Link: https://lore.kernel.org/r/20221013214636.30721-1-palmer@rivosinc.com Signed-off-by: Alex Williamson --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 046ff06ff97fa..daa6a7a755ece 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21539,7 +21539,7 @@ M: Alex Williamson R: Cornelia Huck L: kvm@vger.kernel.org S: Maintained -T: git git://github.com/awilliam/linux-vfio.git +T: git https://github.com/awilliam/linux-vfio.git F: Documentation/ABI/testing/sysfs-devices-vfio-dev F: Documentation/driver-api/vfio.rst F: drivers/vfio/ -- GitLab From cd48ebc5c4f2e94830b238f035ebf04f1c3a4433 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Thu, 22 Sep 2022 20:35:07 +0800 Subject: [PATCH 0447/1480] vfio/mlx5: Switch to use module_pci_driver() macro Since pci provides the helper macro module_pci_driver(), we may replace the module_init/exit with it. Signed-off-by: Shang XiaoJing Reviewed-by: Yishai Hadas Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/20220922123507.11222-1-shangxiaojing@huawei.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/main.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index fd6ccb8454a24..457138b92f134 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -676,18 +676,7 @@ static struct pci_driver mlx5vf_pci_driver = { .driver_managed_dma = true, }; -static void __exit mlx5vf_pci_cleanup(void) -{ - pci_unregister_driver(&mlx5vf_pci_driver); -} - -static int __init mlx5vf_pci_init(void) -{ - return pci_register_driver(&mlx5vf_pci_driver); -} - -module_init(mlx5vf_pci_init); -module_exit(mlx5vf_pci_cleanup); +module_pci_driver(mlx5vf_pci_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Max Gurtovoy "); -- GitLab From e67e070632a665c932d534b8b800477bb3111449 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Tue, 18 Oct 2022 12:28:25 -0300 Subject: [PATCH 0448/1480] vfio: platform: Do not pass return buffer to ACPI _RST method The ACPI _RST method has no return value, there's no need to pass a return buffer to acpi_evaluate_object(). Fixes: d30daa33ec1d ("vfio: platform: call _RST method when using ACPI") Signed-off-by: Rafael Mendonca Reviewed-by: Eric Auger Link: https://lore.kernel.org/r/20221018152825.891032-1-rafaelmendsr@gmail.com Signed-off-by: Alex Williamson --- drivers/vfio/platform/vfio_platform_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 55dc4f43c31e3..1a0a238ffa354 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -72,12 +72,11 @@ static int vfio_platform_acpi_call_reset(struct vfio_platform_device *vdev, const char **extra_dbg) { #ifdef CONFIG_ACPI - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct device *dev = vdev->device; acpi_handle handle = ACPI_HANDLE(dev); acpi_status acpi_ret; - acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, &buffer); + acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, NULL); if (ACPI_FAILURE(acpi_ret)) { if (extra_dbg) *extra_dbg = acpi_format_exception(acpi_ret); -- GitLab From ea00d4ededcd8639f9e814513426cfeccdd3aaf0 Mon Sep 17 00:00:00 2001 From: Joao Martins Date: Tue, 25 Oct 2022 20:31:13 +0100 Subject: [PATCH 0449/1480] vfio/iova_bitmap: Explicitly include linux/slab.h kzalloc/kzfree are used so include `slab.h`. While it happens to work without it, due to commit 8b9f3ac5b01d ("fs: introduce alloc_inode_sb() to allocate filesystems specific inode") which indirectly includes via: . ./include/linux/mm.h .. ./include/linux/huge_mm.h ... ./include/linux/fs.h .... ./include/linux/slab.h Make it explicit should any of its indirect dependencies be dropped/changed for entirely different reasons as it was the cause prior to commit above recently (i.e. <= v5.18). Signed-off-by: Joao Martins Link: https://lore.kernel.org/r/20221025193114.58695-2-joao.m.martins@oracle.com Signed-off-by: Alex Williamson --- drivers/vfio/iova_bitmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c index 6631e8befe1b2..56816ba1be9b1 100644 --- a/drivers/vfio/iova_bitmap.c +++ b/drivers/vfio/iova_bitmap.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #define BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE) -- GitLab From f38044e5ef58ad0346fdabd7027ea5c1e1a3b624 Mon Sep 17 00:00:00 2001 From: Joao Martins Date: Tue, 25 Oct 2022 20:31:14 +0100 Subject: [PATCH 0450/1480] vfio/iova_bitmap: Fix PAGE_SIZE unaligned bitmaps iova_bitmap_set() doesn't consider the end of the page boundary when the first bitmap page offset isn't zero, and wrongly changes the consecutive page right after. Consequently this leads to missing dirty pages from reported by the device as seen from the VMM. The current logic iterates over a given number of base pages and clamps it to the remaining indexes to iterate in the last page. Instead of having to consider extra pages to pin (e.g. first and extra pages), just handle the first page as its own range and let the rest of the bitmap be handled as if it was base page aligned. This is done by changing iova_bitmap_mapped_remaining() to return PAGE_SIZE - pgoff (on the first bitmap page), and leads to pgoff being set to 0 on following iterations. Fixes: 58ccf0190d19 ("vfio: Add an IOVA bitmap support") Reported-by: Avihai Horon Tested-by: Avihai Horon Signed-off-by: Joao Martins Link: https://lore.kernel.org/r/20221025193114.58695-3-joao.m.martins@oracle.com Signed-off-by: Alex Williamson --- drivers/vfio/iova_bitmap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c index 56816ba1be9b1..de6d6ea5c4967 100644 --- a/drivers/vfio/iova_bitmap.c +++ b/drivers/vfio/iova_bitmap.c @@ -296,11 +296,15 @@ void iova_bitmap_free(struct iova_bitmap *bitmap) */ static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap) { - unsigned long remaining; + unsigned long remaining, bytes; + + /* Cap to one page in the first iteration, if PAGE_SIZE unaligned. */ + bytes = !bitmap->mapped.pgoff ? bitmap->mapped.npages << PAGE_SHIFT : + PAGE_SIZE - bitmap->mapped.pgoff; remaining = bitmap->mapped_total_index - bitmap->mapped_base_index; remaining = min_t(unsigned long, remaining, - (bitmap->mapped.npages << PAGE_SHIFT) / sizeof(*bitmap->bitmap)); + bytes / sizeof(*bitmap->bitmap)); return remaining; } -- GitLab From be7e8b917ead54754cc14b6c03769c8738a3f3f3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Nov 2022 15:48:43 +0100 Subject: [PATCH 0451/1480] blkdev: make struct block_device_operations.devnode() take a const * The devnode() callback in struct block_device_operations should not be modifying the device that is passed into it, so mark it as a const * and propagate the function signature changes out into the one subsystem that actually uses this callback. Acked-by: Jens Axboe Link: https://lore.kernel.org/r/20221109144843.679668-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/block/pktcdvd.c | 2 +- include/linux/blkdev.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 4cea3b08087ed..8dc15be959625 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2632,7 +2632,7 @@ static unsigned int pkt_check_events(struct gendisk *disk, return attached_disk->fops->check_events(attached_disk, clearing); } -static char *pkt_devnode(struct gendisk *disk, umode_t *mode) +static char *pkt_devnode(const struct gendisk *disk, umode_t *mode) { return kasprintf(GFP_KERNEL, "pktcdvd/%s", disk->disk_name); } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 50e358a19d986..2a455793462b2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1413,7 +1413,7 @@ struct block_device_operations { void (*swap_slot_free_notify) (struct block_device *, unsigned long); int (*report_zones)(struct gendisk *, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); - char *(*devnode)(struct gendisk *disk, umode_t *mode); + char *(*devnode)(const struct gendisk *disk, umode_t *mode); /* returns the length of the identifier or a negative errno: */ int (*get_unique_id)(struct gendisk *disk, u8 id[16], enum blk_unique_id id_type); -- GitLab From 927bdd1e65bd14ae035d9c625df2f4ccd51e8a83 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Nov 2022 15:07:10 +0100 Subject: [PATCH 0452/1480] driver core: remove devm_device_remove_groups() There is no in-kernel user of this function, so it is not needed anymore and can be removed. Cc: Dmitry Torokhov Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221109140711.105222-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 17 ----------------- include/linux/device.h | 2 -- 2 files changed, 19 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index f07b1c349f791..5fd99f2df692c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2693,23 +2693,6 @@ int devm_device_add_groups(struct device *dev, } EXPORT_SYMBOL_GPL(devm_device_add_groups); -/** - * devm_device_remove_groups - remove a list of managed groups - * - * @dev: The device for the groups to be removed from - * @groups: NULL terminated list of groups to be removed - * - * If groups is not NULL, remove the specified groups from the device. - */ -void devm_device_remove_groups(struct device *dev, - const struct attribute_group **groups) -{ - WARN_ON(devres_release(dev, devm_attr_groups_remove, - devm_attr_group_match, - /* cast away const */ (void *)groups)); -} -EXPORT_SYMBOL_GPL(devm_device_remove_groups); - static int device_add_attrs(struct device *dev) { struct class *class = dev->class; diff --git a/include/linux/device.h b/include/linux/device.h index 023ea50b19162..4efc607c008cd 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1062,8 +1062,6 @@ static inline void device_remove_group(struct device *dev, int __must_check devm_device_add_groups(struct device *dev, const struct attribute_group **groups); -void devm_device_remove_groups(struct device *dev, - const struct attribute_group **groups); int __must_check devm_device_add_group(struct device *dev, const struct attribute_group *grp); void devm_device_remove_group(struct device *dev, -- GitLab From 0f0605d550ed986279030d452c7ed10df34da449 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Nov 2022 15:07:11 +0100 Subject: [PATCH 0453/1480] driver core: remove devm_device_remove_group() There is no in-kernel user of this function, so it is not needed anymore and can be removed. Cc: Dmitry Torokhov Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221109140711.105222-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 22 ---------------------- include/linux/device.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 5fd99f2df692c..af721e6c0253e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2585,11 +2585,6 @@ union device_attr_group_devres { const struct attribute_group **groups; }; -static int devm_attr_group_match(struct device *dev, void *res, void *data) -{ - return ((union device_attr_group_devres *)res)->group == data; -} - static void devm_attr_group_remove(struct device *dev, void *res) { union device_attr_group_devres *devres = res; @@ -2640,23 +2635,6 @@ int devm_device_add_group(struct device *dev, const struct attribute_group *grp) } EXPORT_SYMBOL_GPL(devm_device_add_group); -/** - * devm_device_remove_group: remove a managed group from a device - * @dev: device to remove the group from - * @grp: group to remove - * - * This function removes a group of attributes from a device. The attributes - * previously have to have been created for this group, otherwise it will fail. - */ -void devm_device_remove_group(struct device *dev, - const struct attribute_group *grp) -{ - WARN_ON(devres_release(dev, devm_attr_group_remove, - devm_attr_group_match, - /* cast away const */ (void *)grp)); -} -EXPORT_SYMBOL_GPL(devm_device_remove_group); - /** * devm_device_add_groups - create a bunch of managed attribute groups * @dev: The device to create the group for diff --git a/include/linux/device.h b/include/linux/device.h index 4efc607c008cd..84ae52de6746a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1064,8 +1064,6 @@ int __must_check devm_device_add_groups(struct device *dev, const struct attribute_group **groups); int __must_check devm_device_add_group(struct device *dev, const struct attribute_group *grp); -void devm_device_remove_group(struct device *dev, - const struct attribute_group *grp); /* * Platform "fixup" functions - allow the platform to have their say -- GitLab From 189a87f8ef8ceed16b2a230dc0ce65117068ac30 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 30 Oct 2022 10:22:55 +0100 Subject: [PATCH 0454/1480] driver core: mark driver_allows_async_probing static driver_allows_async_probing is only used in drivers/base/dd.c, so mark it static and remove the declaration in drivers/base/base.h. Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20221030092255.872280-1-hch@lst.de Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 1 - drivers/base/dd.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index b902d1ecc247f..7d4803c03d3e6 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -146,7 +146,6 @@ static inline int driver_match_device(struct device_driver *drv, { return drv->bus->match ? drv->bus->match(dev, drv) : 1; } -extern bool driver_allows_async_probing(struct device_driver *drv); extern int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 3dda62503102f..4001e22617ab0 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -843,7 +843,7 @@ static int __init save_async_options(char *buf) } __setup("driver_async_probe=", save_async_options); -bool driver_allows_async_probing(struct device_driver *drv) +static bool driver_allows_async_probing(struct device_driver *drv) { switch (drv->probe_type) { case PROBE_PREFER_ASYNCHRONOUS: -- GitLab From 3da72e18371c41a6f6f96b594854b178168c7757 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 26 Oct 2022 20:59:54 +0200 Subject: [PATCH 0455/1480] cacheinfo: Decrement refcount in cache_setup_of_node() Refcounts to DT nodes are only incremented in the function and never decremented. Decrease the refcounts when necessary. Signed-off-by: Pierre Gondois Reviewed-by: Sudeep Holla Link: https://lore.kernel.org/r/20221026185954.991547-1-pierre.gondois@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 4b5cd08c5a657..04317cde800cb 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -196,7 +196,7 @@ static void cache_of_set_props(struct cacheinfo *this_leaf, static int cache_setup_of_node(unsigned int cpu) { - struct device_node *np; + struct device_node *np, *prev; struct cacheinfo *this_leaf; unsigned int index = 0; @@ -206,19 +206,24 @@ static int cache_setup_of_node(unsigned int cpu) return -ENOENT; } + prev = np; + while (index < cache_leaves(cpu)) { this_leaf = per_cpu_cacheinfo_idx(cpu, index); - if (this_leaf->level != 1) + if (this_leaf->level != 1) { np = of_find_next_cache_node(np); - else - np = of_node_get(np);/* cpu node itself */ - if (!np) - break; + of_node_put(prev); + prev = np; + if (!np) + break; + } cache_of_set_props(this_leaf, np); this_leaf->fw_token = np; index++; } + of_node_put(np); + if (index != cache_leaves(cpu)) /* not all OF nodes populated */ return -ENOENT; -- GitLab From 730600223b64918324ab322ab174361bd41073c0 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 1 Nov 2022 22:14:17 +0100 Subject: [PATCH 0456/1480] driver core: Use kstrtobool() instead of strtobool() strtobool() is the same as kstrtobool(). However, the latter is more used within the kernel. In order to remove strtobool() and slightly simplify kstrtox.h, switch to the other function name. While at it, include the corresponding header file () Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/02ba683a5c0716638ad8ca11e8b0fdca97c4f294.1667336095.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index af721e6c0253e..ab01828fe6c1f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1628,7 +1629,7 @@ early_param("fw_devlink", fw_devlink_setup); static bool fw_devlink_strict; static int __init fw_devlink_strict_setup(char *arg) { - return strtobool(arg, &fw_devlink_strict); + return kstrtobool(arg, &fw_devlink_strict); } early_param("fw_devlink.strict", fw_devlink_strict_setup); @@ -2280,7 +2281,7 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, { struct dev_ext_attribute *ea = to_ext_attr(attr); - if (strtobool(buf, ea->var) < 0) + if (kstrtobool(buf, ea->var) < 0) return -EINVAL; return size; @@ -2534,7 +2535,7 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr, bool val; int ret; - ret = strtobool(buf, &val); + ret = kstrtobool(buf, &val); if (ret < 0) return ret; -- GitLab From 27c0d217340e47ec995557f61423ef415afba987 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 20 Sep 2022 17:14:13 -0700 Subject: [PATCH 0457/1480] driver core: Fix bus_type.match() error handling in __driver_attach() When a driver registers with a bus, it will attempt to match with every device on the bus through the __driver_attach() function. Currently, if the bus_type.match() function encounters an error that is not -EPROBE_DEFER, __driver_attach() will return a negative error code, which causes the driver registration logic to stop trying to match with the remaining devices on the bus. This behavior is not correct; a failure while matching a driver to a device does not mean that the driver won't be able to match and bind with other devices on the bus. Update the logic in __driver_attach() to reflect this. Fixes: 656b8035b0ee ("ARM: 8524/1: driver cohandle -EPROBE_DEFER from bus_type.match()") Cc: stable@vger.kernel.org Cc: Saravana Kannan Signed-off-by: Isaac J. Manjarres Link: https://lore.kernel.org/r/20220921001414.4046492-1-isaacmanjarres@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 4001e22617ab0..e9b2f9c25efe4 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1162,7 +1162,11 @@ static int __driver_attach(struct device *dev, void *data) return 0; } else if (ret < 0) { dev_dbg(dev, "Bus failed to match device: %d\n", ret); - return ret; + /* + * Driver could not match with device, but may match with + * another device on the bus. + */ + return 0; } /* ret > 0 means positive match */ if (driver_allows_async_probing(drv)) { -- GitLab From 02c39bbb36bab698b29f066a28c3e342d1136e53 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 6 Oct 2022 07:27:17 +0200 Subject: [PATCH 0458/1480] virt: fsl_hypervisor: Replace NO_IRQ by 0 NO_IRQ is used to check the return of irq_of_parse_and_map(). On some architecture NO_IRQ is 0, on other architectures it is -1. irq_of_parse_and_map() returns 0 on error, independent of NO_IRQ. So use 0 instead of using NO_IRQ. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/20dd37b96bac0a72caef28e7462b32c93487a516.1665033909.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/virt/fsl_hypervisor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index 07035249a5e1e..f8b4389d60d9f 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -839,7 +839,7 @@ static int __init fsl_hypervisor_init(void) handle = of_get_property(np, "interrupts", NULL); irq = irq_of_parse_and_map(np, 0); - if (!handle || (irq == NO_IRQ)) { + if (!handle || !irq) { pr_err("fsl-hv: no 'interrupts' property in %pOF node\n", np); continue; -- GitLab From 2d2879e1834d02852347d9dc910fffd5d22ac337 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 10 Nov 2022 15:37:54 +0530 Subject: [PATCH 0459/1480] dt-bindings: spmi: Add qcom,bus-id For PMIC arbiter version 7 and beyond we need to define if we are using primary or secondary bus, so add a new property of qcom,bus-id Signed-off-by: Vinod Koul Acked-by: Rob Herring Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221110100755.4032505-2-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml index fee4f0eb46652..f983b4af6db93 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml @@ -85,6 +85,14 @@ properties: description: > which of the PMIC Arb provided channels to use for accesses + qcom,bus-id: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 1 + description: > + SPMI bus instance. only applicable to PMIC arbiter version 7 and beyond. + Supported values, 0 = primary bus, 1 = secondary bus + required: - compatible - reg-names @@ -113,5 +121,7 @@ examples: interrupt-controller; #interrupt-cells = <4>; + + qcom,bus-id = <0>; }; -- GitLab From 231601cd22bd60e332dfa9ead22f871e93ad9821 Mon Sep 17 00:00:00 2001 From: David Collins Date: Thu, 10 Nov 2022 15:37:55 +0530 Subject: [PATCH 0460/1480] spmi: pmic-arb: Add support for PMIC v7 PMIC v7 has different offset values and seqeunces, so add support for this new version of PMIC Signed-off-by: David Collins Signed-off-by: Vinod Koul Tested-by: Dmitry Baryshkov # SM8450 HDK Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221110100755.4032505-3-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/spmi/spmi-pmic-arb.c | 242 ++++++++++++++++++++++++++++++++--- 1 file changed, 221 insertions(+), 21 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 2cf3203b2397e..8b6a42ab816fb 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -22,8 +22,14 @@ #define PMIC_ARB_VERSION_V2_MIN 0x20010000 #define PMIC_ARB_VERSION_V3_MIN 0x30000000 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 +#define PMIC_ARB_VERSION_V7_MIN 0x70000000 #define PMIC_ARB_INT_EN 0x0004 +#define PMIC_ARB_FEATURES 0x0004 +#define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) + +#define PMIC_ARB_FEATURES1 0x0008 + /* PMIC Arbiter channel registers offsets */ #define PMIC_ARB_CMD 0x00 #define PMIC_ARB_CONFIG 0x04 @@ -48,7 +54,6 @@ #define INVALID_EE 0xFF /* Ownership Table */ -#define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N))) #define SPMI_OWNERSHIP_PERIPH2OWNER(X) ((X) & 0x7) /* Channel Status fields */ @@ -91,6 +96,7 @@ enum pmic_arb_channel { /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 +#define PMIC_ARB_MAX_PERIPHS_V7 1024 #define PMIC_ARB_TIMEOUT_US 1000 #define PMIC_ARB_MAX_TRANS_BYTES (8) @@ -104,12 +110,12 @@ enum pmic_arb_channel { ((((slave_id) & 0xF) << 28) | \ (((periph_id) & 0xFF) << 20) | \ (((irq_id) & 0x7) << 16) | \ - (((apid) & 0x1FF) << 0)) + (((apid) & 0x3FF) << 0)) #define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF) #define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF) #define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7) -#define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x1FF) +#define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x3FF) struct pmic_arb_ver_ops; @@ -130,13 +136,21 @@ struct apid_data { * @channel: execution environment channel to use for accesses. * @irq: PMIC ARB interrupt. * @ee: the current Execution Environment + * @bus_instance: on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus * @min_apid: minimum APID (used for bounding IRQ search) * @max_apid: maximum APID + * @base_apid: on v7: minimum APID associated with the particular SPMI + * bus instance + * @apid_count: on v5 and v7: number of APIDs associated with the + * particular SPMI bus instance * @mapping_table: in-memory copy of PPID -> APID mapping table. * @domain: irq domain object for PMIC IRQ domain * @spmic: SPMI controller object * @ver_ops: version dependent operations. - * @ppid_to_apid in-memory copy of PPID -> APID mapping table. + * @ppid_to_apid: in-memory copy of PPID -> APID mapping table. + * @last_apid: Highest value APID in use + * @apid_data: Table of data for all APIDs + * @max_periphs: Number of elements in apid_data[] */ struct spmi_pmic_arb { void __iomem *rd_base; @@ -149,8 +163,11 @@ struct spmi_pmic_arb { u8 channel; int irq; u8 ee; + u32 bus_instance; u16 min_apid; u16 max_apid; + u16 base_apid; + int apid_count; u32 *mapping_table; DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS); struct irq_domain *domain; @@ -158,7 +175,8 @@ struct spmi_pmic_arb { const struct pmic_arb_ver_ops *ver_ops; u16 *ppid_to_apid; u16 last_apid; - struct apid_data apid_data[PMIC_ARB_MAX_PERIPHS]; + struct apid_data *apid_data; + int max_periphs; }; /** @@ -180,6 +198,7 @@ struct spmi_pmic_arb { * @irq_clear: on v1 address of PMIC_ARB_SPMI_PIC_IRQ_CLEARn * on v2 address of SPMI_PIC_IRQ_CLEARn. * @apid_map_offset: offset of PMIC_ARB_REG_CHNLn + * @apid_owner: on v2 and later address of SPMI_PERIPHn_2OWNER_TABLE_REG */ struct pmic_arb_ver_ops { const char *ver_str; @@ -196,6 +215,7 @@ struct pmic_arb_ver_ops { void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n); void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n); u32 (*apid_map_offset)(u16 n); + void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n); }; static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb, @@ -627,6 +647,11 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) struct irq_chip *chip = irq_desc_get_chip(desc); int first = pmic_arb->min_apid; int last = pmic_arb->max_apid; + /* + * acc_offset will be non-zero for the secondary SPMI bus instance on + * v7 controllers. + */ + int acc_offset = pmic_arb->base_apid >> 5; u8 ee = pmic_arb->ee; u32 status, enable, handled = 0; int i, id, apid; @@ -637,8 +662,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) chained_irq_enter(chip, desc); for (i = first >> 5; i <= last >> 5; ++i) { - status = readl_relaxed( - ver_ops->owner_acc_status(pmic_arb, ee, i)); + status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset)); if (status) acc_valid = true; @@ -983,8 +1007,8 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid) if (offset >= pmic_arb->core_size) break; - regval = readl_relaxed(pmic_arb->cnfg + - SPMI_OWNERSHIP_TABLE_REG(apid)); + regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, + apid)); apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); apidd->write_ee = apidd->irq_ee; @@ -1020,21 +1044,30 @@ static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid) static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) { - struct apid_data *apidd = pmic_arb->apid_data; + struct apid_data *apidd; struct apid_data *prev_apidd; - u16 i, apid, ppid; + u16 i, apid, ppid, apid_max; bool valid, is_irq_ee; u32 regval, offset; /* * In order to allow multiple EEs to write to a single PPID in arbiter - * version 5, there is more than one APID mapped to each PPID. + * version 5 and 7, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID * which has the IRQ owner bit set for a given PPID will receive * interrupts from the PPID. + * + * In arbiter version 7, the APID numbering space is divided between + * the primary bus (0) and secondary bus (1) such that: + * APID = 0 to N-1 are assigned to the primary bus + * APID = N to N+M-1 are assigned to the secondary bus + * where N = number of APIDs supported by the primary bus and + * M = number of APIDs supported by the secondary bus */ - for (i = 0; ; i++, apidd++) { + apidd = &pmic_arb->apid_data[pmic_arb->base_apid]; + apid_max = pmic_arb->base_apid + pmic_arb->apid_count; + for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(i); if (offset >= pmic_arb->core_size) break; @@ -1045,8 +1078,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) ppid = (regval >> 8) & PMIC_ARB_PPID_MASK; is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval); - regval = readl_relaxed(pmic_arb->cnfg + - SPMI_OWNERSHIP_TABLE_REG(i)); + regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, + i)); apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE; @@ -1145,6 +1178,40 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, return offset; } +/* + * v7 offset per ee and per apid for observer channels and per apid for + * read/write channels. + */ +static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) +{ + u16 apid; + int rc; + u32 offset = 0; + u16 ppid = (sid << 8) | (addr >> 8); + + rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid); + if (rc < 0) + return rc; + + apid = rc; + switch (ch_type) { + case PMIC_ARB_CHANNEL_OBS: + offset = 0x8000 * pmic_arb->ee + 0x20 * apid; + break; + case PMIC_ARB_CHANNEL_RW: + if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) { + dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", + sid, addr); + return -EPERM; + } + offset = 0x1000 * apid; + break; + } + + return offset; +} + static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) { return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); @@ -1179,6 +1246,12 @@ pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) return pmic_arb->intr + 0x10000 * m + 0x4 * n; } +static void __iomem * +pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +{ + return pmic_arb->intr + 0x1000 * m + 0x4 * n; +} + static void __iomem * pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n) { @@ -1197,6 +1270,12 @@ pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n) return pmic_arb->wr_base + 0x100 + 0x10000 * n; } +static void __iomem * +pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +{ + return pmic_arb->wr_base + 0x100 + 0x1000 * n; +} + static void __iomem * pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n) { @@ -1215,6 +1294,12 @@ pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n) return pmic_arb->wr_base + 0x104 + 0x10000 * n; } +static void __iomem * +pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +{ + return pmic_arb->wr_base + 0x104 + 0x1000 * n; +} + static void __iomem * pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n) { @@ -1233,6 +1318,12 @@ pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n) return pmic_arb->wr_base + 0x108 + 0x10000 * n; } +static void __iomem * +pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +{ + return pmic_arb->wr_base + 0x108 + 0x1000 * n; +} + static u32 pmic_arb_apid_map_offset_v2(u16 n) { return 0x800 + 0x4 * n; @@ -1243,6 +1334,28 @@ static u32 pmic_arb_apid_map_offset_v5(u16 n) return 0x900 + 0x4 * n; } +static u32 pmic_arb_apid_map_offset_v7(u16 n) +{ + return 0x2000 + 0x4 * n; +} + +static void __iomem * +pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n) +{ + return pmic_arb->cnfg + 0x700 + 0x4 * n; +} + +/* + * For arbiter version 7, APID ownership table registers have independent + * numbering space for each SPMI bus instance, so each is indexed starting from + * 0. + */ +static void __iomem * +pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +{ + return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid); +} + static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", .ppid_to_apid = pmic_arb_ppid_to_apid_v1, @@ -1254,6 +1367,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = { .irq_status = pmic_arb_irq_status_v1, .irq_clear = pmic_arb_irq_clear_v1, .apid_map_offset = pmic_arb_apid_map_offset_v2, + .apid_owner = pmic_arb_apid_owner_v2, }; static const struct pmic_arb_ver_ops pmic_arb_v2 = { @@ -1267,6 +1381,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = { .irq_status = pmic_arb_irq_status_v2, .irq_clear = pmic_arb_irq_clear_v2, .apid_map_offset = pmic_arb_apid_map_offset_v2, + .apid_owner = pmic_arb_apid_owner_v2, }; static const struct pmic_arb_ver_ops pmic_arb_v3 = { @@ -1280,6 +1395,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = { .irq_status = pmic_arb_irq_status_v2, .irq_clear = pmic_arb_irq_clear_v2, .apid_map_offset = pmic_arb_apid_map_offset_v2, + .apid_owner = pmic_arb_apid_owner_v2, }; static const struct pmic_arb_ver_ops pmic_arb_v5 = { @@ -1293,6 +1409,21 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { .irq_status = pmic_arb_irq_status_v5, .irq_clear = pmic_arb_irq_clear_v5, .apid_map_offset = pmic_arb_apid_map_offset_v5, + .apid_owner = pmic_arb_apid_owner_v2, +}; + +static const struct pmic_arb_ver_ops pmic_arb_v7 = { + .ver_str = "v7", + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, + .non_data_cmd = pmic_arb_non_data_cmd_v2, + .offset = pmic_arb_offset_v7, + .fmt_cmd = pmic_arb_fmt_cmd_v2, + .owner_acc_status = pmic_arb_owner_acc_status_v7, + .acc_enable = pmic_arb_acc_enable_v7, + .irq_status = pmic_arb_irq_status_v7, + .irq_clear = pmic_arb_irq_clear_v7, + .apid_map_offset = pmic_arb_apid_map_offset_v7, + .apid_owner = pmic_arb_apid_owner_v7, }; static const struct irq_domain_ops pmic_arb_irq_domain_ops = { @@ -1319,8 +1450,18 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb = spmi_controller_get_drvdata(ctrl); pmic_arb->spmic = ctrl; + /* + * Please don't replace this with devm_platform_ioremap_resource() or + * devm_ioremap_resource(). These both result in a call to + * devm_request_mem_region() which prevents multiple mappings of this + * register address range. SoCs with PMIC arbiter v7 may define two + * arbiter devices, for the two physical SPMI interfaces, which share + * some register address ranges (i.e. "core", "obsrvr", and "chnls"). + * Ensure that both devices probe successfully by calling devm_ioremap() + * which does not result in a devm_request_mem_region() call. + */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); - core = devm_ioremap_resource(&ctrl->dev, res); + core = devm_ioremap(&ctrl->dev, res->start, resource_size(res)); if (IS_ERR(core)) { err = PTR_ERR(core); goto err_put_ctrl; @@ -1349,12 +1490,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ver_ops = &pmic_arb_v2; else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) pmic_arb->ver_ops = &pmic_arb_v3; - else + else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) pmic_arb->ver_ops = &pmic_arb_v5; + else + pmic_arb->ver_ops = &pmic_arb_v7; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "obsrvr"); - pmic_arb->rd_base = devm_ioremap_resource(&ctrl->dev, res); + pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start, + resource_size(res)); if (IS_ERR(pmic_arb->rd_base)) { err = PTR_ERR(pmic_arb->rd_base); goto err_put_ctrl; @@ -1362,13 +1506,69 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "chnls"); - pmic_arb->wr_base = devm_ioremap_resource(&ctrl->dev, res); + pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start, + resource_size(res)); if (IS_ERR(pmic_arb->wr_base)) { err = PTR_ERR(pmic_arb->wr_base); goto err_put_ctrl; } } + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; + + if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) { + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; + /* Optional property for v7: */ + of_property_read_u32(pdev->dev.of_node, "qcom,bus-id", + &pmic_arb->bus_instance); + if (pmic_arb->bus_instance > 1) { + err = -EINVAL; + dev_err(&pdev->dev, "invalid bus instance (%u) specified\n", + pmic_arb->bus_instance); + goto err_put_ctrl; + } + + if (pmic_arb->bus_instance == 0) { + pmic_arb->base_apid = 0; + pmic_arb->apid_count = + readl_relaxed(core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else { + pmic_arb->base_apid = + readl_relaxed(core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + pmic_arb->apid_count = + readl_relaxed(core + PMIC_ARB_FEATURES1) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } + + if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { + err = -EINVAL; + dev_err(&pdev->dev, "Unsupported APID count %d detected\n", + pmic_arb->base_apid + pmic_arb->apid_count); + goto err_put_ctrl; + } + } else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) { + pmic_arb->base_apid = 0; + pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + + if (pmic_arb->apid_count > pmic_arb->max_periphs) { + err = -EINVAL; + dev_err(&pdev->dev, "Unsupported APID count %d detected\n", + pmic_arb->apid_count); + goto err_put_ctrl; + } + } + + pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, + sizeof(*pmic_arb->apid_data), + GFP_KERNEL); + if (!pmic_arb->apid_data) { + err = -ENOMEM; + goto err_put_ctrl; + } + dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", pmic_arb->ver_ops->ver_str, hw_ver); @@ -1420,7 +1620,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) } pmic_arb->ee = ee; - mapping_table = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PERIPHS, + mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, sizeof(*mapping_table), GFP_KERNEL); if (!mapping_table) { err = -ENOMEM; @@ -1431,7 +1631,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) /* Initialize max_apid/min_apid to the opposite bounds, during * the irq domain translation, we are sure to update these */ pmic_arb->max_apid = 0; - pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1; + pmic_arb->min_apid = pmic_arb->max_periphs - 1; platform_set_drvdata(pdev, ctrl); raw_spin_lock_init(&pmic_arb->lock); -- GitLab From 4634c973096a64662a24d9914c47cebc2a8b72f4 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Wed, 2 Nov 2022 15:26:59 +0800 Subject: [PATCH 0461/1480] chardev: Fix potential memory leak when cdev_add() failed Some init function of cdev(like comedi) will call kobject_set_name() before cdev_add(), but won't free the cdev.kobj.name or put the ref cnt of cdev.kobj when cdev_add() failed. As the result, cdev.kobj.name will be leaked. Free the name of kobject in cdev_add() fail path to prevent memleak. With this fix, the callers don't need to care about freeing the name of kobject if cdev_add() fails. unreferenced object 0xffff8881000fa8c0 (size 8): comm "modprobe", pid 239, jiffies 4294905173 (age 51.308s) hex dump (first 8 bytes): 63 6f 6d 65 64 69 00 ff comedi.. backtrace: [<000000005f9878f7>] __kmalloc_node_track_caller+0x4c/0x1c0 [<000000000fd70302>] kstrdup+0x3f/0x70 [<000000009428bc33>] kstrdup_const+0x46/0x60 [<00000000ed50d9de>] kvasprintf_const+0xdb/0xf0 [<00000000b2766964>] kobject_set_name_vargs+0x3c/0xe0 [<00000000f2424ef7>] kobject_set_name+0x62/0x90 [<000000005d5a125b>] 0xffffffffa0013098 [<00000000f331e663>] do_one_initcall+0x7a/0x380 [<00000000aa7bac96>] do_init_module+0x5c/0x230 [<000000005fd72335>] load_module+0x227d/0x2420 [<00000000ad550cf1>] __do_sys_finit_module+0xd5/0x140 [<00000000069a60c5>] do_syscall_64+0x3f/0x90 [<00000000c5e0d521>] entry_SYSCALL_64_after_hwframe+0x63/0xcd Suggested-by: Greg KH Signed-off-by: Shang XiaoJing Link: https://lore.kernel.org/r/20221102072659.23671-1-shangxiaojing@huawei.com Signed-off-by: Greg Kroah-Hartman --- fs/char_dev.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/char_dev.c b/fs/char_dev.c index ba0ded7842a77..340e4543b24a9 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -483,17 +483,24 @@ int cdev_add(struct cdev *p, dev_t dev, unsigned count) p->dev = dev; p->count = count; - if (WARN_ON(dev == WHITEOUT_DEV)) - return -EBUSY; + if (WARN_ON(dev == WHITEOUT_DEV)) { + error = -EBUSY; + goto err; + } error = kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); if (error) - return error; + goto err; kobject_get(p->kobj.parent); return 0; + +err: + kfree_const(p->kobj.name); + p->kobj.name = NULL; + return error; } /** -- GitLab From 982a84455e94bf195f2c35f221a6b4fe239d74d2 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Mon, 31 Oct 2022 02:35:57 -0400 Subject: [PATCH 0462/1480] misc: genwqe: card_base: Fix some kernel-doc warnings Fixes the following W=1 kernel build warning(s): drivers/misc/genwqe/card_base.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst Signed-off-by: Bo Liu Link: https://lore.kernel.org/r/20221031063557.2710-1-liubo03@inspur.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 693981891870c..bae8114f28059 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * IBM Accelerator Family 'GenWQE' * * (C) Copyright IBM Corp. 2013 -- GitLab From e48031603ae644054a9251c6fc7f0e0fd4e2683a Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 6 Oct 2022 07:36:50 +0200 Subject: [PATCH 0463/1480] uio: uio_fsl_elbc_gpcm: Replace NO_IRQ by 0 NO_IRQ is used to check the return of irq_of_parse_and_map(). On some architecture NO_IRQ is 0, on other architectures it is -1. irq_of_parse_and_map() returns 0 on error, independent of NO_IRQ. So use 0 instead of using NO_IRQ. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/68ccdf51811ab26bdb452babf17ae860fa4900c2.1665034535.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_fsl_elbc_gpcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c index 7d8eb9dc20681..82dda799f327d 100644 --- a/drivers/uio/uio_fsl_elbc_gpcm.c +++ b/drivers/uio/uio_fsl_elbc_gpcm.c @@ -390,13 +390,13 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) info->priv = priv; info->name = uio_name; info->version = "0.0.1"; - if (irq != NO_IRQ) { + if (irq) { if (priv->irq_handler) { info->irq = irq; info->irq_flags = IRQF_SHARED; info->handler = priv->irq_handler; } else { - irq = NO_IRQ; + irq = 0; dev_warn(priv->dev, "ignoring irq, no handler\n"); } } @@ -417,7 +417,7 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) dev_info(priv->dev, "eLBC/GPCM device (%s) at 0x%llx, bank %d, irq=%d\n", priv->name, (unsigned long long)res.start, priv->bank, - irq != NO_IRQ ? irq : -1); + irq ? : -1); return 0; out_err2: -- GitLab From d88bd098f45e0dcf317f8924a38b48e8a14a3854 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Sep 2022 22:16:37 +0100 Subject: [PATCH 0464/1480] test_firmware: Fix spelling mistake "EMTPY" -> "EMPTY" There are spelling mistakes in config show text. Fix these. Signed-off-by: Colin Ian King Reviewed-by: Russ Weight Link: https://lore.kernel.org/r/20220928211637.62529-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- lib/test_firmware.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/test_firmware.c b/lib/test_firmware.c index c82b65947ce68..0c714cdd51eff 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -284,7 +284,7 @@ static ssize_t config_show(struct device *dev, test_fw_config->name); else len += scnprintf(buf + len, PAGE_SIZE - len, - "name:\tEMTPY\n"); + "name:\tEMPTY\n"); len += scnprintf(buf + len, PAGE_SIZE - len, "num_requests:\t%u\n", test_fw_config->num_requests); @@ -315,7 +315,7 @@ static ssize_t config_show(struct device *dev, test_fw_config->upload_name); else len += scnprintf(buf + len, PAGE_SIZE - len, - "upload_name:\tEMTPY\n"); + "upload_name:\tEMPTY\n"); mutex_unlock(&test_fw_mutex); -- GitLab From 19d54020883c210a0cc78e5c735900ee9e9f64b3 Mon Sep 17 00:00:00 2001 From: Jack Rosenthal Date: Fri, 4 Nov 2022 10:15:28 -0600 Subject: [PATCH 0465/1480] firmware: google: Implement cbmem in sysfs driver The CBMEM area is a downward-growing memory region used by coreboot to dynamically allocate tagged data structures ("CBMEM entries") that remain resident during boot. This implements a driver which exports access to the CBMEM entries via sysfs under /sys/bus/coreboot/devices/cbmem-. This implementation is quite versatile. Examples of how it could be used are given below: * Tools like util/cbmem from the coreboot tree could use this driver instead of finding CBMEM in /dev/mem directly. Alternatively, firmware developers debugging an issue may find the sysfs interface more ergonomic than the cbmem tool and choose to use it directly. * The crossystem tool, which exposes verified boot variables, can use this driver to read the vboot work buffer. * Tools which read the BIOS SPI flash (e.g., flashrom) can find the flash layout in CBMEM directly, which is significantly faster than searching the flash directly. Write access is provided to all CBMEM regions via /sys/bus/coreboot/devices/cbmem-/mem, as the existing cbmem tooling updates this memory region, and envisioned use cases with crossystem can benefit from updating memory regions. Link: https://issuetracker.google.com/239604743 Cc: Stephen Boyd Cc: Tzung-Bi Shih Reviewed-by: Guenter Roeck Reviewed-by: Julius Werner Tested-by: Jack Rosenthal Signed-off-by: Jack Rosenthal Link: https://lore.kernel.org/r/20221104161528.531248-1-jrosenth@chromium.org Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-coreboot | 45 +++++++ drivers/firmware/google/Kconfig | 15 +++ drivers/firmware/google/Makefile | 3 + drivers/firmware/google/cbmem.c | 129 +++++++++++++++++++ drivers/firmware/google/coreboot_table.c | 11 +- drivers/firmware/google/coreboot_table.h | 18 +++ 6 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-coreboot create mode 100644 drivers/firmware/google/cbmem.c diff --git a/Documentation/ABI/testing/sysfs-bus-coreboot b/Documentation/ABI/testing/sysfs-bus-coreboot new file mode 100644 index 0000000000000..9c5accecc4709 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coreboot @@ -0,0 +1,45 @@ +What: /sys/bus/coreboot +Date: August 2022 +Contact: Jack Rosenthal +Description: + The coreboot bus provides a variety of virtual devices used to + access data structures created by the Coreboot BIOS. + +What: /sys/bus/coreboot/devices/cbmem- +Date: August 2022 +Contact: Jack Rosenthal +Description: + CBMEM is a downwards-growing memory region created by Coreboot, + and contains tagged data structures to be shared with payloads + in the boot process and the OS. Each CBMEM entry is given a + directory in /sys/bus/coreboot/devices based on its id. + A list of ids known to Coreboot can be found in the coreboot + source tree at + ``src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h``. + +What: /sys/bus/coreboot/devices/cbmem-/address +Date: August 2022 +Contact: Jack Rosenthal +Description: + This is the pyhsical memory address that the CBMEM entry's data + begins at, in hexadecimal (e.g., ``0x76ffe000``). + +What: /sys/bus/coreboot/devices/cbmem-/size +Date: August 2022 +Contact: Jack Rosenthal +Description: + This is the size of the CBMEM entry's data, in hexadecimal + (e.g., ``0x1234``). + +What: /sys/bus/coreboot/devices/cbmem-/mem +Date: August 2022 +Contact: Jack Rosenthal +Description: + A file exposing read/write access to the entry's data. Note + that this file does not support mmap(), as coreboot + does not guarantee that the data will be page-aligned. + + The mode of this file is 0600. While there shouldn't be + anything security-sensitive contained in CBMEM, read access + requires root privileges given this is exposing a small subset + of physical memory. diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig index 983e07dc022ed..9f190eab43ed1 100644 --- a/drivers/firmware/google/Kconfig +++ b/drivers/firmware/google/Kconfig @@ -19,6 +19,21 @@ config GOOGLE_SMI driver provides an interface for reading and writing NVRAM variables. +config GOOGLE_CBMEM + tristate "CBMEM entries in sysfs" + depends on GOOGLE_COREBOOT_TABLE + help + CBMEM is a downwards-growing memory region created by the + Coreboot BIOS containing tagged data structures from the + BIOS. These data structures expose things like the verified + boot firmware variables, flash layout, firmware event log, + and more. + + This option enables the cbmem module, which causes the + kernel to search for Coreboot CBMEM entries, and expose the + memory for each entry in sysfs under + /sys/bus/coreboot/devices/cbmem-. + config GOOGLE_COREBOOT_TABLE tristate "Coreboot Table Access" depends on HAS_IOMEM && (ACPI || OF) diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile index d17caded5d883..8151e323cc434 100644 --- a/drivers/firmware/google/Makefile +++ b/drivers/firmware/google/Makefile @@ -7,5 +7,8 @@ obj-$(CONFIG_GOOGLE_MEMCONSOLE) += memconsole.o obj-$(CONFIG_GOOGLE_MEMCONSOLE_COREBOOT) += memconsole-coreboot.o obj-$(CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY) += memconsole-x86-legacy.o +# Must come after coreboot_table.o, as this driver depends on that bus type. +obj-$(CONFIG_GOOGLE_CBMEM) += cbmem.o + vpd-sysfs-y := vpd.o vpd_decode.o obj-$(CONFIG_GOOGLE_VPD) += vpd-sysfs.o diff --git a/drivers/firmware/google/cbmem.c b/drivers/firmware/google/cbmem.c new file mode 100644 index 0000000000000..685f3070ce9d8 --- /dev/null +++ b/drivers/firmware/google/cbmem.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cbmem.c + * + * Driver for exporting cbmem entries in sysfs. + * + * Copyright 2022 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coreboot_table.h" + +struct cbmem_entry { + char *mem_file_buf; + u32 size; +}; + +static struct cbmem_entry *to_cbmem_entry(struct kobject *kobj) +{ + return dev_get_drvdata(kobj_to_dev(kobj)); +} + +static ssize_t mem_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t pos, + size_t count) +{ + struct cbmem_entry *entry = to_cbmem_entry(kobj); + + return memory_read_from_buffer(buf, count, &pos, entry->mem_file_buf, + entry->size); +} + +static ssize_t mem_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t pos, + size_t count) +{ + struct cbmem_entry *entry = to_cbmem_entry(kobj); + + if (pos < 0 || pos >= entry->size) + return -EINVAL; + if (count > entry->size - pos) + count = entry->size - pos; + + memcpy(entry->mem_file_buf + pos, buf, count); + return count; +} +static BIN_ATTR_ADMIN_RW(mem, 0); + +static ssize_t address_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct coreboot_device *cbdev = dev_to_coreboot_device(dev); + + return sysfs_emit(buf, "0x%llx\n", cbdev->cbmem_entry.address); +} +static DEVICE_ATTR_RO(address); + +static ssize_t size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct coreboot_device *cbdev = dev_to_coreboot_device(dev); + + return sysfs_emit(buf, "0x%x\n", cbdev->cbmem_entry.entry_size); +} +static DEVICE_ATTR_RO(size); + +static struct attribute *attrs[] = { + &dev_attr_address.attr, + &dev_attr_size.attr, + NULL, +}; + +static struct bin_attribute *bin_attrs[] = { + &bin_attr_mem, + NULL, +}; + +static const struct attribute_group cbmem_entry_group = { + .attrs = attrs, + .bin_attrs = bin_attrs, +}; + +static const struct attribute_group *dev_groups[] = { + &cbmem_entry_group, + NULL, +}; + +static int cbmem_entry_probe(struct coreboot_device *dev) +{ + struct cbmem_entry *entry; + + entry = devm_kzalloc(&dev->dev, sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + dev_set_drvdata(&dev->dev, entry); + entry->mem_file_buf = devm_memremap(&dev->dev, dev->cbmem_entry.address, + dev->cbmem_entry.entry_size, + MEMREMAP_WB); + if (!entry->mem_file_buf) + return -ENOMEM; + + entry->size = dev->cbmem_entry.entry_size; + + return 0; +} + +static struct coreboot_driver cbmem_entry_driver = { + .probe = cbmem_entry_probe, + .drv = { + .name = "cbmem", + .owner = THIS_MODULE, + .dev_groups = dev_groups, + }, + .tag = LB_TAG_CBMEM_ENTRY, +}; +module_coreboot_driver(cbmem_entry_driver); + +MODULE_AUTHOR("Jack Rosenthal "); +MODULE_LICENSE("GPL"); diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c index c52bcaa9def60..7748067eb9e6b 100644 --- a/drivers/firmware/google/coreboot_table.c +++ b/drivers/firmware/google/coreboot_table.c @@ -97,12 +97,21 @@ static int coreboot_table_populate(struct device *dev, void *ptr) if (!device) return -ENOMEM; - dev_set_name(&device->dev, "coreboot%d", i); device->dev.parent = dev; device->dev.bus = &coreboot_bus_type; device->dev.release = coreboot_device_release; memcpy(&device->entry, ptr_entry, entry->size); + switch (device->entry.tag) { + case LB_TAG_CBMEM_ENTRY: + dev_set_name(&device->dev, "cbmem-%08x", + device->cbmem_entry.id); + break; + default: + dev_set_name(&device->dev, "coreboot%d", i); + break; + } + ret = device_register(&device->dev); if (ret) { put_device(&device->dev); diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h index beb778674acdc..37f4d335a606d 100644 --- a/drivers/firmware/google/coreboot_table.h +++ b/drivers/firmware/google/coreboot_table.h @@ -39,6 +39,18 @@ struct lb_cbmem_ref { u64 cbmem_addr; }; +#define LB_TAG_CBMEM_ENTRY 0x31 + +/* Corresponds to LB_TAG_CBMEM_ENTRY */ +struct lb_cbmem_entry { + u32 tag; + u32 size; + + u64 address; + u32 entry_size; + u32 id; +}; + /* Describes framebuffer setup by coreboot */ struct lb_framebuffer { u32 tag; @@ -65,10 +77,16 @@ struct coreboot_device { union { struct coreboot_table_entry entry; struct lb_cbmem_ref cbmem_ref; + struct lb_cbmem_entry cbmem_entry; struct lb_framebuffer framebuffer; }; }; +static inline struct coreboot_device *dev_to_coreboot_device(struct device *dev) +{ + return container_of(dev, struct coreboot_device, dev); +} + /* A driver for handling devices described in coreboot tables. */ struct coreboot_driver { int (*probe)(struct coreboot_device *); -- GitLab From 9de255c461d1b3f0242b3ad1450c3323a3e00b34 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Fri, 30 Sep 2022 19:40:57 -0300 Subject: [PATCH 0466/1480] uio: uio_dmem_genirq: Fix missing unlock in irq configuration Commit b74351287d4b ("uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") started calling disable_irq() without holding the spinlock because it can sleep. However, that fix introduced another bug: if interrupt is already disabled and a new disable request comes in, then the spinlock is not unlocked: root@localhost:~# printf '\x00\x00\x00\x00' > /dev/uio0 root@localhost:~# printf '\x00\x00\x00\x00' > /dev/uio0 root@localhost:~# [ 14.851538] BUG: scheduling while atomic: bash/223/0x00000002 [ 14.851991] Modules linked in: uio_dmem_genirq uio myfpga(OE) bochs drm_vram_helper drm_ttm_helper ttm drm_kms_helper drm snd_pcm ppdev joydev psmouse snd_timer snd e1000fb_sys_fops syscopyarea parport sysfillrect soundcore sysimgblt input_leds pcspkr i2c_piix4 serio_raw floppy evbug qemu_fw_cfg mac_hid pata_acpi ip_tables x_tables autofs4 [last unloaded: parport_pc] [ 14.854206] CPU: 0 PID: 223 Comm: bash Tainted: G OE 6.0.0-rc7 #21 [ 14.854786] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 [ 14.855664] Call Trace: [ 14.855861] [ 14.856025] dump_stack_lvl+0x4d/0x67 [ 14.856325] dump_stack+0x14/0x1a [ 14.856583] __schedule_bug.cold+0x4b/0x5c [ 14.856915] __schedule+0xe81/0x13d0 [ 14.857199] ? idr_find+0x13/0x20 [ 14.857456] ? get_work_pool+0x2d/0x50 [ 14.857756] ? __flush_work+0x233/0x280 [ 14.858068] ? __schedule+0xa95/0x13d0 [ 14.858307] ? idr_find+0x13/0x20 [ 14.858519] ? get_work_pool+0x2d/0x50 [ 14.858798] schedule+0x6c/0x100 [ 14.859009] schedule_hrtimeout_range_clock+0xff/0x110 [ 14.859335] ? tty_write_room+0x1f/0x30 [ 14.859598] ? n_tty_poll+0x1ec/0x220 [ 14.859830] ? tty_ldisc_deref+0x1a/0x20 [ 14.860090] schedule_hrtimeout_range+0x17/0x20 [ 14.860373] do_select+0x596/0x840 [ 14.860627] ? __kernel_text_address+0x16/0x50 [ 14.860954] ? poll_freewait+0xb0/0xb0 [ 14.861235] ? poll_freewait+0xb0/0xb0 [ 14.861517] ? rpm_resume+0x49d/0x780 [ 14.861798] ? common_interrupt+0x59/0xa0 [ 14.862127] ? asm_common_interrupt+0x2b/0x40 [ 14.862511] ? __uart_start.isra.0+0x61/0x70 [ 14.862902] ? __check_object_size+0x61/0x280 [ 14.863255] core_sys_select+0x1c6/0x400 [ 14.863575] ? vfs_write+0x1c9/0x3d0 [ 14.863853] ? vfs_write+0x1c9/0x3d0 [ 14.864121] ? _copy_from_user+0x45/0x70 [ 14.864526] do_pselect.constprop.0+0xb3/0xf0 [ 14.864893] ? do_syscall_64+0x6d/0x90 [ 14.865228] ? do_syscall_64+0x6d/0x90 [ 14.865556] __x64_sys_pselect6+0x76/0xa0 [ 14.865906] do_syscall_64+0x60/0x90 [ 14.866214] ? syscall_exit_to_user_mode+0x2a/0x50 [ 14.866640] ? do_syscall_64+0x6d/0x90 [ 14.866972] ? do_syscall_64+0x6d/0x90 [ 14.867286] ? do_syscall_64+0x6d/0x90 [ 14.867626] entry_SYSCALL_64_after_hwframe+0x63/0xcd [...] stripped [ 14.872959] ('myfpga' is a simple 'uio_dmem_genirq' driver I wrote to test this) The implementation of "uio_dmem_genirq" was based on "uio_pdrv_genirq" and it is used in a similar manner to the "uio_pdrv_genirq" driver with respect to interrupt configuration and handling. At the time "uio_dmem_genirq" was introduced, both had the same implementation of the 'uio_info' handlers irqcontrol() and handler(). Then commit 34cb27528398 ("UIO: Fix concurrency issue"), which was only applied to "uio_pdrv_genirq", ended up making them a little different. That commit, among other things, changed disable_irq() to disable_irq_nosync() in the implementation of irqcontrol(). The motivation there was to avoid a deadlock between irqcontrol() and handler(), since it added a spinlock in the irq handler, and disable_irq() waits for the completion of the irq handler. By changing disable_irq() to disable_irq_nosync() in irqcontrol(), we also avoid the sleeping-while-atomic bug that commit b74351287d4b ("uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") was trying to fix. Thus, this fixes the missing unlock in irqcontrol() by importing the implementation of irqcontrol() handler from the "uio_pdrv_genirq" driver. In the end, it reverts commit b74351287d4b ("uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") and change disable_irq() to disable_irq_nosync(). It is worth noting that this still does not address the concurrency issue fixed by commit 34cb27528398 ("UIO: Fix concurrency issue"). It will be addressed separately in the next commits. Split out from commit 34cb27528398 ("UIO: Fix concurrency issue"). Fixes: b74351287d4b ("uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol()") Signed-off-by: Rafael Mendonca Link: https://lore.kernel.org/r/20220930224100.816175-2-rafaelmendsr@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 1106f33764047..cb283ee36eaa9 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -132,13 +132,11 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) if (irq_on) { if (test_and_clear_bit(0, &priv->flags)) enable_irq(dev_info->irq); - spin_unlock_irqrestore(&priv->lock, flags); } else { - if (!test_and_set_bit(0, &priv->flags)) { - spin_unlock_irqrestore(&priv->lock, flags); - disable_irq(dev_info->irq); - } + if (!test_and_set_bit(0, &priv->flags)) + disable_irq_nosync(dev_info->irq); } + spin_unlock_irqrestore(&priv->lock, flags); return 0; } -- GitLab From 118b918018175d9fcd8db667f905012e986cc2c9 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Fri, 30 Sep 2022 19:40:58 -0300 Subject: [PATCH 0467/1480] uio: uio_dmem_genirq: Fix deadlock between irq config and handling This fixes a concurrency issue addressed in commit 34cb27528398 ("UIO: Fix concurrency issue"): "In a SMP case there was a race condition issue between Uio_pdrv_genirq_irqcontrol() running on one CPU and irq handler on another CPU. Fix it by spin_locking shared resources access inside irq handler." The implementation of "uio_dmem_genirq" was based on "uio_pdrv_genirq" and it is used in a similar manner to the "uio_pdrv_genirq" driver with respect to interrupt configuration and handling. At the time "uio_dmem_genirq" was merged, both had the same implementation of the 'uio_info' handlers irqcontrol() and handler(), thus, both had the same concurrency issue mentioned by the above commit. However, the above patch was only applied to the "uio_pdrv_genirq" driver. Split out from commit 34cb27528398 ("UIO: Fix concurrency issue"). Fixes: 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation") Signed-off-by: Rafael Mendonca Link: https://lore.kernel.org/r/20220930224100.816175-3-rafaelmendsr@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index cb283ee36eaa9..792c3e9c9ce53 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -110,8 +110,10 @@ static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info) * remember the state so we can allow user space to enable it later. */ + spin_lock(&priv->lock); if (!test_and_set_bit(0, &priv->flags)) disable_irq_nosync(irq); + spin_unlock(&priv->lock); return IRQ_HANDLED; } @@ -125,7 +127,8 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) * in the interrupt controller, but keep track of the * state to prevent per-irq depth damage. * - * Serialize this operation to support multiple tasks. + * Serialize this operation to support multiple tasks and concurrency + * with irq handler on SMP systems. */ spin_lock_irqsave(&priv->lock, flags); -- GitLab From a3fc57bc49a24960fd6a907457f9360a3e65b968 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Fri, 30 Sep 2022 19:40:59 -0300 Subject: [PATCH 0468/1480] uio: uio_dmem_genirq: Use non-atomic bit operations in irq config and handling This finishes the port of the irq configuration and handling from "uio_pdrv_genirq" to "uio_dmem_genirq". It changes the atomic bit-manipulation routines to their non-atomic counterparts as we are already guarding the code by spinlock. Split out from commit 34cb27528398 ("UIO: Fix concurrency issue"). Signed-off-by: Rafael Mendonca Link: https://lore.kernel.org/r/20220930224100.816175-4-rafaelmendsr@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 792c3e9c9ce53..5313307c2754a 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -41,6 +41,11 @@ struct uio_dmem_genirq_platdata { unsigned int refcnt; }; +/* Bits in uio_dmem_genirq_platdata.flags */ +enum { + UIO_IRQ_DISABLED = 0, +}; + static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) { struct uio_dmem_genirq_platdata *priv = info->priv; @@ -111,7 +116,7 @@ static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info) */ spin_lock(&priv->lock); - if (!test_and_set_bit(0, &priv->flags)) + if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags)) disable_irq_nosync(irq); spin_unlock(&priv->lock); @@ -133,10 +138,10 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) spin_lock_irqsave(&priv->lock, flags); if (irq_on) { - if (test_and_clear_bit(0, &priv->flags)) + if (__test_and_clear_bit(UIO_IRQ_DISABLED, &priv->flags)) enable_irq(dev_info->irq); } else { - if (!test_and_set_bit(0, &priv->flags)) + if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags)) disable_irq_nosync(dev_info->irq); } spin_unlock_irqrestore(&priv->lock, flags); -- GitLab From d4ad017d634561907ecdd1e467a28612b369ee00 Mon Sep 17 00:00:00 2001 From: Soha Jin Date: Sat, 1 Oct 2022 00:26:04 +0800 Subject: [PATCH 0469/1480] platform: use fwnode_irq_get_byname instead of of_irq_get_byname to get irq Not only platform devices described by OF have named interrupts, but devices described by ACPI also have named interrupts. The fwnode is an abstraction to different standards, and using fwnode_irq_get_byname can support more devices. Signed-off-by: Soha Jin Tested-by: Wende Tan Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 51bb2289865c7..968f3d71eeab2 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -441,8 +441,8 @@ static int __platform_get_irq_byname(struct platform_device *dev, struct resource *r; int ret; - if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { - ret = of_irq_get_byname(dev->dev.of_node, name); + if (!dev->dev.of_node || IS_ENABLED(CONFIG_OF_IRQ)) { + ret = fwnode_irq_get_byname(dev_fwnode(&dev->dev), name); if (ret > 0 || ret == -EPROBE_DEFER) return ret; } -- GitLab From 2a4e628570d42fcc13a94f1acf25e3cfeaec08f6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Nov 2022 17:56:17 +0200 Subject: [PATCH 0470/1480] resource: Replace printk(KERN_WARNING) by pr_warn(), printk() by pr_info() Replace printk(KERN_WARNING) by pr_warn() and printk() by pr_info(). While at it, use %pa for the resource_size_t variables. With that, for the sake of consistency, introduce a temporary variable for the end address in iomem_map_sanity_check() like it's done in another function in the same module. Signed-off-by: Andy Shevchenko Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221109155618.42276-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- kernel/resource.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index 4c5e80b92f2f4..ab32b015bd509 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -888,7 +888,7 @@ void insert_resource_expand_to_fit(struct resource *root, struct resource *new) if (conflict->end > new->end) new->end = conflict->end; - printk("Expanded resource %s due to conflict with %s\n", new->name, conflict->name); + pr_info("Expanded resource %s due to conflict with %s\n", new->name, conflict->name); } write_unlock(&resource_lock); } @@ -1283,9 +1283,7 @@ void __release_region(struct resource *parent, resource_size_t start, write_unlock(&resource_lock); - printk(KERN_WARNING "Trying to free nonexistent resource " - "<%016llx-%016llx>\n", (unsigned long long)start, - (unsigned long long)end); + pr_warn("Trying to free nonexistent resource <%pa-%pa>\n", &start, &end); } EXPORT_SYMBOL(__release_region); @@ -1658,6 +1656,7 @@ __setup("reserve=", reserve_setup); int iomem_map_sanity_check(resource_size_t addr, unsigned long size) { struct resource *p = &iomem_resource; + resource_size_t end = addr + size - 1; int err = 0; loff_t l; @@ -1667,12 +1666,12 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) * We can probably skip the resources without * IORESOURCE_IO attribute? */ - if (p->start >= addr + size) + if (p->start > end) continue; if (p->end < addr) continue; if (PFN_DOWN(p->start) <= PFN_DOWN(addr) && - PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1)) + PFN_DOWN(p->end) >= PFN_DOWN(end)) continue; /* * if a resource is "BUSY", it's not a hardware resource @@ -1683,10 +1682,8 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) if (p->flags & IORESOURCE_BUSY) continue; - printk(KERN_WARNING "resource sanity check: requesting [mem %#010llx-%#010llx], which spans more than %s %pR\n", - (unsigned long long)addr, - (unsigned long long)(addr + size - 1), - p->name, p); + pr_warn("resource sanity check: requesting [mem %pa-%pa], which spans more than %s %pR\n", + &addr, &end, p->name, p); err = -1; break; } -- GitLab From 52c4d11f1dce60453ab2a75fd7103118cedb2b58 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Nov 2022 17:56:18 +0200 Subject: [PATCH 0471/1480] resource: Convert DEFINE_RES_NAMED() to be compound literal Currently DEFINE_RES_NAMED() can only be used to fill the static data. In some cases it would be convenient to use it as right value in the assignment operation. But it can't be done as is, because compiler has no clue about the data layout. Converting it to be a compound literal allows the above mentioned usage. Signed-off-by: Andy Shevchenko Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221109155618.42276-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/ioport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 27642ca15d932..67d3fb2133b6c 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -155,7 +155,7 @@ enum { /* helpers to define resources */ #define DEFINE_RES_NAMED(_start, _size, _name, _flags) \ - { \ +(struct resource) { \ .start = (_start), \ .end = (_start) + (_size) - 1, \ .name = (_name), \ -- GitLab From 882cf4c913d730a74175db039d941005b883de38 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 17 Oct 2022 15:40:38 +0800 Subject: [PATCH 0472/1480] drivers: bus: simple-pm-bus: Use clocks Simple Power-Managed bus controller may need functional clock(s) to be enabled before child devices connected to the bus can be accessed. Get the clock(s) as a bulk and enable/disable the clock(s) when the bus is being power managed. One example is that Freescale i.MX8qxp pixel link MSI bus controller needs MSI clock and AHB clock to be enabled before accessing child devices. Reviewed-by: Geert Uytterhoeven Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20221017074039.4181843-2-victor.liu@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/bus/simple-pm-bus.c | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c index 6b8d6257ed8a4..d7b043fefde9e 100644 --- a/drivers/bus/simple-pm-bus.c +++ b/drivers/bus/simple-pm-bus.c @@ -8,17 +8,24 @@ * for more details. */ +#include #include #include #include #include +struct simple_pm_bus { + struct clk_bulk_data *clks; + int num_clks; +}; + static int simple_pm_bus_probe(struct platform_device *pdev) { const struct device *dev = &pdev->dev; const struct of_dev_auxdata *lookup = dev_get_platdata(dev); struct device_node *np = dev->of_node; const struct of_device_id *match; + struct simple_pm_bus *bus; /* * Allow user to use driver_override to bind this driver to a @@ -44,6 +51,16 @@ static int simple_pm_bus_probe(struct platform_device *pdev) return -ENODEV; } + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + + bus->num_clks = devm_clk_bulk_get_all(&pdev->dev, &bus->clks); + if (bus->num_clks < 0) + return dev_err_probe(&pdev->dev, bus->num_clks, "failed to get clocks\n"); + + dev_set_drvdata(&pdev->dev, bus); + dev_dbg(&pdev->dev, "%s\n", __func__); pm_runtime_enable(&pdev->dev); @@ -67,6 +84,36 @@ static int simple_pm_bus_remove(struct platform_device *pdev) return 0; } +static int simple_pm_bus_runtime_suspend(struct device *dev) +{ + struct simple_pm_bus *bus = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(bus->num_clks, bus->clks); + + return 0; +} + +static int simple_pm_bus_runtime_resume(struct device *dev) +{ + struct simple_pm_bus *bus = dev_get_drvdata(dev); + int ret; + + ret = clk_bulk_prepare_enable(bus->num_clks, bus->clks); + if (ret) { + dev_err(dev, "failed to enable clocks: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct dev_pm_ops simple_pm_bus_pm_ops = { + SET_RUNTIME_PM_OPS(simple_pm_bus_runtime_suspend, + simple_pm_bus_runtime_resume, NULL) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + #define ONLY_BUS ((void *) 1) /* Match if the device is only a bus. */ static const struct of_device_id simple_pm_bus_of_match[] = { @@ -85,6 +132,7 @@ static struct platform_driver simple_pm_bus_driver = { .driver = { .name = "simple-pm-bus", .of_match_table = simple_pm_bus_of_match, + .pm = &simple_pm_bus_pm_ops, }, }; -- GitLab From c08645ea215c446ceb21029fe5416e6a62cbbed7 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 17 Oct 2022 15:40:39 +0800 Subject: [PATCH 0473/1480] dt-bindings: bus: Add Freescale i.MX8qxp pixel link MSI bus binding Freescale i.MX8qxp pixel link MSI bus is a simple memory-mapped bus. It is used to access peripherals in i.MX8qm/qxp imaging, LVDS, MIPI DSI and HDMI TX subsystems, like I2C controller, PWM controller, MIPI DSI controller and Control and Status Registers (CSR) module. Reference simple-pm-bus bindings and add Freescale i.MX8qxp pixel link MSI bus specific bindings. Reviewed-by: Rob Herring Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20221017074039.4181843-3-victor.liu@nxp.com Signed-off-by: Greg Kroah-Hartman --- .../bus/fsl,imx8qxp-pixel-link-msi-bus.yaml | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml diff --git a/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml b/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml new file mode 100644 index 0000000000000..b568d0ce438d2 --- /dev/null +++ b/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml @@ -0,0 +1,232 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8qxp Pixel Link Medium Speed Interconnect (MSI) Bus + +maintainers: + - Liu Ying + +description: | + i.MX8qxp pixel link MSI bus is used to control settings of PHYs, I/Os + sitting together with the PHYs. It is not the same as the MSI bus coming + from i.MX8 System Controller Unit (SCU) which is used to control power, + clock and reset through the i.MX8 Distributed Slave System Controller (DSC). + + i.MX8qxp pixel link MSI bus is a simple memory-mapped bus. Two input clocks, + that is, MSI clock and AHB clock, need to be enabled so that peripherals + connected to the bus can be accessed. Also, the bus is part of a power + domain. The power domain needs to be enabled before the peripherals can + be accessed. + + Peripherals in i.MX8qm/qxp imaging, LVDS, MIPI DSI and HDMI TX subsystems, + like I2C controller, PWM controller, MIPI DSI controller and Control and + Status Registers (CSR) module, are accessed through the bus. + + The i.MX System Controller Firmware (SCFW) owns and uses the i.MX8qm/qxp + pixel link MSI bus controller and does not allow SCFW user to control it. + So, the controller's registers cannot be accessed by SCFW user. Hence, + the interrupts generated by the controller don't make any sense from SCFW + user's point of view. + +allOf: + - $ref: simple-pm-bus.yaml# + +# We need a select here so we don't match all nodes with 'simple-pm-bus'. +select: + properties: + compatible: + contains: + enum: + - fsl,imx8qxp-display-pixel-link-msi-bus + - fsl,imx8qm-display-pixel-link-msi-bus + required: + - compatible + +properties: + compatible: + items: + - enum: + - fsl,imx8qxp-display-pixel-link-msi-bus + - fsl,imx8qm-display-pixel-link-msi-bus + - const: simple-pm-bus + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: master gated clock from system + - description: AHB clock + + clock-names: + items: + - const: msi + - const: ahb + +patternProperties: + "^.*@[0-9a-f]+$": + description: Devices attached to the bus + type: object + properties: + reg: + maxItems: 1 + + required: + - reg + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + +unevaluatedProperties: false + +examples: + - | + #include + #include + bus@56200000 { + compatible = "fsl,imx8qxp-display-pixel-link-msi-bus", "simple-pm-bus"; + reg = <0x56200000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&dc0_irqsteer>; + interrupts = <320>; + ranges; + clocks = <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>, + <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>; + clock-names = "msi", "ahb"; + power-domains = <&pd IMX_SC_R_DC_0>; + + syscon@56221000 { + compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd"; + reg = <0x56221000 0x1000>; + clocks = <&mipi_lvds_0_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>; + clock-names = "ipg"; + + pxl2dpi { + compatible = "fsl,imx8qxp-pxl2dpi"; + fsl,sc-resource = ; + power-domains = <&pd IMX_SC_R_MIPI_0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint@0 { + reg = <0>; + remote-endpoint = <&dc0_pixel_link0_mipi_lvds_0_pxl2dpi>; + }; + + mipi_lvds_0_pxl2dpi_dc0_pixel_link1: endpoint@1 { + reg = <1>; + remote-endpoint = <&dc0_pixel_link1_mipi_lvds_0_pxl2dpi>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>; + }; + + mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint@1 { + reg = <1>; + remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>; + }; + }; + }; + }; + + ldb { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8qxp-ldb"; + clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>, + <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>; + clock-names = "pixel", "bypass"; + power-domains = <&pd IMX_SC_R_LVDS_0>; + + channel@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + phys = <&mipi_lvds_0_phy>; + phy-names = "lvds_phy"; + + port@0 { + reg = <0>; + + mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint { + remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>; + }; + }; + + port@1 { + reg = <1>; + + /* ... */ + }; + }; + + channel@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + phys = <&mipi_lvds_0_phy>; + phy-names = "lvds_phy"; + + port@0 { + reg = <0>; + + mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint { + remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>; + }; + }; + + port@1 { + reg = <1>; + + /* ... */ + }; + }; + }; + }; + + clock-controller@56223004 { + compatible = "fsl,imx8qxp-lpcg"; + reg = <0x56223004 0x4>; + #clock-cells = <1>; + clocks = <&mipi_lvds_0_ipg_clk>; + clock-indices = ; + clock-output-names = "mipi_lvds_0_di_mipi_lvds_regs_lpcg_ipg_clk"; + power-domains = <&pd IMX_SC_R_MIPI_0>; + }; + + phy@56228300 { + compatible = "fsl,imx8qxp-mipi-dphy"; + reg = <0x56228300 0x100>; + clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>; + clock-names = "phy_ref"; + #phy-cells = <0>; + fsl,syscon = <&mipi_lvds_0_csr>; + power-domains = <&pd IMX_SC_R_MIPI_0>; + }; + }; -- GitLab From 4a4a4e9ebaa3ce903a3cdf8bb173eeaf87828cea Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Mon, 31 Oct 2022 09:44:41 +0700 Subject: [PATCH 0474/1480] misc: smpro-errmon: Add Ampere's SMpro error monitor driver Add Ampere's SMpro error monitor driver for monitoring and reporting RAS-related errors as reported by SMpro co-processor found on Ampere's Altra processor family. Signed-off-by: Quan Nguyen Link: https://lore.kernel.org/r/20221031024442.2490881-3-quan@os.amperecomputing.com Signed-off-by: Greg Kroah-Hartman --- .../sysfs-bus-platform-devices-ampere-smpro | 264 +++++++++ drivers/misc/Kconfig | 12 + drivers/misc/Makefile | 1 + drivers/misc/smpro-errmon.c | 529 ++++++++++++++++++ 4 files changed, 806 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro create mode 100644 drivers/misc/smpro-errmon.c diff --git a/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro b/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro new file mode 100644 index 0000000000000..2b84dc8c3149d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro @@ -0,0 +1,264 @@ +What: /sys/bus/platform/devices/smpro-errmon.*/error_[core|mem|pcie|other]_[ce|ue] +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RO) Contains the 48-byte Ampere (Vendor-Specific) Error Record printed + in hex format according to the table below: + + +--------+---------------+-------------+------------------------------------------------------------+ + | Offset | Field | Size (byte) | Description | + +--------+---------------+-------------+------------------------------------------------------------+ + | 00 | Error Type | 1 | See :ref:`the table below ` for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 01 | Subtype | 1 | See :ref:`the table below ` for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 02 | Instance | 2 | See :ref:`the table below ` for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 04 | Error status | 4 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 08 | Error Address | 8 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 16 | Error Misc 0 | 8 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 24 | Error Misc 1 | 8 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 32 | Error Misc 2 | 8 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + | 40 | Error Misc 3 | 8 | See ARM RAS specification for details | + +--------+---------------+-------------+------------------------------------------------------------+ + + The table below defines the value of error types, their subtype, subcomponent and instance: + + .. _smpro-error-types: + + +-----------------+------------+----------+----------------+----------------------------------------+ + | Error Group | Error Type | Sub type | Sub component | Instance | + +-----------------+------------+----------+----------------+----------------------------------------+ + | CPM (core) | 0 | 0 | Snoop-Logic | CPM # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | CPM (core) | 0 | 2 | Armv8 Core 1 | CPM # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 1 | ERR1 | MCU # \| SLOT << 11 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 2 | ERR2 | MCU # \| SLOT << 11 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 3 | ERR3 | MCU # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 4 | ERR4 | MCU # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 5 | ERR5 | MCU # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 6 | ERR6 | MCU # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | MCU (mem) | 1 | 7 | Link Error | MCU # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | Mesh (other) | 2 | 0 | Cross Point | X \| (Y << 5) \| NS <<11 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | Mesh (other) | 2 | 1 | Home Node(IO) | X \| (Y << 5) \| NS <<11 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | Mesh (other) | 2 | 2 | Home Node(Mem) | X \| (Y << 5) \| NS <<11 \| device<<12 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | Mesh (other) | 2 | 4 | CCIX Node | X \| (Y << 5) \| NS <<11 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | 2P Link (other) | 3 | 0 | N/A | Altra 2P Link # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 0 | ERR0 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 1 | ERR1 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 2 | ERR2 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 3 | ERR3 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 4 | ERR4 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 5 | ERR5 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 6 | ERR6 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 7 | ERR7 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 8 | ERR8 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 9 | ERR9 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 10 | ERR10 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 11 | ERR11 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 12 | ERR12 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | GIC (other) | 5 | 13-21 | ERR13 | RC # + 1 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TCU | 100 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU0 | 0 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU1 | 1 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU2 | 2 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU3 | 3 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU4 | 4 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU5 | 5 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU6 | 6 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU7 | 7 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU8 | 8 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMMU (other) | 6 | TBU9 | 9 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PCIe AER (pcie) | 7 | Root | 0 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PCIe AER (pcie) | 7 | Device | 1 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PCIe RC (pcie) | 8 | RCA HB | 0 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PCIe RC (pcie) | 8 | RCB HB | 1 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PCIe RC (pcie) | 8 | RASDP | 8 | RC # | + +-----------------+------------+----------+----------------+----------------------------------------+ + | OCM (other) | 9 | ERR0 | 0 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | OCM (other) | 9 | ERR1 | 1 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | OCM (other) | 9 | ERR2 | 2 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMpro (other) | 10 | ERR0 | 0 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMpro (other) | 10 | ERR1 | 1 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | SMpro (other) | 10 | MPA_ERR | 2 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PMpro (other) | 11 | ERR0 | 0 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PMpro (other) | 11 | ERR1 | 1 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + | PMpro (other) | 11 | MPA_ERR | 2 | 0 | + +-----------------+------------+----------+----------------+----------------------------------------+ + + Example:: + + # cat error_other_ue + 880807001e004010401040101500000001004010401040100c0000000000000000000000000000000000000000000000 + + The detail of each sysfs entries is as below: + + +-------------+---------------------------------------------------------+----------------------------------+ + | Error | Sysfs entry | Description (when triggered) | + +-------------+---------------------------------------------------------+----------------------------------+ + | Core's CE | /sys/bus/platform/devices/smpro-errmon.*/error_core_ce | Core has CE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | Core's UE | /sys/bus/platform/devices/smpro-errmon.*/error_core_ue | Core has UE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | Memory's CE | /sys/bus/platform/devices/smpro-errmon.*/error_mem_ce | Memory has CE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | Memory's UE | /sys/bus/platform/devices/smpro-errmon.*/error_mem_ue | Memory has UE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | PCIe's CE | /sys/bus/platform/devices/smpro-errmon.*/error_pcie_ce | any PCIe controller has CE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | PCIe's UE | /sys/bus/platform/devices/smpro-errmon.*/error_pcie_ue | any PCIe controller has UE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | Other's CE | /sys/bus/platform/devices/smpro-errmon.*/error_other_ce | any other CE error | + +-------------+---------------------------------------------------------+----------------------------------+ + | Other's UE | /sys/bus/platform/devices/smpro-errmon.*/error_other_ue | any other UE error | + +-------------+---------------------------------------------------------+----------------------------------+ + + UE: Uncorrect-able Error + CE: Correct-able Error + + For details, see section `3.3 Ampere (Vendor-Specific) Error Record Formats, + Altra Family RAS Supplement`. + + +What: /sys/bus/platform/devices/smpro-errmon.*/overflow_[core|mem|pcie|other]_[ce|ue] +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RO) Return the overflow status of each type HW error reported: + + - 0 : No overflow + - 1 : There is an overflow and the oldest HW errors are dropped + + The detail of each sysfs entries is as below: + + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Overflow | Sysfs entry | Description | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Core's CE | /sys/bus/platform/devices/smpro-errmon.*/overflow_core_ce | Core CE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Core's UE | /sys/bus/platform/devices/smpro-errmon.*/overflow_core_ue | Core UE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Memory's CE | /sys/bus/platform/devices/smpro-errmon.*/overflow_mem_ce | Memory CE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Memory's UE | /sys/bus/platform/devices/smpro-errmon.*/overflow_mem_ue | Memory UE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | PCIe's CE | /sys/bus/platform/devices/smpro-errmon.*/overflow_pcie_ce | any PCIe controller CE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | PCIe's UE | /sys/bus/platform/devices/smpro-errmon.*/overflow_pcie_ue | any PCIe controller UE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Other's CE | /sys/bus/platform/devices/smpro-errmon.*/overflow_other_ce| any other CE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + | Other's UE | /sys/bus/platform/devices/smpro-errmon.*/overflow_other_ue| other UE error overflow | + +-------------+-----------------------------------------------------------+---------------------------------------+ + + where: + + - UE: Uncorrect-able Error + - CE: Correct-able Error + +What: /sys/bus/platform/devices/smpro-errmon.*/[error|warn]_[smpro|pmpro] +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RO) Contains the internal firmware error/warning printed as hex format. + + The detail of each sysfs entries is as below: + + +---------------+------------------------------------------------------+--------------------------+ + | Error | Sysfs entry | Description | + +---------------+------------------------------------------------------+--------------------------+ + | SMpro error | /sys/bus/platform/devices/smpro-errmon.*/error_smpro | system has SMpro error | + +---------------+------------------------------------------------------+--------------------------+ + | SMpro warning | /sys/bus/platform/devices/smpro-errmon.*/warn_smpro | system has SMpro warning | + +---------------+------------------------------------------------------+--------------------------+ + | PMpro error | /sys/bus/platform/devices/smpro-errmon.*/error_pmpro | system has PMpro error | + +---------------+------------------------------------------------------+--------------------------+ + | PMpro warning | /sys/bus/platform/devices/smpro-errmon.*/warn_pmpro | system has PMpro warning | + +---------------+------------------------------------------------------+--------------------------+ + + For details, see section `5.10 RAS Internal Error Register Definitions, + Altra Family Soc BMC Interface Specification`. + +What: /sys/bus/platform/devices/smpro-errmon.*/event_[vrd_warn_fault|vrd_hot|dimm_hot] +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RO) Contains the detail information in case of VRD/DIMM warning/hot events + in hex format as below:: + + AAAA + + where: + + - ``AAAA``: The event detail information data + + The detail of each sysfs entries is as below: + + +---------------+---------------------------------------------------------------+---------------------+ + | Event | Sysfs entry | Description | + +---------------+---------------------------------------------------------------+---------------------+ + | VRD HOT | /sys/bus/platform/devices/smpro-errmon.*/event_vrd_hot | VRD Hot | + +---------------+---------------------------------------------------------------+---------------------+ + | VR Warn/Fault | /sys/bus/platform/devices/smpro-errmon.*/event_vrd_warn_fault | VR Warning or Fault | + +---------------+---------------------------------------------------------------+---------------------+ + | DIMM HOT | /sys/bus/platform/devices/smpro-errmon.*/event_dimm_hot | DIMM Hot | + +---------------+---------------------------------------------------------------+---------------------+ + + For more details, see section `5.7 GPI Status Registers, + Altra Family Soc BMC Interface Specification`. + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 358ad56f65245..b9ceee949dab8 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -176,6 +176,18 @@ config SGI_XP this feature will allow for direct communication between SSIs based on a network adapter and DMA messaging. +config SMPRO_ERRMON + tristate "Ampere Computing SMPro error monitor driver" + depends on MFD_SMPRO || COMPILE_TEST + help + Say Y here to get support for the SMpro error monitor function + provided by Ampere Computing's Altra and Altra Max SoCs. Upon + loading, the driver creates sysfs files which can be use to gather + multiple HW error data reported via read and write system calls. + + To compile this driver as a module, say M here. The driver will be + called smpro-errmon. + config CS5535_MFGPT tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support" depends on MFD_CS5535 diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index ac9b3e757ba1d..bbe24d4511a33 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ +obj-$(CONFIG_SMPRO_ERRMON) += smpro-errmon.o obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_GEHC_ACHC) += gehc-achc.o obj-$(CONFIG_HP_ILO) += hpilo.o diff --git a/drivers/misc/smpro-errmon.c b/drivers/misc/smpro-errmon.c new file mode 100644 index 0000000000000..d1431d419aa42 --- /dev/null +++ b/drivers/misc/smpro-errmon.c @@ -0,0 +1,529 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Ampere Computing SoC's SMpro Error Monitoring Driver + * + * Copyright (c) 2022, Ampere Computing LLC + * + */ + +#include +#include +#include +#include +#include + +/* GPI RAS Error Registers */ +#define GPI_RAS_ERR 0x7E + +/* Core and L2C Error Registers */ +#define CORE_CE_ERR_CNT 0x80 +#define CORE_CE_ERR_LEN 0x81 +#define CORE_CE_ERR_DATA 0x82 +#define CORE_UE_ERR_CNT 0x83 +#define CORE_UE_ERR_LEN 0x84 +#define CORE_UE_ERR_DATA 0x85 + +/* Memory Error Registers */ +#define MEM_CE_ERR_CNT 0x90 +#define MEM_CE_ERR_LEN 0x91 +#define MEM_CE_ERR_DATA 0x92 +#define MEM_UE_ERR_CNT 0x93 +#define MEM_UE_ERR_LEN 0x94 +#define MEM_UE_ERR_DATA 0x95 + +/* RAS Error/Warning Registers */ +#define ERR_SMPRO_TYPE 0xA0 +#define ERR_PMPRO_TYPE 0xA1 +#define ERR_SMPRO_INFO_LO 0xA2 +#define ERR_SMPRO_INFO_HI 0xA3 +#define ERR_SMPRO_DATA_LO 0xA4 +#define ERR_SMPRO_DATA_HI 0xA5 +#define WARN_SMPRO_INFO_LO 0xAA +#define WARN_SMPRO_INFO_HI 0xAB +#define ERR_PMPRO_INFO_LO 0xA6 +#define ERR_PMPRO_INFO_HI 0xA7 +#define ERR_PMPRO_DATA_LO 0xA8 +#define ERR_PMPRO_DATA_HI 0xA9 +#define WARN_PMPRO_INFO_LO 0xAC +#define WARN_PMPRO_INFO_HI 0xAD + +/* PCIE Error Registers */ +#define PCIE_CE_ERR_CNT 0xC0 +#define PCIE_CE_ERR_LEN 0xC1 +#define PCIE_CE_ERR_DATA 0xC2 +#define PCIE_UE_ERR_CNT 0xC3 +#define PCIE_UE_ERR_LEN 0xC4 +#define PCIE_UE_ERR_DATA 0xC5 + +/* Other Error Registers */ +#define OTHER_CE_ERR_CNT 0xD0 +#define OTHER_CE_ERR_LEN 0xD1 +#define OTHER_CE_ERR_DATA 0xD2 +#define OTHER_UE_ERR_CNT 0xD8 +#define OTHER_UE_ERR_LEN 0xD9 +#define OTHER_UE_ERR_DATA 0xDA + +/* Event Data Registers */ +#define VRD_WARN_FAULT_EVENT_DATA 0x78 +#define VRD_HOT_EVENT_DATA 0x79 +#define DIMM_HOT_EVENT_DATA 0x7A + +#define MAX_READ_BLOCK_LENGTH 48 + +#define RAS_SMPRO_ERR 0 +#define RAS_PMPRO_ERR 1 + +enum RAS_48BYTES_ERR_TYPES { + CORE_CE_ERR, + CORE_UE_ERR, + MEM_CE_ERR, + MEM_UE_ERR, + PCIE_CE_ERR, + PCIE_UE_ERR, + OTHER_CE_ERR, + OTHER_UE_ERR, + NUM_48BYTES_ERR_TYPE, +}; + +struct smpro_error_hdr { + u8 count; /* Number of the RAS errors */ + u8 len; /* Number of data bytes */ + u8 data; /* Start of 48-byte data */ + u8 max_cnt; /* Max num of errors */ +}; + +/* + * Included Address of registers to get Count, Length of data and Data + * of the 48 bytes error data + */ +static struct smpro_error_hdr smpro_error_table[] = { + [CORE_CE_ERR] = { + .count = CORE_CE_ERR_CNT, + .len = CORE_CE_ERR_LEN, + .data = CORE_CE_ERR_DATA, + .max_cnt = 32 + }, + [CORE_UE_ERR] = { + .count = CORE_UE_ERR_CNT, + .len = CORE_UE_ERR_LEN, + .data = CORE_UE_ERR_DATA, + .max_cnt = 32 + }, + [MEM_CE_ERR] = { + .count = MEM_CE_ERR_CNT, + .len = MEM_CE_ERR_LEN, + .data = MEM_CE_ERR_DATA, + .max_cnt = 16 + }, + [MEM_UE_ERR] = { + .count = MEM_UE_ERR_CNT, + .len = MEM_UE_ERR_LEN, + .data = MEM_UE_ERR_DATA, + .max_cnt = 16 + }, + [PCIE_CE_ERR] = { + .count = PCIE_CE_ERR_CNT, + .len = PCIE_CE_ERR_LEN, + .data = PCIE_CE_ERR_DATA, + .max_cnt = 96 + }, + [PCIE_UE_ERR] = { + .count = PCIE_UE_ERR_CNT, + .len = PCIE_UE_ERR_LEN, + .data = PCIE_UE_ERR_DATA, + .max_cnt = 96 + }, + [OTHER_CE_ERR] = { + .count = OTHER_CE_ERR_CNT, + .len = OTHER_CE_ERR_LEN, + .data = OTHER_CE_ERR_DATA, + .max_cnt = 8 + }, + [OTHER_UE_ERR] = { + .count = OTHER_UE_ERR_CNT, + .len = OTHER_UE_ERR_LEN, + .data = OTHER_UE_ERR_DATA, + .max_cnt = 8 + }, +}; + +/* + * List of SCP registers which are used to get + * one type of RAS Internal errors. + */ +struct smpro_int_error_hdr { + u8 type; + u8 info_l; + u8 info_h; + u8 data_l; + u8 data_h; + u8 warn_l; + u8 warn_h; +}; + +static struct smpro_int_error_hdr list_smpro_int_error_hdr[] = { + [RAS_SMPRO_ERR] = { + .type = ERR_SMPRO_TYPE, + .info_l = ERR_SMPRO_INFO_LO, + .info_h = ERR_SMPRO_INFO_HI, + .data_l = ERR_SMPRO_DATA_LO, + .data_h = ERR_SMPRO_DATA_HI, + .warn_l = WARN_SMPRO_INFO_LO, + .warn_h = WARN_SMPRO_INFO_HI, + }, + [RAS_PMPRO_ERR] = { + .type = ERR_PMPRO_TYPE, + .info_l = ERR_PMPRO_INFO_LO, + .info_h = ERR_PMPRO_INFO_HI, + .data_l = ERR_PMPRO_DATA_LO, + .data_h = ERR_PMPRO_DATA_HI, + .warn_l = WARN_PMPRO_INFO_LO, + .warn_h = WARN_PMPRO_INFO_HI, + }, +}; + +struct smpro_errmon { + struct regmap *regmap; +}; + +enum EVENT_TYPES { + VRD_WARN_FAULT_EVENT, + VRD_HOT_EVENT, + DIMM_HOT_EVENT, + NUM_EVENTS_TYPE, +}; + +/* Included Address of event source and data registers */ +static u8 smpro_event_table[NUM_EVENTS_TYPE] = { + VRD_WARN_FAULT_EVENT_DATA, + VRD_HOT_EVENT_DATA, + DIMM_HOT_EVENT_DATA, +}; + +static ssize_t smpro_event_data_read(struct device *dev, + struct device_attribute *da, char *buf, + int channel) +{ + struct smpro_errmon *errmon = dev_get_drvdata(dev); + s32 event_data; + int ret; + + ret = regmap_read(errmon->regmap, smpro_event_table[channel], &event_data); + if (ret) + return ret; + /* Clear event after read */ + if (event_data != 0) + regmap_write(errmon->regmap, smpro_event_table[channel], event_data); + + return sysfs_emit(buf, "%04x\n", event_data); +} + +static ssize_t smpro_overflow_data_read(struct device *dev, struct device_attribute *da, + char *buf, int channel) +{ + struct smpro_errmon *errmon = dev_get_drvdata(dev); + struct smpro_error_hdr *err_info; + s32 err_count; + int ret; + + err_info = &smpro_error_table[channel]; + + ret = regmap_read(errmon->regmap, err_info->count, &err_count); + if (ret) + return ret; + + /* Bit 8 indicates the overflow status */ + return sysfs_emit(buf, "%d\n", (err_count & BIT(8)) ? 1 : 0); +} + +static ssize_t smpro_error_data_read(struct device *dev, struct device_attribute *da, + char *buf, int channel) +{ + struct smpro_errmon *errmon = dev_get_drvdata(dev); + unsigned char err_data[MAX_READ_BLOCK_LENGTH]; + struct smpro_error_hdr *err_info; + s32 err_count, err_length; + int ret; + + err_info = &smpro_error_table[channel]; + + ret = regmap_read(errmon->regmap, err_info->count, &err_count); + /* Error count is the low byte */ + err_count &= 0xff; + if (ret || !err_count || err_count > err_info->max_cnt) + return ret; + + ret = regmap_read(errmon->regmap, err_info->len, &err_length); + if (ret || err_length <= 0) + return ret; + + if (err_length > MAX_READ_BLOCK_LENGTH) + err_length = MAX_READ_BLOCK_LENGTH; + + memset(err_data, 0x00, MAX_READ_BLOCK_LENGTH); + ret = regmap_noinc_read(errmon->regmap, err_info->data, err_data, err_length); + if (ret < 0) + return ret; + + /* clear the error */ + ret = regmap_write(errmon->regmap, err_info->count, 0x100); + if (ret) + return ret; + /* + * The output of Core/Memory/PCIe/Others UE/CE errors follows the format + * specified in section 5.8.1 CE/UE Error Data record in + * Altra SOC BMC Interface specification. + */ + return sysfs_emit(buf, "%*phN\n", MAX_READ_BLOCK_LENGTH, err_data); +} + +/* + * Output format: + * <4-byte hex value of error info><4-byte hex value of error extensive data> + * Where: + * + error info : The error information + * + error data : Extensive data (32 bits) + * Reference to section 5.10 RAS Internal Error Register Definition in + * Altra SOC BMC Interface specification + */ +static ssize_t smpro_internal_err_read(struct device *dev, struct device_attribute *da, + char *buf, int channel) +{ + struct smpro_errmon *errmon = dev_get_drvdata(dev); + struct smpro_int_error_hdr *err_info; + unsigned int err[4] = { 0 }; + unsigned int err_type; + unsigned int val; + int ret; + + /* read error status */ + ret = regmap_read(errmon->regmap, GPI_RAS_ERR, &val); + if (ret) + return ret; + + if ((channel == RAS_SMPRO_ERR && !(val & BIT(0))) || + (channel == RAS_PMPRO_ERR && !(val & BIT(1)))) + return 0; + + err_info = &list_smpro_int_error_hdr[channel]; + ret = regmap_read(errmon->regmap, err_info->type, &val); + if (ret) + return ret; + + err_type = (val & BIT(1)) ? BIT(1) : + (val & BIT(2)) ? BIT(2) : 0; + + if (!err_type) + return 0; + + ret = regmap_read(errmon->regmap, err_info->info_l, err + 1); + if (ret) + return ret; + + ret = regmap_read(errmon->regmap, err_info->info_h, err); + if (ret) + return ret; + + if (err_type & BIT(2)) { + /* Error with data type */ + ret = regmap_read(errmon->regmap, err_info->data_l, err + 3); + if (ret) + return ret; + + ret = regmap_read(errmon->regmap, err_info->data_h, err + 2); + if (ret) + return ret; + } + + /* clear the read errors */ + ret = regmap_write(errmon->regmap, err_info->type, err_type); + if (ret) + return ret; + + return sysfs_emit(buf, "%*phN\n", (int)sizeof(err), err); +} + +/* + * Output format: + * <4-byte hex value of warining info> + * Reference to section 5.10 RAS Internal Error Register Definition in + * Altra SOC BMC Interface specification + */ +static ssize_t smpro_internal_warn_read(struct device *dev, struct device_attribute *da, + char *buf, int channel) +{ + struct smpro_errmon *errmon = dev_get_drvdata(dev); + struct smpro_int_error_hdr *err_info; + unsigned int warn[2] = { 0 }; + unsigned int val; + int ret; + + /* read error status */ + ret = regmap_read(errmon->regmap, GPI_RAS_ERR, &val); + if (ret) + return ret; + + if ((channel == RAS_SMPRO_ERR && !(val & BIT(0))) || + (channel == RAS_PMPRO_ERR && !(val & BIT(1)))) + return 0; + + err_info = &list_smpro_int_error_hdr[channel]; + ret = regmap_read(errmon->regmap, err_info->type, &val); + if (ret) + return ret; + + if (!(val & BIT(0))) + return 0; + + ret = regmap_read(errmon->regmap, err_info->warn_l, warn + 1); + if (ret) + return ret; + + ret = regmap_read(errmon->regmap, err_info->warn_h, warn); + if (ret) + return ret; + + /* clear the warning */ + ret = regmap_write(errmon->regmap, err_info->type, BIT(0)); + if (ret) + return ret; + + return sysfs_emit(buf, "%*phN\n", (int)sizeof(warn), warn); +} + +#define ERROR_OVERFLOW_RO(_error, _index) \ + static ssize_t overflow_##_error##_show(struct device *dev, \ + struct device_attribute *da, \ + char *buf) \ + { \ + return smpro_overflow_data_read(dev, da, buf, _index); \ + } \ + static DEVICE_ATTR_RO(overflow_##_error) + +ERROR_OVERFLOW_RO(core_ce, CORE_CE_ERR); +ERROR_OVERFLOW_RO(core_ue, CORE_UE_ERR); +ERROR_OVERFLOW_RO(mem_ce, MEM_CE_ERR); +ERROR_OVERFLOW_RO(mem_ue, MEM_UE_ERR); +ERROR_OVERFLOW_RO(pcie_ce, PCIE_CE_ERR); +ERROR_OVERFLOW_RO(pcie_ue, PCIE_UE_ERR); +ERROR_OVERFLOW_RO(other_ce, OTHER_CE_ERR); +ERROR_OVERFLOW_RO(other_ue, OTHER_UE_ERR); + +#define ERROR_RO(_error, _index) \ + static ssize_t error_##_error##_show(struct device *dev, \ + struct device_attribute *da, \ + char *buf) \ + { \ + return smpro_error_data_read(dev, da, buf, _index); \ + } \ + static DEVICE_ATTR_RO(error_##_error) + +ERROR_RO(core_ce, CORE_CE_ERR); +ERROR_RO(core_ue, CORE_UE_ERR); +ERROR_RO(mem_ce, MEM_CE_ERR); +ERROR_RO(mem_ue, MEM_UE_ERR); +ERROR_RO(pcie_ce, PCIE_CE_ERR); +ERROR_RO(pcie_ue, PCIE_UE_ERR); +ERROR_RO(other_ce, OTHER_CE_ERR); +ERROR_RO(other_ue, OTHER_UE_ERR); + +static ssize_t error_smpro_show(struct device *dev, struct device_attribute *da, char *buf) +{ + return smpro_internal_err_read(dev, da, buf, RAS_SMPRO_ERR); +} +static DEVICE_ATTR_RO(error_smpro); + +static ssize_t error_pmpro_show(struct device *dev, struct device_attribute *da, char *buf) +{ + return smpro_internal_err_read(dev, da, buf, RAS_PMPRO_ERR); +} +static DEVICE_ATTR_RO(error_pmpro); + +static ssize_t warn_smpro_show(struct device *dev, struct device_attribute *da, char *buf) +{ + return smpro_internal_warn_read(dev, da, buf, RAS_SMPRO_ERR); +} +static DEVICE_ATTR_RO(warn_smpro); + +static ssize_t warn_pmpro_show(struct device *dev, struct device_attribute *da, char *buf) +{ + return smpro_internal_warn_read(dev, da, buf, RAS_PMPRO_ERR); +} +static DEVICE_ATTR_RO(warn_pmpro); + +#define EVENT_RO(_event, _index) \ + static ssize_t event_##_event##_show(struct device *dev, \ + struct device_attribute *da, \ + char *buf) \ + { \ + return smpro_event_data_read(dev, da, buf, _index); \ + } \ + static DEVICE_ATTR_RO(event_##_event) + +EVENT_RO(vrd_warn_fault, VRD_WARN_FAULT_EVENT); +EVENT_RO(vrd_hot, VRD_HOT_EVENT); +EVENT_RO(dimm_hot, DIMM_HOT_EVENT); + +static struct attribute *smpro_errmon_attrs[] = { + &dev_attr_overflow_core_ce.attr, + &dev_attr_overflow_core_ue.attr, + &dev_attr_overflow_mem_ce.attr, + &dev_attr_overflow_mem_ue.attr, + &dev_attr_overflow_pcie_ce.attr, + &dev_attr_overflow_pcie_ue.attr, + &dev_attr_overflow_other_ce.attr, + &dev_attr_overflow_other_ue.attr, + &dev_attr_error_core_ce.attr, + &dev_attr_error_core_ue.attr, + &dev_attr_error_mem_ce.attr, + &dev_attr_error_mem_ue.attr, + &dev_attr_error_pcie_ce.attr, + &dev_attr_error_pcie_ue.attr, + &dev_attr_error_other_ce.attr, + &dev_attr_error_other_ue.attr, + &dev_attr_error_smpro.attr, + &dev_attr_error_pmpro.attr, + &dev_attr_warn_smpro.attr, + &dev_attr_warn_pmpro.attr, + &dev_attr_event_vrd_warn_fault.attr, + &dev_attr_event_vrd_hot.attr, + &dev_attr_event_dimm_hot.attr, + NULL +}; + +ATTRIBUTE_GROUPS(smpro_errmon); + +static int smpro_errmon_probe(struct platform_device *pdev) +{ + struct smpro_errmon *errmon; + + errmon = devm_kzalloc(&pdev->dev, sizeof(struct smpro_errmon), GFP_KERNEL); + if (!errmon) + return -ENOMEM; + + platform_set_drvdata(pdev, errmon); + + errmon->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!errmon->regmap) + return -ENODEV; + + return 0; +} + +static struct platform_driver smpro_errmon_driver = { + .probe = smpro_errmon_probe, + .driver = { + .name = "smpro-errmon", + .dev_groups = smpro_errmon_groups, + }, +}; + +module_platform_driver(smpro_errmon_driver); + +MODULE_AUTHOR("Tung Nguyen "); +MODULE_AUTHOR("Thinh Pham "); +MODULE_AUTHOR("Hoang Nguyen "); +MODULE_AUTHOR("Thu Nguyen "); +MODULE_AUTHOR("Quan Nguyen "); +MODULE_DESCRIPTION("Ampere Altra SMpro driver"); +MODULE_LICENSE("GPL"); -- GitLab From 763dc90e9a4332f82ad43c866c6878742b15d4ab Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Mon, 31 Oct 2022 09:44:42 +0700 Subject: [PATCH 0475/1480] misc: smpro-misc: Add Ampere's Altra SMpro misc driver Add driver support for accessing various information reported by Ampere's SMpro co-processor such as Boot Progress and other miscellaneous data. Signed-off-by: Quan Nguyen Link: https://lore.kernel.org/r/20221031024442.2490881-4-quan@os.amperecomputing.com Signed-off-by: Greg Kroah-Hartman --- .../sysfs-bus-platform-devices-ampere-smpro | 48 ++++++ drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile | 1 + drivers/misc/smpro-misc.c | 145 ++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 drivers/misc/smpro-misc.c diff --git a/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro b/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro index 2b84dc8c3149d..ca93c215ef995 100644 --- a/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro +++ b/Documentation/ABI/testing/sysfs-bus-platform-devices-ampere-smpro @@ -262,3 +262,51 @@ Description: For more details, see section `5.7 GPI Status Registers, Altra Family Soc BMC Interface Specification`. +What: /sys/bus/platform/devices/smpro-misc.*/boot_progress +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RO) Contains the boot stages information in hex as format below:: + + AABBCCCCCCCC + + where: + + - ``AA`` : The boot stages + + - 00: SMpro firmware booting + - 01: PMpro firmware booting + - 02: ATF BL1 firmware booting + - 03: DDR initialization + - 04: DDR training report status + - 05: ATF BL2 firmware booting + - 06: ATF BL31 firmware booting + - 07: ATF BL32 firmware booting + - 08: UEFI firmware booting + - 09: OS booting + + - ``BB`` : Boot status + + - 00: Not started + - 01: Started + - 02: Completed without error + - 03: Failed. + + - ``CCCCCCCC``: Boot status information defined for each boot stages + + For details, see section `5.11 Boot Stage Register Definitions` + and section `6. Processor Boot Progress Codes, Altra Family Soc BMC + Interface Specification`. + + +What: /sys/bus/platform/devices/smpro-misc*/soc_power_limit +KernelVersion: 6.1 +Contact: Quan Nguyen +Description: + (RW) Contains the desired SoC power limit in Watt. + Writes to this sysfs set the desired SoC power limit (W). + Reads from this register return the current SoC power limit (W). + The value ranges: + + - Minimum: 120 W + - Maximum: Socket TDP power diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b9ceee949dab8..9947b7892bd5a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -188,6 +188,16 @@ config SMPRO_ERRMON To compile this driver as a module, say M here. The driver will be called smpro-errmon. +config SMPRO_MISC + tristate "Ampere Computing SMPro miscellaneous driver" + depends on MFD_SMPRO || COMPILE_TEST + help + Say Y here to get support for the SMpro error miscellalenous function + provided by Ampere Computing's Altra and Altra Max SoCs. + + To compile this driver as a module, say M here. The driver will be + called smpro-misc. + config CS5535_MFGPT tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support" depends on MFD_CS5535 diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index bbe24d4511a33..87b54a4a44224 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_SMPRO_ERRMON) += smpro-errmon.o +obj-$(CONFIG_SMPRO_MISC) += smpro-misc.o obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_GEHC_ACHC) += gehc-achc.o obj-$(CONFIG_HP_ILO) += hpilo.o diff --git a/drivers/misc/smpro-misc.c b/drivers/misc/smpro-misc.c new file mode 100644 index 0000000000000..6c427141e51b4 --- /dev/null +++ b/drivers/misc/smpro-misc.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Ampere Computing SoC's SMpro Misc Driver + * + * Copyright (c) 2022, Ampere Computing LLC + */ +#include +#include +#include +#include + +/* Boot Stage/Progress Registers */ +#define BOOTSTAGE 0xB0 +#define BOOTSTAGE_LO 0xB1 +#define CUR_BOOTSTAGE 0xB2 +#define BOOTSTAGE_HI 0xB3 + +/* SOC State Registers */ +#define SOC_POWER_LIMIT 0xE5 + +struct smpro_misc { + struct regmap *regmap; +}; + +static ssize_t boot_progress_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct smpro_misc *misc = dev_get_drvdata(dev); + u16 boot_progress[3] = { 0 }; + u32 bootstage; + u8 boot_stage; + u8 cur_stage; + u32 reg_lo; + u32 reg; + int ret; + + /* Read current boot stage */ + ret = regmap_read(misc->regmap, CUR_BOOTSTAGE, ®); + if (ret) + return ret; + + cur_stage = reg & 0xff; + + ret = regmap_read(misc->regmap, BOOTSTAGE, &bootstage); + if (ret) + return ret; + + boot_stage = (bootstage >> 8) & 0xff; + + if (boot_stage > cur_stage) + return -EINVAL; + + ret = regmap_read(misc->regmap, BOOTSTAGE_LO, ®_lo); + if (!ret) + ret = regmap_read(misc->regmap, BOOTSTAGE_HI, ®); + if (ret) + return ret; + + /* Firmware to report new boot stage next time */ + if (boot_stage < cur_stage) { + ret = regmap_write(misc->regmap, BOOTSTAGE, ((bootstage & 0xff00) | 0x1)); + if (ret) + return ret; + } + + boot_progress[0] = bootstage; + boot_progress[1] = swab16(reg); + boot_progress[2] = swab16(reg_lo); + + return sysfs_emit(buf, "%*phN\n", (int)sizeof(boot_progress), boot_progress); +} + +static DEVICE_ATTR_RO(boot_progress); + +static ssize_t soc_power_limit_show(struct device *dev, struct device_attribute *da, char *buf) +{ + struct smpro_misc *misc = dev_get_drvdata(dev); + unsigned int value; + int ret; + + ret = regmap_read(misc->regmap, SOC_POWER_LIMIT, &value); + if (ret) + return ret; + + return sysfs_emit(buf, "%d\n", value); +} + +static ssize_t soc_power_limit_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct smpro_misc *misc = dev_get_drvdata(dev); + unsigned long val; + s32 ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + ret = regmap_write(misc->regmap, SOC_POWER_LIMIT, (unsigned int)val); + if (ret) + return -EPROTO; + + return count; +} + +static DEVICE_ATTR_RW(soc_power_limit); + +static struct attribute *smpro_misc_attrs[] = { + &dev_attr_boot_progress.attr, + &dev_attr_soc_power_limit.attr, + NULL +}; + +ATTRIBUTE_GROUPS(smpro_misc); + +static int smpro_misc_probe(struct platform_device *pdev) +{ + struct smpro_misc *misc; + + misc = devm_kzalloc(&pdev->dev, sizeof(struct smpro_misc), GFP_KERNEL); + if (!misc) + return -ENOMEM; + + platform_set_drvdata(pdev, misc); + + misc->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!misc->regmap) + return -ENODEV; + + return 0; +} + +static struct platform_driver smpro_misc_driver = { + .probe = smpro_misc_probe, + .driver = { + .name = "smpro-misc", + .dev_groups = smpro_misc_groups, + }, +}; + +module_platform_driver(smpro_misc_driver); + +MODULE_AUTHOR("Tung Nguyen "); +MODULE_AUTHOR("Quan Nguyen "); +MODULE_DESCRIPTION("Ampere Altra SMpro Misc driver"); +MODULE_LICENSE("GPL"); -- GitLab From 0d4a030b3db1b53498f1c1ae243677fa0dd2e7ce Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 1 Nov 2022 22:13:59 +0100 Subject: [PATCH 0476/1480] greybus: svc: Use kstrtobool() instead of strtobool() strtobool() is the same as kstrtobool(). However, the latter is more used within the kernel. In order to remove strtobool() and slightly simplify kstrtox.h, switch to the other function name. While at it, include the corresponding header file () Signed-off-by: Christophe JAILLET Reviewed-by: Johan Hovold Reviewed-by: Alex Elder Link: https://lore.kernel.org/r/ebf1e6988a53a455990230a37cf759ee542ea7ec.1667336095.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/greybus/svc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/greybus/svc.c b/drivers/greybus/svc.c index 56d2b44d6fefc..16cced80867a6 100644 --- a/drivers/greybus/svc.c +++ b/drivers/greybus/svc.c @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -83,7 +84,7 @@ static ssize_t watchdog_store(struct device *dev, int retval; bool user_request; - retval = strtobool(buf, &user_request); + retval = kstrtobool(buf, &user_request); if (retval) return retval; -- GitLab From d3d76fbde1c456a6d19991baa99ea8c2d6e6696f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 3 Nov 2022 16:24:07 +0100 Subject: [PATCH 0477/1480] kernel/ksysfs.c: export kernel cpu byteorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certain files in procfs are formatted in byteorder-dependent formats. For example the IP addresses in /proc/net/udp. When using emulation like qemu-user, applications are not guaranteed to be using the same byteorder as the kernel. Therefore the kernel needs to provide a way for applications to discover the byteorder used in API-filesystems. Using systemcalls is not enough because these are intercepted and translated by the emulation. Also this makes it easier for non-compiled applications like shellscripts to discover the byteorder. Signed-off-by: Thomas Weißschuh Link: https://lore.kernel.org/r/20221103152407.3348-1-linux@weissschuh.net Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-kernel-cpu_byteorder | 12 ++++++++++++ kernel/ksysfs.c | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-kernel-cpu_byteorder diff --git a/Documentation/ABI/testing/sysfs-kernel-cpu_byteorder b/Documentation/ABI/testing/sysfs-kernel-cpu_byteorder new file mode 100644 index 0000000000000..f0e6ac1b53566 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-cpu_byteorder @@ -0,0 +1,12 @@ +What: /sys/kernel/cpu_byteorder +Date: February 2023 +KernelVersion: 6.2 +Contact: Thomas Weißschuh +Description: + The endianness of the running kernel. + + Access: Read + + Valid values: + "little", "big" +Users: util-linux diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 65dba9076f312..2df00b789b907 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -6,6 +6,7 @@ * Copyright (C) 2004 Kay Sievers */ +#include #include #include #include @@ -20,6 +21,14 @@ #include /* rcu_expedited and rcu_normal */ +#if defined(__LITTLE_ENDIAN) +#define CPU_BYTEORDER_STRING "little" +#elif defined(__BIG_ENDIAN) +#define CPU_BYTEORDER_STRING "big" +#else +#error Unknown byteorder +#endif + #define KERNEL_ATTR_RO(_name) \ static struct kobj_attribute _name##_attr = __ATTR_RO(_name) @@ -34,6 +43,14 @@ static ssize_t uevent_seqnum_show(struct kobject *kobj, } KERNEL_ATTR_RO(uevent_seqnum); +/* cpu byteorder */ +static ssize_t cpu_byteorder_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%s\n", CPU_BYTEORDER_STRING); +} +KERNEL_ATTR_RO(cpu_byteorder); + #ifdef CONFIG_UEVENT_HELPER /* uevent helper program, used during early boot */ static ssize_t uevent_helper_show(struct kobject *kobj, @@ -215,6 +232,7 @@ EXPORT_SYMBOL_GPL(kernel_kobj); static struct attribute * kernel_attrs[] = { &fscaps_attr.attr, &uevent_seqnum_attr.attr, + &cpu_byteorder_attr.attr, #ifdef CONFIG_UEVENT_HELPER &uevent_helper_attr.attr, #endif -- GitLab From 9b351be25360c5cedfb98b88d6dfd89327849e52 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sat, 22 Oct 2022 16:56:36 -0600 Subject: [PATCH 0478/1480] vmlinux.lds.h: add BOUNDED_SECTION* macros vmlinux.lds.h has ~45 occurrences of this general pattern: __start_foo = .; KEEP(*(foo)) __stop_foo = .; Reduce this pattern to a (group of 4) macros, and use them to reduce linecount. This was inspired by the codetag patchset. no functional change. CC: Suren Baghdasaryan CC: Kent Overstreet Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20221022225637.1406715-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 219 +++++++++++------------------- 1 file changed, 79 insertions(+), 140 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index c15de165ec8ff..9f6352171f886 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -193,100 +193,99 @@ # endif #endif +#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _s_, _e_) \ + _s_##_label_ = .; \ + KEEP(*(_sec_)) \ + _e_##_label_ = .; + +#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _s_, _e_) \ + _label_##_s_ = .; \ + KEEP(*(_sec_)) \ + _label_##_e_ = .; + +#define BOUNDED_SECTION_BY(_sec_, _label_) \ + BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop) + +#define BOUNDED_SECTION(_sec) BOUNDED_SECTION_BY(_sec, _sec) + #ifdef CONFIG_TRACE_BRANCH_PROFILING -#define LIKELY_PROFILE() __start_annotated_branch_profile = .; \ - KEEP(*(_ftrace_annotated_branch)) \ - __stop_annotated_branch_profile = .; +#define LIKELY_PROFILE() \ + BOUNDED_SECTION_BY(_ftrace_annotated_branch, _annotated_branch_profile) #else #define LIKELY_PROFILE() #endif #ifdef CONFIG_PROFILE_ALL_BRANCHES -#define BRANCH_PROFILE() __start_branch_profile = .; \ - KEEP(*(_ftrace_branch)) \ - __stop_branch_profile = .; +#define BRANCH_PROFILE() \ + BOUNDED_SECTION_BY(_ftrace_branch, _branch_profile) #else #define BRANCH_PROFILE() #endif #ifdef CONFIG_KPROBES -#define KPROBE_BLACKLIST() . = ALIGN(8); \ - __start_kprobe_blacklist = .; \ - KEEP(*(_kprobe_blacklist)) \ - __stop_kprobe_blacklist = .; +#define KPROBE_BLACKLIST() \ + . = ALIGN(8); \ + BOUNDED_SECTION(_kprobe_blacklist) #else #define KPROBE_BLACKLIST() #endif #ifdef CONFIG_FUNCTION_ERROR_INJECTION -#define ERROR_INJECT_WHITELIST() STRUCT_ALIGN(); \ - __start_error_injection_whitelist = .; \ - KEEP(*(_error_injection_whitelist)) \ - __stop_error_injection_whitelist = .; +#define ERROR_INJECT_WHITELIST() \ + STRUCT_ALIGN(); \ + BOUNDED_SECTION(_error_injection_whitelist) #else #define ERROR_INJECT_WHITELIST() #endif #ifdef CONFIG_EVENT_TRACING -#define FTRACE_EVENTS() . = ALIGN(8); \ - __start_ftrace_events = .; \ - KEEP(*(_ftrace_events)) \ - __stop_ftrace_events = .; \ - __start_ftrace_eval_maps = .; \ - KEEP(*(_ftrace_eval_map)) \ - __stop_ftrace_eval_maps = .; +#define FTRACE_EVENTS() \ + . = ALIGN(8); \ + BOUNDED_SECTION(_ftrace_events) \ + BOUNDED_SECTION_BY(_ftrace_eval_map, _ftrace_eval_maps) #else #define FTRACE_EVENTS() #endif #ifdef CONFIG_TRACING -#define TRACE_PRINTKS() __start___trace_bprintk_fmt = .; \ - KEEP(*(__trace_printk_fmt)) /* Trace_printk fmt' pointer */ \ - __stop___trace_bprintk_fmt = .; -#define TRACEPOINT_STR() __start___tracepoint_str = .; \ - KEEP(*(__tracepoint_str)) /* Trace_printk fmt' pointer */ \ - __stop___tracepoint_str = .; +#define TRACE_PRINTKS() BOUNDED_SECTION_BY(__trace_printk_fmt, ___trace_bprintk_fmt) +#define TRACEPOINT_STR() BOUNDED_SECTION_BY(__tracepoint_str, ___tracepoint_str) #else #define TRACE_PRINTKS() #define TRACEPOINT_STR() #endif #ifdef CONFIG_FTRACE_SYSCALLS -#define TRACE_SYSCALLS() . = ALIGN(8); \ - __start_syscalls_metadata = .; \ - KEEP(*(__syscalls_metadata)) \ - __stop_syscalls_metadata = .; +#define TRACE_SYSCALLS() \ + . = ALIGN(8); \ + BOUNDED_SECTION_BY(__syscalls_metadata, _syscalls_metadata) #else #define TRACE_SYSCALLS() #endif #ifdef CONFIG_BPF_EVENTS -#define BPF_RAW_TP() STRUCT_ALIGN(); \ - __start__bpf_raw_tp = .; \ - KEEP(*(__bpf_raw_tp_map)) \ - __stop__bpf_raw_tp = .; +#define BPF_RAW_TP() STRUCT_ALIGN(); \ + BOUNDED_SECTION_BY(__bpf_raw_tp_map, __bpf_raw_tp) #else #define BPF_RAW_TP() #endif #ifdef CONFIG_SERIAL_EARLYCON -#define EARLYCON_TABLE() . = ALIGN(8); \ - __earlycon_table = .; \ - KEEP(*(__earlycon_table)) \ - __earlycon_table_end = .; +#define EARLYCON_TABLE() \ + . = ALIGN(8); \ + BOUNDED_SECTION_POST_LABEL(__earlycon_table, __earlycon_table, , _end) #else #define EARLYCON_TABLE() #endif #ifdef CONFIG_SECURITY -#define LSM_TABLE() . = ALIGN(8); \ - __start_lsm_info = .; \ - KEEP(*(.lsm_info.init)) \ - __end_lsm_info = .; -#define EARLY_LSM_TABLE() . = ALIGN(8); \ - __start_early_lsm_info = .; \ - KEEP(*(.early_lsm_info.init)) \ - __end_early_lsm_info = .; +#define LSM_TABLE() \ + . = ALIGN(8); \ + BOUNDED_SECTION_PRE_LABEL(.lsm_info.init, _lsm_info, __start, __end) + +#define EARLY_LSM_TABLE() \ + . = ALIGN(8); \ + BOUNDED_SECTION_PRE_LABEL(.early_lsm_info.init, _early_lsm_info, __start, __end) #else #define LSM_TABLE() #define EARLY_LSM_TABLE() @@ -312,9 +311,8 @@ #ifdef CONFIG_ACPI #define ACPI_PROBE_TABLE(name) \ . = ALIGN(8); \ - __##name##_acpi_probe_table = .; \ - KEEP(*(__##name##_acpi_probe_table)) \ - __##name##_acpi_probe_table_end = .; + BOUNDED_SECTION_POST_LABEL(__##name##_acpi_probe_table, \ + __##name##_acpi_probe_table,, _end) #else #define ACPI_PROBE_TABLE(name) #endif @@ -322,9 +320,8 @@ #ifdef CONFIG_THERMAL #define THERMAL_TABLE(name) \ . = ALIGN(8); \ - __##name##_thermal_table = .; \ - KEEP(*(__##name##_thermal_table)) \ - __##name##_thermal_table_end = .; + BOUNDED_SECTION_POST_LABEL(__##name##_thermal_table, \ + __##name##_thermal_table,, _end) #else #define THERMAL_TABLE(name) #endif @@ -353,12 +350,8 @@ *(__tracepoints) \ /* implement dynamic printk debug */ \ . = ALIGN(8); \ - __start___dyndbg_classes = .; \ - KEEP(*(__dyndbg_classes)) \ - __stop___dyndbg_classes = .; \ - __start___dyndbg = .; \ - KEEP(*(__dyndbg)) \ - __stop___dyndbg = .; \ + BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes) \ + BOUNDED_SECTION_BY(__dyndbg, ___dyndbg) \ LIKELY_PROFILE() \ BRANCH_PROFILE() \ TRACE_PRINTKS() \ @@ -401,19 +394,13 @@ #define JUMP_TABLE_DATA \ . = ALIGN(8); \ - __start___jump_table = .; \ - KEEP(*(__jump_table)) \ - __stop___jump_table = .; + BOUNDED_SECTION_BY(__jump_table, ___jump_table) #ifdef CONFIG_HAVE_STATIC_CALL_INLINE #define STATIC_CALL_DATA \ . = ALIGN(8); \ - __start_static_call_sites = .; \ - KEEP(*(.static_call_sites)) \ - __stop_static_call_sites = .; \ - __start_static_call_tramp_key = .; \ - KEEP(*(.static_call_tramp_key)) \ - __stop_static_call_tramp_key = .; + BOUNDED_SECTION_BY(.static_call_sites, _static_call_sites) \ + BOUNDED_SECTION_BY(.static_call_tramp_key, _static_call_tramp_key) #else #define STATIC_CALL_DATA #endif @@ -439,9 +426,7 @@ #ifdef CONFIG_ARCH_USES_CFI_TRAPS #define KCFI_TRAPS \ __kcfi_traps : AT(ADDR(__kcfi_traps) - LOAD_OFFSET) { \ - __start___kcfi_traps = .; \ - KEEP(*(.kcfi_traps)) \ - __stop___kcfi_traps = .; \ + BOUNDED_SECTION_BY(.kcfi_traps, ___kcfi_traps) \ } #else #define KCFI_TRAPS @@ -459,9 +444,7 @@ SCHED_DATA \ RO_AFTER_INIT_DATA /* Read only after init */ \ . = ALIGN(8); \ - __start___tracepoints_ptrs = .; \ - KEEP(*(__tracepoints_ptrs)) /* Tracepoints: pointer array */ \ - __stop___tracepoints_ptrs = .; \ + BOUNDED_SECTION_BY(__tracepoints_ptrs, ___tracepoints_ptrs) \ *(__tracepoints_strings)/* Tracepoints: strings */ \ } \ \ @@ -471,30 +454,14 @@ \ /* PCI quirks */ \ .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ - __start_pci_fixups_early = .; \ - KEEP(*(.pci_fixup_early)) \ - __end_pci_fixups_early = .; \ - __start_pci_fixups_header = .; \ - KEEP(*(.pci_fixup_header)) \ - __end_pci_fixups_header = .; \ - __start_pci_fixups_final = .; \ - KEEP(*(.pci_fixup_final)) \ - __end_pci_fixups_final = .; \ - __start_pci_fixups_enable = .; \ - KEEP(*(.pci_fixup_enable)) \ - __end_pci_fixups_enable = .; \ - __start_pci_fixups_resume = .; \ - KEEP(*(.pci_fixup_resume)) \ - __end_pci_fixups_resume = .; \ - __start_pci_fixups_resume_early = .; \ - KEEP(*(.pci_fixup_resume_early)) \ - __end_pci_fixups_resume_early = .; \ - __start_pci_fixups_suspend = .; \ - KEEP(*(.pci_fixup_suspend)) \ - __end_pci_fixups_suspend = .; \ - __start_pci_fixups_suspend_late = .; \ - KEEP(*(.pci_fixup_suspend_late)) \ - __end_pci_fixups_suspend_late = .; \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_early, _pci_fixups_early, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_header, _pci_fixups_header, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_final, _pci_fixups_final, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_enable, _pci_fixups_enable, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_resume, _pci_fixups_resume, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_suspend, _pci_fixups_suspend, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_resume_early, _pci_fixups_resume_early, __start, __end) \ + BOUNDED_SECTION_PRE_LABEL(.pci_fixup_suspend_late, _pci_fixups_suspend_late, __start, __end) \ } \ \ FW_LOADER_BUILT_IN_DATA \ @@ -544,16 +511,12 @@ \ /* Built-in module parameters. */ \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \ - __start___param = .; \ - KEEP(*(__param)) \ - __stop___param = .; \ + BOUNDED_SECTION_BY(__param, ___param) \ } \ \ /* Built-in module versions. */ \ __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ - __start___modver = .; \ - KEEP(*(__modver)) \ - __stop___modver = .; \ + BOUNDED_SECTION_BY(__modver, ___modver) \ } \ \ KCFI_TRAPS \ @@ -663,9 +626,7 @@ #define EXCEPTION_TABLE(align) \ . = ALIGN(align); \ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { \ - __start___ex_table = .; \ - KEEP(*(__ex_table)) \ - __stop___ex_table = .; \ + BOUNDED_SECTION_BY(__ex_table, ___ex_table) \ } /* @@ -674,9 +635,7 @@ #ifdef CONFIG_DEBUG_INFO_BTF #define BTF \ .BTF : AT(ADDR(.BTF) - LOAD_OFFSET) { \ - __start_BTF = .; \ - KEEP(*(.BTF)) \ - __stop_BTF = .; \ + BOUNDED_SECTION_BY(.BTF, _BTF) \ } \ . = ALIGN(4); \ .BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) { \ @@ -853,9 +812,7 @@ #define BUG_TABLE \ . = ALIGN(8); \ __bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) { \ - __start___bug_table = .; \ - KEEP(*(__bug_table)) \ - __stop___bug_table = .; \ + BOUNDED_SECTION_BY(__bug_table, ___bug_table) \ } #else #define BUG_TABLE @@ -865,15 +822,11 @@ #define ORC_UNWIND_TABLE \ . = ALIGN(4); \ .orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) { \ - __start_orc_unwind_ip = .; \ - KEEP(*(.orc_unwind_ip)) \ - __stop_orc_unwind_ip = .; \ + BOUNDED_SECTION_BY(.orc_unwind_ip, _orc_unwind_ip) \ } \ . = ALIGN(2); \ .orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) { \ - __start_orc_unwind = .; \ - KEEP(*(.orc_unwind)) \ - __stop_orc_unwind = .; \ + BOUNDED_SECTION_BY(.orc_unwind, _orc_unwind) \ } \ text_size = _etext - _stext; \ . = ALIGN(4); \ @@ -891,9 +844,7 @@ #ifdef CONFIG_FW_LOADER #define FW_LOADER_BUILT_IN_DATA \ .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) { \ - __start_builtin_fw = .; \ - KEEP(*(.builtin_fw)) \ - __end_builtin_fw = .; \ + BOUNDED_SECTION_PRE_LABEL(.builtin_fw, _builtin_fw, __start, __end) \ } #else #define FW_LOADER_BUILT_IN_DATA @@ -903,9 +854,7 @@ #define TRACEDATA \ . = ALIGN(4); \ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { \ - __tracedata_start = .; \ - KEEP(*(.tracedata)) \ - __tracedata_end = .; \ + BOUNDED_SECTION_POST_LABEL(.tracedata, __tracedata, _start, _end) \ } #else #define TRACEDATA @@ -914,9 +863,7 @@ #ifdef CONFIG_PRINTK_INDEX #define PRINTK_INDEX \ .printk_index : AT(ADDR(.printk_index) - LOAD_OFFSET) { \ - __start_printk_index = .; \ - *(.printk_index) \ - __stop_printk_index = .; \ + BOUNDED_SECTION_BY(.printk_index, _printk_index) \ } #else #define PRINTK_INDEX @@ -924,17 +871,13 @@ #define NOTES \ .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ - __start_notes = .; \ - KEEP(*(.note.*)) \ - __stop_notes = .; \ + BOUNDED_SECTION_BY(.note.*, _notes) \ } NOTES_HEADERS \ NOTES_HEADERS_RESTORE #define INIT_SETUP(initsetup_align) \ . = ALIGN(initsetup_align); \ - __setup_start = .; \ - KEEP(*(.init.setup)) \ - __setup_end = .; + BOUNDED_SECTION_POST_LABEL(.init.setup, __setup, _start, _end) #define INIT_CALLS_LEVEL(level) \ __initcall##level##_start = .; \ @@ -956,16 +899,12 @@ __initcall_end = .; #define CON_INITCALL \ - __con_initcall_start = .; \ - KEEP(*(.con_initcall.init)) \ - __con_initcall_end = .; + BOUNDED_SECTION_POST_LABEL(.con_initcall.init, __con_initcall, _start, _end) /* Alignment must be consistent with (kunit_suite *) in include/kunit/test.h */ #define KUNIT_TABLE() \ . = ALIGN(8); \ - __kunit_suites_start = .; \ - KEEP(*(.kunit_test_suites)) \ - __kunit_suites_end = .; + BOUNDED_SECTION_POST_LABEL(.kunit_test_suites, __kunit_suites, _start, _end) #ifdef CONFIG_BLK_DEV_INITRD #define INIT_RAM_FS \ -- GitLab From 2f465b921bb8ff97025017e05f6c7a7a1f6a5749 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sat, 22 Oct 2022 16:56:37 -0600 Subject: [PATCH 0479/1480] vmlinux.lds.h: place optional header space in BOUNDED_SECTION Extend recently added BOUNDED_SECTION(_name) macro by adding a KEEP(*(.gnu.linkonce.##_name)) before the KEEP(*(_name)). This does nothing by itself, vmlinux is the same before and after this patch. But if a developer adds a .gnu.linkonce.foo record, that record is placed in the front of the section, where it can be used as a header for the table. The intent is to create an up-link to another organizing struct, from where related tables can be referenced. And since every item in a table has a known offset from its header, that same offset can be used to fetch records from the related tables. By itself, this doesnt gain much, unless maybe the pattern of access is to scan 1 or 2 fields in each fat record, but with 2 16 bit .map* fields added, we could de-duplicate 2 related tables. The use case here is struct _ddebug, which has 3 pointers (function, file, module) with substantial repetition; respectively 53%, 90%, and the module column is fully recoverable after dynamic_debug_init() splits the table into a linked list of "module" chunks. On a DYNAMIC_DEBUG=y kernel with 5k pr_debugs, the memory savings should be ~100 KiB. Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20221022225637.1406715-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9f6352171f886..b3ca56ac163f7 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -195,11 +195,13 @@ #define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _s_, _e_) \ _s_##_label_ = .; \ + KEEP(*(.gnu.linkonce.##_sec_)) \ KEEP(*(_sec_)) \ _e_##_label_ = .; #define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _s_, _e_) \ _label_##_s_ = .; \ + KEEP(*(.gnu.linkonce.##_sec_)) \ KEEP(*(_sec_)) \ _label_##_e_ = .; -- GitLab From 9e6f07cd1eaa72c41719050c5ca9d22a8c0b7c02 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:01 +0100 Subject: [PATCH 0480/1480] vfio/ccw: create a parent struct Move the stuff associated with the mdev parent (and thus the subchannel struct) into its own struct, and leave the rest in the existing private structure. The subchannel will point to the parent, and the parent will point to the private, for the areas where one or both are needed. Further separation of these structs will follow. Signed-off-by: Eric Farman Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-2-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_drv.c | 98 +++++++++++++++++++++++------ drivers/s390/cio/vfio_ccw_ops.c | 8 ++- drivers/s390/cio/vfio_ccw_private.h | 20 ++++-- 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 7f5402fe857a2..444b32047397b 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -36,10 +36,19 @@ debug_info_t *vfio_ccw_debug_trace_id; */ int vfio_ccw_sch_quiesce(struct subchannel *sch) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); DECLARE_COMPLETION_ONSTACK(completion); int iretry, ret = 0; + /* + * Probably an impossible situation, after being called through + * FSM callbacks. But in the event it did, register a warning + * and return as if things were fine. + */ + if (WARN_ON(!private)) + return 0; + iretry = 255; do { @@ -121,7 +130,23 @@ static void vfio_ccw_crw_todo(struct work_struct *work) */ static void vfio_ccw_sch_irq(struct subchannel *sch) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); + + /* + * The subchannel should still be disabled at this point, + * so an interrupt would be quite surprising. As with an + * interrupt while the FSM is closed, let's attempt to + * disable the subchannel again. + */ + if (!private) { + VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: unexpected interrupt\n", + sch->schid.cssid, sch->schid.ssid, + sch->schid.sch_no); + + cio_disable_subchannel(sch); + return; + } inc_irq_stat(IRQIO_CIO); vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); @@ -201,10 +226,19 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private) mutex_destroy(&private->io_mutex); kfree(private); } + +static void vfio_ccw_free_parent(struct device *dev) +{ + struct vfio_ccw_parent *parent = container_of(dev, struct vfio_ccw_parent, dev); + + kfree(parent); +} + static int vfio_ccw_sch_probe(struct subchannel *sch) { struct pmcw *pmcw = &sch->schib.pmcw; struct vfio_ccw_private *private; + struct vfio_ccw_parent *parent; int ret = -ENOMEM; if (pmcw->qf) { @@ -213,38 +247,58 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) return -ENODEV; } + parent = kzalloc(sizeof(*parent), GFP_KERNEL); + if (!parent) + return -ENOMEM; + + dev_set_name(&parent->dev, "parent"); + parent->dev.parent = &sch->dev; + parent->dev.release = &vfio_ccw_free_parent; + ret = device_register(&parent->dev); + if (ret) + goto out_free; + private = vfio_ccw_alloc_private(sch); - if (IS_ERR(private)) + if (IS_ERR(private)) { + device_unregister(&parent->dev); return PTR_ERR(private); + } - dev_set_drvdata(&sch->dev, private); + dev_set_drvdata(&sch->dev, parent); + dev_set_drvdata(&parent->dev, private); - private->mdev_type.sysfs_name = "io"; - private->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)"; - private->mdev_types[0] = &private->mdev_type; - ret = mdev_register_parent(&private->parent, &sch->dev, + parent->mdev_type.sysfs_name = "io"; + parent->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)"; + parent->mdev_types[0] = &parent->mdev_type; + ret = mdev_register_parent(&parent->parent, &sch->dev, &vfio_ccw_mdev_driver, - private->mdev_types, 1); + parent->mdev_types, 1); if (ret) - goto out_free; + goto out_unreg; VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no); return 0; +out_unreg: + device_unregister(&parent->dev); out_free: + dev_set_drvdata(&parent->dev, NULL); dev_set_drvdata(&sch->dev, NULL); - vfio_ccw_free_private(private); + if (private) + vfio_ccw_free_private(private); return ret; } static void vfio_ccw_sch_remove(struct subchannel *sch) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); - mdev_unregister_parent(&private->parent); + mdev_unregister_parent(&parent->parent); + device_unregister(&parent->dev); dev_set_drvdata(&sch->dev, NULL); vfio_ccw_free_private(private); @@ -256,7 +310,11 @@ static void vfio_ccw_sch_remove(struct subchannel *sch) static void vfio_ccw_sch_shutdown(struct subchannel *sch) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); + + if (WARN_ON(!private)) + return; vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE); vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); @@ -274,7 +332,8 @@ static void vfio_ccw_sch_shutdown(struct subchannel *sch) */ static int vfio_ccw_sch_event(struct subchannel *sch, int process) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); unsigned long flags; int rc = -EAGAIN; @@ -287,8 +346,10 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process) rc = 0; - if (cio_update_schib(sch)) - vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); + if (cio_update_schib(sch)) { + if (private) + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); + } out_unlock: spin_unlock_irqrestore(sch->lock, flags); @@ -326,7 +387,8 @@ static void vfio_ccw_queue_crw(struct vfio_ccw_private *private, static int vfio_ccw_chp_event(struct subchannel *sch, struct chp_link *link, int event) { - struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); int mask = chp_ssd_get_mask(&sch->ssd_info, link); int retry = 255; diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 6ae4d012d8008..dc084883d872d 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -55,7 +55,9 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) static int vfio_ccw_mdev_probe(struct mdev_device *mdev) { - struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); + struct subchannel *sch = to_subchannel(mdev->dev.parent); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); int ret; if (private->state == VFIO_CCW_STATE_NOT_OPER) @@ -100,7 +102,9 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) static void vfio_ccw_mdev_remove(struct mdev_device *mdev) { - struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); + struct subchannel *sch = to_subchannel(mdev->dev.parent); + struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); + struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: remove\n", private->sch->schid.cssid, diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index bd5fb81456af8..1f598d58d9694 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -67,6 +67,21 @@ struct vfio_ccw_crw { struct crw crw; }; +/** + * struct vfio_ccw_parent + * + * @dev: embedded device struct + * @parent: parent data structures for mdevs created + * @mdev_type(s): identifying information for mdevs created + */ +struct vfio_ccw_parent { + struct device dev; + + struct mdev_parent parent; + struct mdev_type mdev_type; + struct mdev_type *mdev_types[1]; +}; + /** * struct vfio_ccw_private * @vdev: Embedded VFIO device @@ -89,7 +104,6 @@ struct vfio_ccw_crw { * @io_work: work for deferral process of I/O handling * @crw_work: work for deferral process of CRW handling * @release_comp: synchronization helper for vfio device release - * @parent: parent data structures for mdevs created */ struct vfio_ccw_private { struct vfio_device vdev; @@ -116,10 +130,6 @@ struct vfio_ccw_private { struct work_struct crw_work; struct completion release_comp; - - struct mdev_parent parent; - struct mdev_type mdev_type; - struct mdev_type *mdev_types[1]; } __aligned(8); int vfio_ccw_sch_quiesce(struct subchannel *sch); -- GitLab From 008a011d68036ebfa4dede07cb9b93dedaa958b1 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:02 +0100 Subject: [PATCH 0481/1480] vfio/ccw: remove private->sch These places all rely on the ability to jump from a private struct back to the subchannel struct. Rather than keeping a copy in our back pocket, let's use the relationship provided by the vfio_device embedded within the private. Signed-off-by: Eric Farman Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-3-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_chp.c | 5 +++-- drivers/s390/cio/vfio_ccw_drv.c | 3 +-- drivers/s390/cio/vfio_ccw_fsm.c | 27 ++++++++++++--------------- drivers/s390/cio/vfio_ccw_ops.c | 12 ++++++------ drivers/s390/cio/vfio_ccw_private.h | 7 ++++--- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_chp.c b/drivers/s390/cio/vfio_ccw_chp.c index 13b26a1c79886..d3f3a611f95b4 100644 --- a/drivers/s390/cio/vfio_ccw_chp.c +++ b/drivers/s390/cio/vfio_ccw_chp.c @@ -16,6 +16,7 @@ static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private, char __user *buf, size_t count, loff_t *ppos) { + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS; loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK; struct ccw_schib_region *region; @@ -27,12 +28,12 @@ static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private, mutex_lock(&private->io_mutex); region = private->region[i].data; - if (cio_update_schib(private->sch)) { + if (cio_update_schib(sch)) { ret = -ENODEV; goto out; } - memcpy(region, &private->sch->schib, sizeof(*region)); + memcpy(region, &sch->schib, sizeof(*region)); if (copy_to_user(buf, (void *)region + pos, count)) { ret = -EFAULT; diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 444b32047397b..2c680a5563832 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -160,7 +160,6 @@ static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch) if (!private) return ERR_PTR(-ENOMEM); - private->sch = sch; mutex_init(&private->io_mutex); private->state = VFIO_CCW_STATE_STANDBY; INIT_LIST_HEAD(&private->crw); @@ -395,7 +394,7 @@ static int vfio_ccw_chp_event(struct subchannel *sch, if (!private || !mask) return 0; - trace_vfio_ccw_chp_event(private->sch->schid, mask, event); + trace_vfio_ccw_chp_event(sch->schid, mask, event); VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: mask=0x%x event=%d\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no, diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index a59c758869f8f..e67fad897af3a 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -18,15 +18,13 @@ static int fsm_io_helper(struct vfio_ccw_private *private) { - struct subchannel *sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); union orb *orb; int ccode; __u8 lpm; unsigned long flags; int ret; - sch = private->sch; - spin_lock_irqsave(sch->lock, flags); orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm); @@ -80,13 +78,11 @@ out: static int fsm_do_halt(struct vfio_ccw_private *private) { - struct subchannel *sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); unsigned long flags; int ccode; int ret; - sch = private->sch; - spin_lock_irqsave(sch->lock, flags); VFIO_CCW_TRACE_EVENT(2, "haltIO"); @@ -121,13 +117,11 @@ static int fsm_do_halt(struct vfio_ccw_private *private) static int fsm_do_clear(struct vfio_ccw_private *private) { - struct subchannel *sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); unsigned long flags; int ccode; int ret; - sch = private->sch; - spin_lock_irqsave(sch->lock, flags); VFIO_CCW_TRACE_EVENT(2, "clearIO"); @@ -160,7 +154,7 @@ static int fsm_do_clear(struct vfio_ccw_private *private) static void fsm_notoper(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - struct subchannel *sch = private->sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: notoper event %x state %x\n", sch->schid.cssid, @@ -228,7 +222,7 @@ static void fsm_async_retry(struct vfio_ccw_private *private, static void fsm_disabled_irq(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - struct subchannel *sch = private->sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); /* * An interrupt in a disabled state means a previous disable was not @@ -238,7 +232,9 @@ static void fsm_disabled_irq(struct vfio_ccw_private *private, } inline struct subchannel_id get_schid(struct vfio_ccw_private *p) { - return p->sch->schid; + struct subchannel *sch = to_subchannel(p->vdev.dev->parent); + + return sch->schid; } /* @@ -360,10 +356,11 @@ static void fsm_async_request(struct vfio_ccw_private *private, static void fsm_irq(struct vfio_ccw_private *private, enum vfio_ccw_event event) { + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); struct irb *irb = this_cpu_ptr(&cio_irb); VFIO_CCW_TRACE_EVENT(6, "IRQ"); - VFIO_CCW_TRACE_EVENT(6, dev_name(&private->sch->dev)); + VFIO_CCW_TRACE_EVENT(6, dev_name(&sch->dev)); memcpy(&private->irb, irb, sizeof(*irb)); @@ -376,7 +373,7 @@ static void fsm_irq(struct vfio_ccw_private *private, static void fsm_open(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - struct subchannel *sch = private->sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); int ret; spin_lock_irq(sch->lock); @@ -397,7 +394,7 @@ err_unlock: static void fsm_close(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - struct subchannel *sch = private->sch; + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); int ret; spin_lock_irq(sch->lock); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index dc084883d872d..79c50cb7dcb81 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -68,9 +68,9 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) return ret; VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n", - private->sch->schid.cssid, - private->sch->schid.ssid, - private->sch->schid.sch_no); + sch->schid.cssid, + sch->schid.ssid, + sch->schid.sch_no); ret = vfio_register_emulated_iommu_dev(&private->vdev); if (ret) @@ -107,9 +107,9 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: remove\n", - private->sch->schid.cssid, - private->sch->schid.ssid, - private->sch->schid.sch_no); + sch->schid.cssid, + sch->schid.ssid, + sch->schid.sch_no); vfio_unregister_group_dev(&private->vdev); diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 1f598d58d9694..b28af2f639630 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -85,7 +85,6 @@ struct vfio_ccw_parent { /** * struct vfio_ccw_private * @vdev: Embedded VFIO device - * @sch: pointer to the subchannel * @state: internal state of the device * @completion: synchronization helper of the I/O completion * @io_region: MMIO region to input/output I/O arguments/results @@ -107,7 +106,6 @@ struct vfio_ccw_parent { */ struct vfio_ccw_private { struct vfio_device vdev; - struct subchannel *sch; int state; struct completion *completion; struct ccw_io_region *io_region; @@ -172,7 +170,10 @@ extern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS]; static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - trace_vfio_ccw_fsm_event(private->sch->schid, private->state, event); + struct subchannel *sch = to_subchannel(private->vdev.dev->parent); + + if (sch) + trace_vfio_ccw_fsm_event(sch->schid, private->state, event); vfio_ccw_jumptable[private->state][event](private, event); } -- GitLab From 06caaa27df8f1a8a6be78212c5ef5cac04500176 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:03 +0100 Subject: [PATCH 0482/1480] vfio/ccw: move private initialization to callback There's already a device initialization callback that is used to initialize the release completion workaround that was introduced by commit ebb72b765fb49 ("vfio/ccw: Use the new device life cycle helpers"). Move the other elements of the vfio_ccw_private struct that require distinct initialization over to that routine. With that done, the vfio_ccw_alloc_private routine only does a kzalloc, so fold it inline. Signed-off-by: Eric Farman Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-4-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_drv.c | 74 ++++------------------------- drivers/s390/cio/vfio_ccw_ops.c | 43 +++++++++++++++++ drivers/s390/cio/vfio_ccw_private.h | 7 ++- 3 files changed, 58 insertions(+), 66 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 2c680a5563832..fbc26338ceabe 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -23,10 +23,10 @@ #include "vfio_ccw_private.h" struct workqueue_struct *vfio_ccw_work_q; -static struct kmem_cache *vfio_ccw_io_region; -static struct kmem_cache *vfio_ccw_cmd_region; -static struct kmem_cache *vfio_ccw_schib_region; -static struct kmem_cache *vfio_ccw_crw_region; +struct kmem_cache *vfio_ccw_io_region; +struct kmem_cache *vfio_ccw_cmd_region; +struct kmem_cache *vfio_ccw_schib_region; +struct kmem_cache *vfio_ccw_crw_region; debug_info_t *vfio_ccw_debug_msg_id; debug_info_t *vfio_ccw_debug_trace_id; @@ -79,7 +79,7 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch) return ret; } -static void vfio_ccw_sch_io_todo(struct work_struct *work) +void vfio_ccw_sch_io_todo(struct work_struct *work) { struct vfio_ccw_private *private; struct irb *irb; @@ -115,7 +115,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) eventfd_signal(private->io_trigger, 1); } -static void vfio_ccw_crw_todo(struct work_struct *work) +void vfio_ccw_crw_todo(struct work_struct *work) { struct vfio_ccw_private *private; @@ -152,62 +152,6 @@ static void vfio_ccw_sch_irq(struct subchannel *sch) vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); } -static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch) -{ - struct vfio_ccw_private *private; - - private = kzalloc(sizeof(*private), GFP_KERNEL); - if (!private) - return ERR_PTR(-ENOMEM); - - mutex_init(&private->io_mutex); - private->state = VFIO_CCW_STATE_STANDBY; - INIT_LIST_HEAD(&private->crw); - INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); - INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); - - private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1), - GFP_KERNEL); - if (!private->cp.guest_cp) - goto out_free_private; - - private->io_region = kmem_cache_zalloc(vfio_ccw_io_region, - GFP_KERNEL | GFP_DMA); - if (!private->io_region) - goto out_free_cp; - - private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region, - GFP_KERNEL | GFP_DMA); - if (!private->cmd_region) - goto out_free_io; - - private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region, - GFP_KERNEL | GFP_DMA); - - if (!private->schib_region) - goto out_free_cmd; - - private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region, - GFP_KERNEL | GFP_DMA); - - if (!private->crw_region) - goto out_free_schib; - return private; - -out_free_schib: - kmem_cache_free(vfio_ccw_schib_region, private->schib_region); -out_free_cmd: - kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); -out_free_io: - kmem_cache_free(vfio_ccw_io_region, private->io_region); -out_free_cp: - kfree(private->cp.guest_cp); -out_free_private: - mutex_destroy(&private->io_mutex); - kfree(private); - return ERR_PTR(-ENOMEM); -} - static void vfio_ccw_free_private(struct vfio_ccw_private *private) { struct vfio_ccw_crw *crw, *temp; @@ -257,10 +201,10 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) if (ret) goto out_free; - private = vfio_ccw_alloc_private(sch); - if (IS_ERR(private)) { + private = kzalloc(sizeof(*private), GFP_KERNEL); + if (!private) { device_unregister(&parent->dev); - return PTR_ERR(private); + return -ENOMEM; } dev_set_drvdata(&sch->dev, parent); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 79c50cb7dcb81..eb0b8cc210bb8 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -49,8 +49,51 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) struct vfio_ccw_private *private = container_of(vdev, struct vfio_ccw_private, vdev); + mutex_init(&private->io_mutex); + private->state = VFIO_CCW_STATE_STANDBY; + INIT_LIST_HEAD(&private->crw); + INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); + INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); init_completion(&private->release_comp); + + private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1), + GFP_KERNEL); + if (!private->cp.guest_cp) + goto out_free_private; + + private->io_region = kmem_cache_zalloc(vfio_ccw_io_region, + GFP_KERNEL | GFP_DMA); + if (!private->io_region) + goto out_free_cp; + + private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region, + GFP_KERNEL | GFP_DMA); + if (!private->cmd_region) + goto out_free_io; + + private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region, + GFP_KERNEL | GFP_DMA); + if (!private->schib_region) + goto out_free_cmd; + + private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region, + GFP_KERNEL | GFP_DMA); + if (!private->crw_region) + goto out_free_schib; + return 0; + +out_free_schib: + kmem_cache_free(vfio_ccw_schib_region, private->schib_region); +out_free_cmd: + kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); +out_free_io: + kmem_cache_free(vfio_ccw_io_region, private->io_region); +out_free_cp: + kfree(private->cp.guest_cp); +out_free_private: + mutex_destroy(&private->io_mutex); + return -ENOMEM; } static int vfio_ccw_mdev_probe(struct mdev_device *mdev) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index b28af2f639630..55d636225cff8 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -131,6 +131,8 @@ struct vfio_ccw_private { } __aligned(8); int vfio_ccw_sch_quiesce(struct subchannel *sch); +void vfio_ccw_sch_io_todo(struct work_struct *work); +void vfio_ccw_crw_todo(struct work_struct *work); extern struct mdev_driver vfio_ccw_mdev_driver; @@ -178,7 +180,10 @@ static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, } extern struct workqueue_struct *vfio_ccw_work_q; - +extern struct kmem_cache *vfio_ccw_io_region; +extern struct kmem_cache *vfio_ccw_cmd_region; +extern struct kmem_cache *vfio_ccw_schib_region; +extern struct kmem_cache *vfio_ccw_crw_region; /* s390 debug feature, similar to base cio */ extern debug_info_t *vfio_ccw_debug_msg_id; -- GitLab From 3d62fe18b6a3a93c5360c2d590b9b40b6842133e Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:04 +0100 Subject: [PATCH 0483/1480] vfio/ccw: move private to mdev lifecycle Now that the mdev parent data is split out into its own struct, it is safe to move the remaining private data to follow the mdev probe/remove lifecycle. The mdev parent data will remain where it is, and follow the subchannel and the css driver interfaces. Signed-off-by: Eric Farman Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-5-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_drv.c | 16 +--------------- drivers/s390/cio/vfio_ccw_ops.c | 26 +++++++++++++------------- drivers/s390/cio/vfio_ccw_private.h | 2 ++ 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index fbc26338ceabe..9fbd1b27a1ac1 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -152,7 +152,7 @@ static void vfio_ccw_sch_irq(struct subchannel *sch) vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); } -static void vfio_ccw_free_private(struct vfio_ccw_private *private) +void vfio_ccw_free_private(struct vfio_ccw_private *private) { struct vfio_ccw_crw *crw, *temp; @@ -180,7 +180,6 @@ static void vfio_ccw_free_parent(struct device *dev) static int vfio_ccw_sch_probe(struct subchannel *sch) { struct pmcw *pmcw = &sch->schib.pmcw; - struct vfio_ccw_private *private; struct vfio_ccw_parent *parent; int ret = -ENOMEM; @@ -201,14 +200,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) if (ret) goto out_free; - private = kzalloc(sizeof(*private), GFP_KERNEL); - if (!private) { - device_unregister(&parent->dev); - return -ENOMEM; - } - dev_set_drvdata(&sch->dev, parent); - dev_set_drvdata(&parent->dev, private); parent->mdev_type.sysfs_name = "io"; parent->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)"; @@ -227,25 +219,19 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) out_unreg: device_unregister(&parent->dev); out_free: - dev_set_drvdata(&parent->dev, NULL); dev_set_drvdata(&sch->dev, NULL); - if (private) - vfio_ccw_free_private(private); return ret; } static void vfio_ccw_sch_remove(struct subchannel *sch) { struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); - struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); mdev_unregister_parent(&parent->parent); device_unregister(&parent->dev); dev_set_drvdata(&sch->dev, NULL); - vfio_ccw_free_private(private); - VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index eb0b8cc210bb8..e45d4acb109b0 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -100,15 +100,20 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) { struct subchannel *sch = to_subchannel(mdev->dev.parent); struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev); - struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev); + struct vfio_ccw_private *private; int ret; - if (private->state == VFIO_CCW_STATE_NOT_OPER) - return -ENODEV; + private = kzalloc(sizeof(*private), GFP_KERNEL); + if (!private) + return -ENOMEM; ret = vfio_init_device(&private->vdev, &mdev->dev, &vfio_ccw_dev_ops); - if (ret) + if (ret) { + kfree(private); return ret; + } + + dev_set_drvdata(&parent->dev, private); VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n", sch->schid.cssid, @@ -122,6 +127,7 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) return 0; err_put_vdev: + dev_set_drvdata(&parent->dev, NULL); vfio_put_device(&private->vdev); return ret; } @@ -131,15 +137,6 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) struct vfio_ccw_private *private = container_of(vdev, struct vfio_ccw_private, vdev); - /* - * We cannot free vfio_ccw_private here because it includes - * parent info which must be free'ed by css driver. - * - * Use a workaround by memset'ing the core device part and - * then notifying the remove path that all active references - * to this device have been released. - */ - memset(vdev, 0, sizeof(*vdev)); complete(&private->release_comp); } @@ -156,6 +153,7 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) vfio_unregister_group_dev(&private->vdev); + dev_set_drvdata(&parent->dev, NULL); vfio_put_device(&private->vdev); /* * Wait for all active references on mdev are released so it @@ -166,6 +164,8 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) * cycle. */ wait_for_completion(&private->release_comp); + + vfio_ccw_free_private(private); } static int vfio_ccw_mdev_open_device(struct vfio_device *vdev) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 55d636225cff8..747aba5f52723 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -134,6 +134,8 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch); void vfio_ccw_sch_io_todo(struct work_struct *work); void vfio_ccw_crw_todo(struct work_struct *work); +void vfio_ccw_free_private(struct vfio_ccw_private *private); + extern struct mdev_driver vfio_ccw_mdev_driver; /* -- GitLab From f4da83f7e3f096ece936512d86ef3726e470fbfd Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:05 +0100 Subject: [PATCH 0484/1480] vfio/ccw: remove release completion There's enough separation between the parent and private structs now, that it is fine to remove the release completion hack. Signed-off-by: Eric Farman Reviewed-by: Kevin Tian Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-6-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_ops.c | 14 +------------- drivers/s390/cio/vfio_ccw_private.h | 3 --- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index e45d4acb109b0..8a929a9cf3c66 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -54,7 +54,6 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) INIT_LIST_HEAD(&private->crw); INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); - init_completion(&private->release_comp); private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1), GFP_KERNEL); @@ -137,7 +136,7 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) struct vfio_ccw_private *private = container_of(vdev, struct vfio_ccw_private, vdev); - complete(&private->release_comp); + vfio_ccw_free_private(private); } static void vfio_ccw_mdev_remove(struct mdev_device *mdev) @@ -155,17 +154,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) dev_set_drvdata(&parent->dev, NULL); vfio_put_device(&private->vdev); - /* - * Wait for all active references on mdev are released so it - * is safe to defer kfree() to a later point. - * - * TODO: the clean fix is to split parent/mdev info from ccw - * private structure so each can be managed in its own life - * cycle. - */ - wait_for_completion(&private->release_comp); - - vfio_ccw_free_private(private); } static int vfio_ccw_mdev_open_device(struct vfio_device *vdev) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 747aba5f52723..2278fd38d34ea 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -102,7 +102,6 @@ struct vfio_ccw_parent { * @req_trigger: eventfd ctx for signaling userspace to return device * @io_work: work for deferral process of I/O handling * @crw_work: work for deferral process of CRW handling - * @release_comp: synchronization helper for vfio device release */ struct vfio_ccw_private { struct vfio_device vdev; @@ -126,8 +125,6 @@ struct vfio_ccw_private { struct eventfd_ctx *req_trigger; struct work_struct io_work; struct work_struct crw_work; - - struct completion release_comp; } __aligned(8); int vfio_ccw_sch_quiesce(struct subchannel *sch); -- GitLab From 6ac73820993c13f30d226f9521f8ffae62acdf42 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 10 Nov 2022 15:30:10 -0300 Subject: [PATCH 0485/1480] perf trace: Add augmenter for clock_gettime's rqtp timespec arg One more before going the BTF way: # perf trace -e /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o,*nanosleep ? pool-gsd-smart/2893 ... [continued]: clock_nanosleep()) = 0 ? gpm/1042 ... [continued]: clock_nanosleep()) = 0 1.232 pool-gsd-smart/2893 clock_nanosleep(rqtp: { .tv_sec: 1, .tv_nsec: 0 }, rmtp: 0x7f64d7ffec50) ... 1.232 pool-gsd-smart/2893 ... [continued]: clock_nanosleep()) = 0 327.329 gpm/1042 clock_nanosleep(rqtp: { .tv_sec: 2, .tv_nsec: 0 }, rmtp: 0x7ffddfd1cf20) ... 1002.482 pool-gsd-smart/2893 clock_nanosleep(rqtp: { .tv_sec: 1, .tv_nsec: 0 }, rmtp: 0x7f64d7ffec50) = 0 327.329 gpm/1042 ... [continued]: clock_nanosleep()) = 0 2003.947 pool-gsd-smart/2893 clock_nanosleep(rqtp: { .tv_sec: 1, .tv_nsec: 0 }, rmtp: 0x7f64d7ffec50) ... 2003.947 pool-gsd-smart/2893 ... [continued]: clock_nanosleep()) = 0 2327.858 gpm/1042 clock_nanosleep(rqtp: { .tv_sec: 2, .tv_nsec: 0 }, rmtp: 0x7ffddfd1cf20) ... ? crond/1384 ... [continued]: clock_nanosleep()) = 0 3005.382 pool-gsd-smart/2893 clock_nanosleep(rqtp: { .tv_sec: 1, .tv_nsec: 0 }, rmtp: 0x7f64d7ffec50) ... 3005.382 pool-gsd-smart/2893 ... [continued]: clock_nanosleep()) = 0 3675.633 crond/1384 clock_nanosleep(rqtp: { .tv_sec: 60, .tv_nsec: 0 }, rmtp: 0x7ffcc02b66b0) ... ^C# Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 ++ .../examples/bpf/augmented_raw_syscalls.c | 28 +++++++++++++++++++ tools/perf/trace/beauty/Build | 1 + tools/perf/trace/beauty/beauty.h | 3 ++ tools/perf/trace/beauty/timespec.c | 21 ++++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 tools/perf/trace/beauty/timespec.c diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5690c33c523b3..c93b359abc312 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -924,6 +924,8 @@ static struct syscall_fmt syscall_fmts[] = { .arg = { [0] = { .scnprintf = SCA_PTR, /* brk */ }, }, }, { .name = "clock_gettime", .arg = { [0] = STRARRAY(clk_id, clockid), }, }, + { .name = "clock_nanosleep", + .arg = { [2] = { .scnprintf = SCA_TIMESPEC, /* rqtp */ }, }, }, { .name = "clone", .errpid = true, .nr_args = 5, .arg = { [0] = { .name = "flags", .scnprintf = SCA_CLONE_FLAGS, }, [1] = { .name = "child_stack", .scnprintf = SCA_HEX, }, diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 0599823e8ae1b..7dc24c9173a75 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -21,6 +21,13 @@ // FIXME: These should come from system headers typedef char bool; typedef int pid_t; +typedef long long int __s64; +typedef __s64 time64_t; + +struct timespec64 { + time64_t tv_sec; + long int tv_nsec; +}; /* bpf-output associated map */ struct __augmented_syscalls__ { @@ -337,6 +344,27 @@ failure: return 1; /* Failure: don't filter */ } +SEC("!syscalls:sys_enter_clock_nanosleep") +int sys_enter_clock_nanosleep(struct syscall_enter_args *args) +{ + struct augmented_args_payload *augmented_args = augmented_args_payload(); + const void *rqtp_arg = (const void *)args->args[2]; + unsigned int len = sizeof(augmented_args->args); + __u32 size = sizeof(struct timespec64); + + if (augmented_args == NULL) + goto failure; + + if (size > sizeof(augmented_args->__data)) + goto failure; + + bpf_probe_read(&augmented_args->__data, size, rqtp_arg); + + return augmented__output(args, augmented_args, len + size); +failure: + return 1; /* Failure: don't filter */ +} + static pid_t getpid(void) { return bpf_get_current_pid_tgid(); diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index 433dc39053a7f..d11ce256f5114 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -17,4 +17,5 @@ perf-y += sockaddr.o perf-y += socket.o perf-y += statx.o perf-y += sync_file_range.o +perf-y += timespec.o perf-y += tracepoints/ diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index f527a46ab4e72..4c59edddd6a87 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -244,6 +244,9 @@ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_a size_t syscall_arg__scnprintf_sync_file_range_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_SYNC_FILE_RANGE_FLAGS syscall_arg__scnprintf_sync_file_range_flags +size_t syscall_arg__scnprintf_timespec(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_TIMESPEC syscall_arg__scnprintf_timespec + size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix); void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, diff --git a/tools/perf/trace/beauty/timespec.c b/tools/perf/trace/beauty/timespec.c new file mode 100644 index 0000000000000..e1a61f092aad8 --- /dev/null +++ b/tools/perf/trace/beauty/timespec.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: LGPL-2.1 +// Copyright (C) 2022, Red Hat Inc, Arnaldo Carvalho de Melo + +#include "trace/beauty/beauty.h" +#include +#include + +static size_t syscall_arg__scnprintf_augmented_timespec(struct syscall_arg *arg, char *bf, size_t size) +{ + struct timespec *ts = (struct timespec *)arg->augmented.args; + + return scnprintf(bf, size, "{ .tv_sec: %" PRIu64 ", .tv_nsec: %" PRIu64 " }", ts->tv_sec, ts->tv_nsec); +} + +size_t syscall_arg__scnprintf_timespec(char *bf, size_t size, struct syscall_arg *arg) +{ + if (arg->augmented.args) + return syscall_arg__scnprintf_augmented_timespec(arg, bf, size); + + return scnprintf(bf, size, "%#lx", arg->val); +} -- GitLab From d1104f9327df9b26901b97cd026949f80ccab0d3 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:06 +0100 Subject: [PATCH 0486/1480] vfio/ccw: replace vfio_init_device with _alloc_ Now that we have a reasonable separation of structs that follow the subchannel and mdev lifecycles, there's no reason we can't call the official vfio_alloc_device routine for our private data, and behave like everyone else. Signed-off-by: Eric Farman Reviewed-by: Kevin Tian Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-7-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_drv.c | 18 ------------------ drivers/s390/cio/vfio_ccw_ops.c | 28 ++++++++++++++++++---------- drivers/s390/cio/vfio_ccw_private.h | 2 -- drivers/vfio/vfio_main.c | 10 +++++----- include/linux/vfio.h | 2 -- 5 files changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 9fbd1b27a1ac1..c2a65808605af 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -152,24 +152,6 @@ static void vfio_ccw_sch_irq(struct subchannel *sch) vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); } -void vfio_ccw_free_private(struct vfio_ccw_private *private) -{ - struct vfio_ccw_crw *crw, *temp; - - list_for_each_entry_safe(crw, temp, &private->crw, next) { - list_del(&crw->next); - kfree(crw); - } - - kmem_cache_free(vfio_ccw_crw_region, private->crw_region); - kmem_cache_free(vfio_ccw_schib_region, private->schib_region); - kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); - kmem_cache_free(vfio_ccw_io_region, private->io_region); - kfree(private->cp.guest_cp); - mutex_destroy(&private->io_mutex); - kfree(private); -} - static void vfio_ccw_free_parent(struct device *dev) { struct vfio_ccw_parent *parent = container_of(dev, struct vfio_ccw_parent, dev); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 8a929a9cf3c66..1155f8bcedd99 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -102,15 +102,10 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) struct vfio_ccw_private *private; int ret; - private = kzalloc(sizeof(*private), GFP_KERNEL); - if (!private) - return -ENOMEM; - - ret = vfio_init_device(&private->vdev, &mdev->dev, &vfio_ccw_dev_ops); - if (ret) { - kfree(private); - return ret; - } + private = vfio_alloc_device(vfio_ccw_private, vdev, &mdev->dev, + &vfio_ccw_dev_ops); + if (IS_ERR(private)) + return PTR_ERR(private); dev_set_drvdata(&parent->dev, private); @@ -135,8 +130,21 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) { struct vfio_ccw_private *private = container_of(vdev, struct vfio_ccw_private, vdev); + struct vfio_ccw_crw *crw, *temp; + + list_for_each_entry_safe(crw, temp, &private->crw, next) { + list_del(&crw->next); + kfree(crw); + } + + kmem_cache_free(vfio_ccw_crw_region, private->crw_region); + kmem_cache_free(vfio_ccw_schib_region, private->schib_region); + kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); + kmem_cache_free(vfio_ccw_io_region, private->io_region); + kfree(private->cp.guest_cp); + mutex_destroy(&private->io_mutex); - vfio_ccw_free_private(private); + vfio_free_device(vdev); } static void vfio_ccw_mdev_remove(struct mdev_device *mdev) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 2278fd38d34ea..b441ae6700fd2 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -131,8 +131,6 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch); void vfio_ccw_sch_io_todo(struct work_struct *work); void vfio_ccw_crw_todo(struct work_struct *work); -void vfio_ccw_free_private(struct vfio_ccw_private *private); - extern struct mdev_driver vfio_ccw_mdev_driver; /* diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 2d168793d4e1c..2901b8ad5be92 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -348,6 +348,9 @@ static void vfio_device_release(struct device *dev) device->ops->release(device); } +static int vfio_init_device(struct vfio_device *device, struct device *dev, + const struct vfio_device_ops *ops); + /* * Allocate and initialize vfio_device so it can be registered to vfio * core. @@ -386,11 +389,9 @@ EXPORT_SYMBOL_GPL(_vfio_alloc_device); /* * Initialize a vfio_device so it can be registered to vfio core. - * - * Only vfio-ccw driver should call this interface. */ -int vfio_init_device(struct vfio_device *device, struct device *dev, - const struct vfio_device_ops *ops) +static int vfio_init_device(struct vfio_device *device, struct device *dev, + const struct vfio_device_ops *ops) { int ret; @@ -422,7 +423,6 @@ out_uninit: ida_free(&vfio.device_ida, device->index); return ret; } -EXPORT_SYMBOL_GPL(vfio_init_device); /* * The helper called by driver @release callback to free the device diff --git a/include/linux/vfio.h b/include/linux/vfio.h index e7cebeb875dd1..ba809268a48e0 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -176,8 +176,6 @@ struct vfio_device *_vfio_alloc_device(size_t size, struct device *dev, dev, ops), \ struct dev_struct, member) -int vfio_init_device(struct vfio_device *device, struct device *dev, - const struct vfio_device_ops *ops); void vfio_free_device(struct vfio_device *device); static inline void vfio_put_device(struct vfio_device *device) { -- GitLab From 913447d06f032a9e9c84870bec0b1adb8c588f29 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 4 Nov 2022 15:20:07 +0100 Subject: [PATCH 0487/1480] vfio: Remove vfio_free_device With the "mess" sorted out, we should be able to inline the vfio_free_device call introduced by commit cb9ff3f3b84c ("vfio: Add helpers for unifying vfio_device life cycle") and remove them from driver release callbacks. Signed-off-by: Eric Farman Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian Reviewed-by: Cornelia Huck Reviewed-by: Tony Krowiak # vfio-ap part Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20221104142007.1314999-8-farman@linux.ibm.com Signed-off-by: Alex Williamson --- drivers/gpu/drm/i915/gvt/kvmgt.c | 1 - drivers/s390/cio/vfio_ccw_ops.c | 2 -- drivers/s390/crypto/vfio_ap_ops.c | 6 ------ drivers/vfio/fsl-mc/vfio_fsl_mc.c | 1 - drivers/vfio/pci/vfio_pci_core.c | 1 - drivers/vfio/platform/vfio_amba.c | 1 - drivers/vfio/platform/vfio_platform.c | 1 - drivers/vfio/vfio_main.c | 22 ++++------------------ include/linux/vfio.h | 1 - samples/vfio-mdev/mbochs.c | 1 - samples/vfio-mdev/mdpy.c | 1 - samples/vfio-mdev/mtty.c | 1 - 12 files changed, 4 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 7a45e5360caf2..eee6805e67ded 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1461,7 +1461,6 @@ static void intel_vgpu_release_dev(struct vfio_device *vfio_dev) struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev); intel_gvt_destroy_vgpu(vgpu); - vfio_free_device(vfio_dev); } static const struct vfio_device_ops intel_vgpu_dev_ops = { diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 1155f8bcedd99..598a3814d4282 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -143,8 +143,6 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) kmem_cache_free(vfio_ccw_io_region, private->io_region); kfree(private->cp.guest_cp); mutex_destroy(&private->io_mutex); - - vfio_free_device(vdev); } static void vfio_ccw_mdev_remove(struct mdev_device *mdev) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 0b4cc8c597ae6..f108c0f147125 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -765,11 +765,6 @@ static void vfio_ap_mdev_unlink_fr_queues(struct ap_matrix_mdev *matrix_mdev) } } -static void vfio_ap_mdev_release_dev(struct vfio_device *vdev) -{ - vfio_free_device(vdev); -} - static void vfio_ap_mdev_remove(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev); @@ -1784,7 +1779,6 @@ static const struct attribute_group vfio_queue_attr_group = { static const struct vfio_device_ops vfio_ap_matrix_dev_ops = { .init = vfio_ap_mdev_init_dev, - .release = vfio_ap_mdev_release_dev, .open_device = vfio_ap_mdev_open_device, .close_device = vfio_ap_mdev_close_device, .ioctl = vfio_ap_mdev_ioctl, diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index b16874e913e4f..7b8889f550076 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -568,7 +568,6 @@ static void vfio_fsl_mc_release_dev(struct vfio_device *core_vdev) vfio_fsl_uninit_device(vdev); mutex_destroy(&vdev->igate); - vfio_free_device(core_vdev); } static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index badc9d828cac2..9be2d5be5d959 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -2109,7 +2109,6 @@ void vfio_pci_core_release_dev(struct vfio_device *core_vdev) mutex_destroy(&vdev->vma_lock); kfree(vdev->region); kfree(vdev->pm_save); - vfio_free_device(core_vdev); } EXPORT_SYMBOL_GPL(vfio_pci_core_release_dev); diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c index eaea63e5294c5..18faf2678b998 100644 --- a/drivers/vfio/platform/vfio_amba.c +++ b/drivers/vfio/platform/vfio_amba.c @@ -95,7 +95,6 @@ static void vfio_amba_release_dev(struct vfio_device *core_vdev) vfio_platform_release_common(vdev); kfree(vdev->name); - vfio_free_device(core_vdev); } static void vfio_amba_remove(struct amba_device *adev) diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c index 82cedcebfd902..9910451dc3415 100644 --- a/drivers/vfio/platform/vfio_platform.c +++ b/drivers/vfio/platform/vfio_platform.c @@ -83,7 +83,6 @@ static void vfio_platform_release_dev(struct vfio_device *core_vdev) container_of(core_vdev, struct vfio_platform_device, vdev); vfio_platform_release_common(vdev); - vfio_free_device(core_vdev); } static int vfio_platform_remove(struct platform_device *pdev) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 2901b8ad5be92..9835757e2bee4 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -339,13 +339,10 @@ static void vfio_device_release(struct device *dev) vfio_release_device_set(device); ida_free(&vfio.device_ida, device->index); - /* - * kvfree() cannot be done here due to a life cycle mess in - * vfio-ccw. Before the ccw part is fixed all drivers are - * required to support @release and call vfio_free_device() - * from there. - */ - device->ops->release(device); + if (device->ops->release) + device->ops->release(device); + + kvfree(device); } static int vfio_init_device(struct vfio_device *device, struct device *dev, @@ -424,17 +421,6 @@ out_uninit: return ret; } -/* - * The helper called by driver @release callback to free the device - * structure. Drivers which don't have private data to clean can - * simply use this helper as its @release. - */ -void vfio_free_device(struct vfio_device *device) -{ - kvfree(device); -} -EXPORT_SYMBOL_GPL(vfio_free_device); - static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev, enum vfio_group_type type) { diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ba809268a48e0..e7480154825ec 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -176,7 +176,6 @@ struct vfio_device *_vfio_alloc_device(size_t size, struct device *dev, dev, ops), \ struct dev_struct, member) -void vfio_free_device(struct vfio_device *device); static inline void vfio_put_device(struct vfio_device *device) { put_device(&device->device); diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 117a8d799f711..8b5a3a778a257 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -594,7 +594,6 @@ static void mbochs_release_dev(struct vfio_device *vdev) atomic_add(mdev_state->type->mbytes, &mbochs_avail_mbytes); kfree(mdev_state->pages); kfree(mdev_state->vconfig); - vfio_free_device(vdev); } static void mbochs_remove(struct mdev_device *mdev) diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 946e8cfde6fdd..721fb06c6413f 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -283,7 +283,6 @@ static void mdpy_release_dev(struct vfio_device *vdev) vfree(mdev_state->memblk); kfree(mdev_state->vconfig); - vfio_free_device(vdev); } static void mdpy_remove(struct mdev_device *mdev) diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index e72085fc13763..3c2a421b9b696 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -784,7 +784,6 @@ static void mtty_release_dev(struct vfio_device *vdev) atomic_add(mdev_state->nr_ports, &mdev_avail_ports); kfree(mdev_state->vconfig); - vfio_free_device(vdev); } static void mtty_remove(struct mdev_device *mdev) -- GitLab From 30b331d2e3bc5c7c95568477d4bf2661b6e6cb3e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 3 Nov 2022 22:14:40 -0700 Subject: [PATCH 0488/1480] perf lock: Allow concurrent record and report To support live monitoring of kernel lock contention without BPF, it should support something like below: # perf lock record -a -o- sleep 1 | perf lock contention -i- contended total wait max wait avg wait type caller 2 10.27 us 6.17 us 5.13 us spinlock load_balance+0xc03 1 5.29 us 5.29 us 5.29 us rwlock:W ep_scan_ready_list+0x54 1 4.12 us 4.12 us 4.12 us spinlock smpboot_thread_fn+0x116 1 3.28 us 3.28 us 3.28 us mutex pipe_read+0x50 To do that, it needs to handle HEAD_ATTR, HEADER_EVENT_UPDATE and HEADER_TRACING_DATA which are generated only for the pipe mode. And setting event handler also should be delayed until it gets the event information. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221104051440.220989-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 68 +++++++++++++++-------- tools/perf/tests/shell/lock_contention.sh | 15 ++++- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 6f79175365a80..0d280093b19a5 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -1390,6 +1390,34 @@ static int dump_info(void) return rc; } +static const struct evsel_str_handler lock_tracepoints[] = { + { "lock:lock_acquire", evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ + { "lock:lock_acquired", evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ + { "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ + { "lock:lock_release", evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ +}; + +static const struct evsel_str_handler contention_tracepoints[] = { + { "lock:contention_begin", evsel__process_contention_begin, }, + { "lock:contention_end", evsel__process_contention_end, }, +}; + +static int process_event_update(struct perf_tool *tool, + union perf_event *event, + struct evlist **pevlist) +{ + int ret; + + ret = perf_event__process_event_update(tool, event, pevlist); + if (ret < 0) + return ret; + + /* this can return -EEXIST since we call it for each evsel */ + perf_session__set_tracepoints_handlers(session, lock_tracepoints); + perf_session__set_tracepoints_handlers(session, contention_tracepoints); + return 0; +} + typedef int (*tracepoint_handler)(struct evsel *evsel, struct perf_sample *sample); @@ -1545,28 +1573,19 @@ next: print_bad_events(bad, total); } -static const struct evsel_str_handler lock_tracepoints[] = { - { "lock:lock_acquire", evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ - { "lock:lock_acquired", evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ - { "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ - { "lock:lock_release", evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ -}; - -static const struct evsel_str_handler contention_tracepoints[] = { - { "lock:contention_begin", evsel__process_contention_begin, }, - { "lock:contention_end", evsel__process_contention_end, }, -}; - static bool force; static int __cmd_report(bool display_info) { int err = -EINVAL; struct perf_tool eops = { + .attr = perf_event__process_attr, + .event_update = process_event_update, .sample = process_sample_event, .comm = perf_event__process_comm, .mmap = perf_event__process_mmap, .namespaces = perf_event__process_namespaces, + .tracing_data = perf_event__process_tracing_data, .ordered_events = true, }; struct perf_data data = { @@ -1585,17 +1604,19 @@ static int __cmd_report(bool display_info) symbol_conf.sort_by_name = true; symbol__init(&session->header.env); - if (!perf_session__has_traces(session, "lock record")) - goto out_delete; + if (!data.is_pipe) { + if (!perf_session__has_traces(session, "lock record")) + goto out_delete; - if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) { - pr_err("Initializing perf session tracepoint handlers failed\n"); - goto out_delete; - } + if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) { + pr_err("Initializing perf session tracepoint handlers failed\n"); + goto out_delete; + } - if (perf_session__set_tracepoints_handlers(session, contention_tracepoints)) { - pr_err("Initializing perf session tracepoint handlers failed\n"); - goto out_delete; + if (perf_session__set_tracepoints_handlers(session, contention_tracepoints)) { + pr_err("Initializing perf session tracepoint handlers failed\n"); + goto out_delete; + } } if (setup_output_field(false, output_fields)) @@ -1633,9 +1654,12 @@ static int __cmd_contention(int argc, const char **argv) { int err = -EINVAL; struct perf_tool eops = { + .attr = perf_event__process_attr, + .event_update = process_event_update, .sample = process_sample_event, .comm = perf_event__process_comm, .mmap = perf_event__process_mmap, + .tracing_data = perf_event__process_tracing_data, .ordered_events = true, }; struct perf_data data = { @@ -1698,7 +1722,7 @@ static int __cmd_contention(int argc, const char **argv) pr_err("lock contention BPF setup failed\n"); goto out_delete; } - } else { + } else if (!data.is_pipe) { if (!perf_session__has_traces(session, "lock record")) goto out_delete; diff --git a/tools/perf/tests/shell/lock_contention.sh b/tools/perf/tests/shell/lock_contention.sh index 04bf604e3c6f8..f7bd0d8eb5c38 100755 --- a/tools/perf/tests/shell/lock_contention.sh +++ b/tools/perf/tests/shell/lock_contention.sh @@ -53,7 +53,7 @@ test_bpf() if ! perf lock con -b true > /dev/null 2>&1 ; then echo "[Skip] No BPF support" - exit + return fi # the perf lock contention output goes to the stderr @@ -65,9 +65,22 @@ test_bpf() fi } +test_record_concurrent() +{ + echo "Testing perf lock record and perf lock contention at the same time" + perf lock record -o- -- perf bench sched messaging 2> /dev/null | \ + perf lock contention -i- -E 1 -q 2> ${result} + if [ $(cat "${result}" | wc -l) != "1" ]; then + echo "[Fail] Recorded result count is not 1:" $(cat "${result}" | wc -l) + err=1 + exit + fi +} + check test_record test_bpf +test_record_concurrent exit ${err} -- GitLab From 9d895e46842908aa49a042e699097df64ab20b7f Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Wed, 9 Nov 2022 11:39:32 +0100 Subject: [PATCH 0489/1480] perf data: Add tracepoint fields when converting to JSON When converting recorded data into JSON format, perf data omits probe variables. Add them to the output in the format "field name": "field value" using tep_print_field: $ perf data convert --to-json output.json // output.json { "linux-perf-json-version": 1, "headers": { ... }, "samples": [ { "timestamp": 29182079082999, "pid": 309194, [...] "__probe_ip": "0x93ee35", "query_string_string": "select 2;", "nxids": "0" } ] } Signed-off-by: Dmitrii Dolgov <9erthalion6@gmail.com> Acked-by: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Link: https://lore.kernel.org/r/20221109103932.65675-1-9erthalion6@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/data-convert-json.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index 613d6ae826633..57db59068cb68 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -217,6 +217,26 @@ static int process_sample_event(struct perf_tool *tool, } output_json_format(out, false, 3, "]"); + if (sample->raw_data) { + int i; + struct tep_format_field **fields; + + fields = tep_event_fields(evsel->tp_format); + if (fields) { + i = 0; + while (fields[i]) { + struct trace_seq s; + + trace_seq_init(&s); + tep_print_field(&s, sample->raw_data, fields[i]); + output_json_key_string(out, true, 3, fields[i]->name, s.buffer); + + i++; + } + free(fields); + } + } + output_json_format(out, false, 2, "}"); return 0; } -- GitLab From cf9f67b36303de65596ae7504a2a7573c08876bb Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Sat, 5 Nov 2022 22:59:32 +0900 Subject: [PATCH 0490/1480] perf print-events: Remove redundant comparison with zero Since variable npmus is unsigned int, comparing with 0 is unnecessary. Signed-off-by: Kang Minchul Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221105135932.81612-1-tegongkang@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/print-events.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index c4d5d87fae2f6..6df947df1c0fc 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -311,10 +311,8 @@ restart: if ((hybrid_supported == 0) || (hybrid_supported == npmus)) { evt_list[evt_i] = strdup(name); - if (npmus > 0) { - for (j = 0; j < npmus; j++) - zfree(&evt_pmus[j]); - } + for (j = 0; j < npmus; j++) + zfree(&evt_pmus[j]); } else { for (j = 0; j < hybrid_supported; j++) { evt_list[evt_i++] = evt_pmus[j]; -- GitLab From 612a5337ae7a87893f90de7878b20701b2b17d7d Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 20 Oct 2022 14:45:11 +0100 Subject: [PATCH 0491/1480] perf vendor events: Add Arm Neoverse V2 PMU events Rename the neoverse-n2 folder to make it clear that it includes V2, and add V2 to mapfile.csv. V2 has the same events as N2, visible by running the following command in the ARM-software/data github repo [1]: diff pmu/neoverse-v2.json pmu/neoverse-n2.json | grep code Testing: $ perf test pmu 10: PMU events : 10.1: PMU event table sanity : Ok 10.2: PMU event map aliases : Ok 10.3: Parsing of PMU event table metrics : Ok 10.4: Parsing of PMU event table metrics with fake PMUs : Ok [1]: https://github.com/ARM-software/data Reviewed-by: Nick Forrington Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20221020134512.1345013-1-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/branch.json | 0 .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/bus.json | 0 .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/cache.json | 0 .../arm64/arm/{neoverse-n2 => neoverse-n2-v2}/exception.json | 0 .../arm64/arm/{neoverse-n2 => neoverse-n2-v2}/instruction.json | 0 .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/memory.json | 0 .../arm64/arm/{neoverse-n2 => neoverse-n2-v2}/pipeline.json | 0 .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/spe.json | 0 .../arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/trace.json | 0 tools/perf/pmu-events/arch/arm64/mapfile.csv | 3 ++- 10 files changed, 2 insertions(+), 1 deletion(-) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/branch.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/bus.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/cache.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/exception.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/instruction.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/memory.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/pipeline.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/spe.json (100%) rename tools/perf/pmu-events/arch/arm64/arm/{neoverse-n2 => neoverse-n2-v2}/trace.json (100%) diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/branch.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/branch.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/branch.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/branch.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/bus.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/bus.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/bus.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/bus.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/cache.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/cache.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/cache.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/cache.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/exception.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/exception.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/exception.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/exception.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/instruction.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/instruction.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/instruction.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/instruction.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/memory.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/memory.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/memory.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/memory.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/pipeline.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/pipeline.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/pipeline.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/pipeline.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/spe.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/spe.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/spe.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/spe.json diff --git a/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/trace.json b/tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/trace.json similarity index 100% rename from tools/perf/pmu-events/arch/arm64/arm/neoverse-n2/trace.json rename to tools/perf/pmu-events/arch/arm64/arm/neoverse-n2-v2/trace.json diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv index ad502d00f4607..f134e833c069d 100644 --- a/tools/perf/pmu-events/arch/arm64/mapfile.csv +++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv @@ -34,7 +34,8 @@ 0x00000000410fd460,v1,arm/cortex-a510,core 0x00000000410fd470,v1,arm/cortex-a710,core 0x00000000410fd480,v1,arm/cortex-x2,core -0x00000000410fd490,v1,arm/neoverse-n2,core +0x00000000410fd490,v1,arm/neoverse-n2-v2,core +0x00000000410fd4f0,v1,arm/neoverse-n2-v2,core 0x00000000420f5160,v1,cavium/thunderx2,core 0x00000000430f0af0,v1,cavium/thunderx2,core 0x00000000460f0010,v1,fujitsu/a64fx,core -- GitLab From 00fb05ff87bc63a3e9000e3f7c15c86951aca76d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Nov 2022 21:05:54 +0100 Subject: [PATCH 0492/1480] usb: fotg2: add Gemini-specific handling The Cortina Systems Gemini has bolted on a PHY inside the silicon that can be handled by six bits in a MISC register in the system controller. If we are running on Gemini, look up a syscon regmap through a phandle and enable VBUS and optionally the Mini-B connector. If the device is flagged as "wakeup-source" using the standard DT bindings, we also enable this in the global controller for respective port. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221109200554.1957185-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/Kconfig | 1 + drivers/usb/fotg210/fotg210-core.c | 80 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/drivers/usb/fotg210/Kconfig b/drivers/usb/fotg210/Kconfig index 933c513b5728e..534206ee0d1db 100644 --- a/drivers/usb/fotg210/Kconfig +++ b/drivers/usb/fotg210/Kconfig @@ -5,6 +5,7 @@ config USB_FOTG210 depends on USB || USB_GADGET depends on HAS_DMA && HAS_IOMEM default ARCH_GEMINI + select MFD_SYSCON help Faraday FOTG210 is a dual-mode USB controller that can act in both host controller and peripheral controller mode. diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c index 3d07ee46f6d1d..8a54edf921ac2 100644 --- a/drivers/usb/fotg210/fotg210-core.c +++ b/drivers/usb/fotg210/fotg210-core.c @@ -5,15 +5,86 @@ * whether to proceed with probing the host or the peripheral * driver. */ +#include #include +#include #include #include #include +#include #include #include #include "fotg210.h" +/* + * Gemini-specific initialization function, only executed on the + * Gemini SoC using the global misc control register. + * + * The gemini USB blocks are connected to either Mini-A (host mode) or + * Mini-B (peripheral mode) plugs. There is no role switch support on the + * Gemini SoC, just either-or. + */ +#define GEMINI_GLOBAL_MISC_CTRL 0x30 +#define GEMINI_MISC_USB0_WAKEUP BIT(14) +#define GEMINI_MISC_USB1_WAKEUP BIT(15) +#define GEMINI_MISC_USB0_VBUS_ON BIT(22) +#define GEMINI_MISC_USB1_VBUS_ON BIT(23) +#define GEMINI_MISC_USB0_MINI_B BIT(29) +#define GEMINI_MISC_USB1_MINI_B BIT(30) + +static int fotg210_gemini_init(struct device *dev, struct resource *res, + enum usb_dr_mode mode) +{ + struct device_node *np = dev->of_node; + struct regmap *map; + bool wakeup; + u32 mask, val; + int ret; + + map = syscon_regmap_lookup_by_phandle(np, "syscon"); + if (IS_ERR(map)) { + dev_err(dev, "no syscon\n"); + return PTR_ERR(map); + } + wakeup = of_property_read_bool(np, "wakeup-source"); + + /* + * Figure out if this is USB0 or USB1 by simply checking the + * physical base address. + */ + mask = 0; + if (res->start == 0x69000000) { + mask = GEMINI_MISC_USB1_VBUS_ON | GEMINI_MISC_USB1_MINI_B | + GEMINI_MISC_USB1_WAKEUP; + if (mode == USB_DR_MODE_HOST) + val = GEMINI_MISC_USB1_VBUS_ON; + else + val = GEMINI_MISC_USB1_MINI_B; + if (wakeup) + val |= GEMINI_MISC_USB1_WAKEUP; + } else { + mask = GEMINI_MISC_USB0_VBUS_ON | GEMINI_MISC_USB0_MINI_B | + GEMINI_MISC_USB0_WAKEUP; + if (mode == USB_DR_MODE_HOST) + val = GEMINI_MISC_USB0_VBUS_ON; + else + val = GEMINI_MISC_USB0_MINI_B; + if (wakeup) + val |= GEMINI_MISC_USB0_WAKEUP; + } + + ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val); + if (ret) { + dev_err(dev, "failed to initialize Gemini PHY\n"); + return ret; + } + + dev_info(dev, "initialized Gemini PHY in %s mode\n", + (mode == USB_DR_MODE_HOST) ? "host" : "gadget"); + return 0; +} + static int fotg210_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -22,6 +93,15 @@ static int fotg210_probe(struct platform_device *pdev) mode = usb_get_dr_mode(dev); + if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) { + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ret = fotg210_gemini_init(dev, res, mode); + if (ret) + return ret; + } + if (mode == USB_DR_MODE_PERIPHERAL) ret = fotg210_udc_probe(pdev); else -- GitLab From 46ed6026ca2181c917c8334a82e3eaf40a6234dd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Nov 2022 10:03:17 +0100 Subject: [PATCH 0493/1480] usb: fotg210-udc: Fix ages old endianness issues The code in the FOTG210 driver isn't entirely endianness-agnostic as reported by the kernel robot sparse testing. This came to the surface while moving the files around. The driver is only used on little-endian systems, so this causes no real-world regression, but it is nice to be strict and have some compile coverage also on big endian machines, so fix it up with the right LE accessors. Fixes: b84a8dee23fd ("usb: gadget: add Faraday fotg210_udc driver") Reported-by: kernel test robot Link: https://lore.kernel.org/linux-usb/202211110910.0dJ7nZCn-lkp@intel.com/ Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221111090317.94228-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 7757aaa11d6f6..3c357ce42d3b1 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -630,10 +630,10 @@ static void fotg210_request_error(struct fotg210_udc *fotg210) static void fotg210_set_address(struct fotg210_udc *fotg210, struct usb_ctrlrequest *ctrl) { - if (ctrl->wValue >= 0x0100) { + if (le16_to_cpu(ctrl->wValue) >= 0x0100) { fotg210_request_error(fotg210); } else { - fotg210_set_dev_addr(fotg210, ctrl->wValue); + fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue)); fotg210_set_cxdone(fotg210); } } @@ -714,17 +714,17 @@ static void fotg210_get_status(struct fotg210_udc *fotg210, switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - fotg210->ep0_data = 1 << USB_DEVICE_SELF_POWERED; + fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED); break; case USB_RECIP_INTERFACE: - fotg210->ep0_data = 0; + fotg210->ep0_data = cpu_to_le16(0); break; case USB_RECIP_ENDPOINT: epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK; if (epnum) fotg210->ep0_data = - fotg210_is_epnstall(fotg210->ep[epnum]) - << USB_ENDPOINT_HALT; + cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum]) + << USB_ENDPOINT_HALT); else fotg210_request_error(fotg210); break; -- GitLab From 8836402d4b208b2211fc60538ff45d6bb3b73a64 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 10 Nov 2022 18:54:35 +0100 Subject: [PATCH 0494/1480] usb: Check !irq instead of irq == NO_IRQ NO_IRQ is a relic from the old days. It is not used anymore in core functions. By the way, function irq_of_parse_and_map() returns value 0 on error. In some drivers, NO_IRQ is erroneously used to check the return of irq_of_parse_and_map(). It is not a real bug today because the only architectures using the drivers being fixed by this patch define NO_IRQ as 0, but there are architectures which define NO_IRQ as -1. If one day those architectures start using the non fixed drivers, there will be a problem. Long time ago Linus advocated for not using NO_IRQ, see https://lkml.org/lkml/2005/11/21/221 . He re-iterated the same view recently in https://lkml.org/lkml/2022/10/12/622 So test !irq instead of tesing irq == NO_IRQ. Signed-off-by: Christophe Leroy Acked-by: Alan Stern Link: https://lore.kernel.org/r/13feefdf6b240817944e6441e26a8ddc1d81ced1.1668102802.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-grlib.c | 2 +- drivers/usb/host/ehci-ppc-of.c | 2 +- drivers/usb/host/fhci-hcd.c | 2 +- drivers/usb/host/ohci-ppc-of.c | 2 +- drivers/usb/host/uhci-grlib.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index a2c3b4ec8a8b5..0717f2ccf49d5 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -99,7 +99,7 @@ static int ehci_hcd_grlib_probe(struct platform_device *op) hcd->rsrc_len = resource_size(&res); irq = irq_of_parse_and_map(dn, 0); - if (irq == NO_IRQ) { + if (!irq) { dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", __FILE__); rv = -EBUSY; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 28a19693c19fe..62a0a193798c2 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -119,7 +119,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op) hcd->rsrc_len = resource_size(&res); irq = irq_of_parse_and_map(dn, 0); - if (irq == NO_IRQ) { + if (!irq) { dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", __FILE__); rv = -EBUSY; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 95a44462bed04..64a64140c2fd2 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -676,7 +676,7 @@ static int of_fhci_probe(struct platform_device *ofdev) /* USB Host interrupt. */ usb_irq = irq_of_parse_and_map(node, 0); - if (usb_irq == NO_IRQ) { + if (!usb_irq) { dev_err(dev, "could not get usb irq\n"); ret = -EINVAL; goto err_usb_irq; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 591f675cc9306..f2f6c832ec98c 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -120,7 +120,7 @@ static int ohci_hcd_ppc_of_probe(struct platform_device *op) } irq = irq_of_parse_and_map(dn, 0); - if (irq == NO_IRQ) { + if (!irq) { dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", __FILE__); rv = -EBUSY; diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 3ef6d52839e53..907d5f01edfd4 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -116,7 +116,7 @@ static int uhci_hcd_grlib_probe(struct platform_device *op) hcd->rsrc_len = resource_size(&res); irq = irq_of_parse_and_map(dn, 0); - if (irq == NO_IRQ) { + if (!irq) { printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); rv = -EBUSY; goto err_usb; -- GitLab From dd65a243a915ca319ed5fee9161a168c836fa2f2 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 10 Nov 2022 12:47:38 -0700 Subject: [PATCH 0495/1480] usb/usbip: Fix v_recv_cmd_submit() to use PIPE_BULK define Fix v_recv_cmd_submit() to use PIPE_BULK define instead of hard coded values. This also fixes the following signed integer overflow error reported by cppcheck. This is not an issue since pipe is unsigned int. However, this change improves the code to use proper define. drivers/usb/usbip/vudc_rx.c:152:26: error: Signed integer overflow for expression '3<<30'. [integerOverflow] urb_p->urb->pipe &= ~(3 << 30); In addition, add a build time check for PIPE_BULK != 3 as the code path depends on PIPE_BULK = 3. Signed-off-by: Shuah Khan Link: https://lore.kernel.org/r/20221110194738.38514-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vudc_rx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c index d4a2f30a75809..51bb70837b902 100644 --- a/drivers/usb/usbip/vudc_rx.c +++ b/drivers/usb/usbip/vudc_rx.c @@ -149,7 +149,9 @@ static int v_recv_cmd_submit(struct vudc *udc, urb_p->urb->status = -EINPROGRESS; /* FIXME: more pipe setup to please usbip_common */ - urb_p->urb->pipe &= ~(3 << 30); + BUILD_BUG_ON_MSG(PIPE_BULK != 3, "PIPE_* doesn't range from 0 to 3"); + + urb_p->urb->pipe &= ~(PIPE_BULK << 30); switch (urb_p->ep->type) { case USB_ENDPOINT_XFER_BULK: urb_p->urb->pipe |= (PIPE_BULK << 30); -- GitLab From 282a4b71816b6076029017a7bab3a9dcee12a920 Mon Sep 17 00:00:00 2001 From: Eli Billauer Date: Sun, 30 Oct 2022 11:42:09 +0200 Subject: [PATCH 0496/1480] char: xillybus: Prevent use-after-free due to race condition The driver for XillyUSB devices maintains a kref reference count on each xillyusb_dev structure, which represents a physical device. This reference count reaches zero when the device has been disconnected and there are no open file descriptors that are related to the device. When this occurs, kref_put() calls cleanup_dev(), which clears up the device's data, including the structure itself. However, when xillyusb_open() is called, this reference count becomes tricky: This function needs to obtain the xillyusb_dev structure that relates to the inode's major and minor (as there can be several such). xillybus_find_inode() (which is defined in xillybus_class.c) is called for this purpose. xillybus_find_inode() holds a mutex that is global in xillybus_class.c to protect the list of devices, and releases this mutex before returning. As a result, nothing protects the xillyusb_dev's reference counter from being decremented to zero before xillyusb_open() increments it on its own behalf. Hence the structure can be freed due to a rare race condition. To solve this, a mutex is added. It is locked by xillyusb_open() before the call to xillybus_find_inode() and is released only after the kref counter has been incremented on behalf of the newly opened inode. This protects the kref reference counters of all xillyusb_dev structs from being decremented by xillyusb_disconnect() during this time segment, as the call to kref_put() in this function is done with the same lock held. There is no need to hold the lock on other calls to kref_put(), because if xillybus_find_inode() finds a struct, xillyusb_disconnect() has not made the call to remove it, and hence not made its call to kref_put(), which takes place afterwards. Hence preventing xillyusb_disconnect's call to kref_put() is enough to ensure that the reference doesn't reach zero before it's incremented by xillyusb_open(). It would have been more natural to increment the reference count in xillybus_find_inode() of course, however this function is also called by Xillybus' driver for PCIe / OF, which registers a completely different structure. Therefore, xillybus_find_inode() treats these structures as void pointers, and accordingly can't make any changes. Reported-by: Hyunwoo Kim Suggested-by: Alan Stern Signed-off-by: Eli Billauer Link: https://lore.kernel.org/r/20221030094209.65916-1-eli.billauer@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/xillybus/xillyusb.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c index 39bcbfd908b46..5a5afa14ca8cb 100644 --- a/drivers/char/xillybus/xillyusb.c +++ b/drivers/char/xillybus/xillyusb.c @@ -184,6 +184,14 @@ struct xillyusb_dev { struct mutex process_in_mutex; /* synchronize wakeup_all() */ }; +/* + * kref_mutex is used in xillyusb_open() to prevent the xillyusb_dev + * struct from being freed during the gap between being found by + * xillybus_find_inode() and having its reference count incremented. + */ + +static DEFINE_MUTEX(kref_mutex); + /* FPGA to host opcodes */ enum { OPCODE_DATA = 0, @@ -1237,9 +1245,16 @@ static int xillyusb_open(struct inode *inode, struct file *filp) int rc; int index; + mutex_lock(&kref_mutex); + rc = xillybus_find_inode(inode, (void **)&xdev, &index); - if (rc) + if (rc) { + mutex_unlock(&kref_mutex); return rc; + } + + kref_get(&xdev->kref); + mutex_unlock(&kref_mutex); chan = &xdev->channels[index]; filp->private_data = chan; @@ -1275,8 +1290,6 @@ static int xillyusb_open(struct inode *inode, struct file *filp) ((filp->f_mode & FMODE_WRITE) && chan->open_for_write)) goto unmutex_fail; - kref_get(&xdev->kref); - if (filp->f_mode & FMODE_READ) chan->open_for_read = 1; @@ -1413,6 +1426,7 @@ unopen: return rc; unmutex_fail: + kref_put(&xdev->kref, cleanup_dev); mutex_unlock(&chan->lock); return rc; } @@ -2227,7 +2241,9 @@ static void xillyusb_disconnect(struct usb_interface *interface) xdev->dev = NULL; + mutex_lock(&kref_mutex); kref_put(&xdev->kref, cleanup_dev); + mutex_unlock(&kref_mutex); } static struct usb_driver xillyusb_driver = { -- GitLab From c42edde5de3af6285fbb38c9d503a40ef491d10d Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:37 +0200 Subject: [PATCH 0497/1480] i2c: designware: Fix slave state machine for sequential reads Some read types from I2C bus don't work correctly when testing the i2c-designware-slave.c with the slave-eeprom backend. The same reads work correctly when testing with a real 24c02 EEPROM chip. In the following tests an i2c-designware-slave.c instance with the slave-eeprom backend is configured to act as a simulated 24c02 at address 0x65 on an I2C host bus 6: 1. i2cdump -y 6 0x65 b (OK) Random read. Each byte are read using a byte address write with a current address read in a same message. 2. i2cdump -y 6 0x65 c (OK, was NOK before commit 3b5f7f10ff6e when it was repeating the 1st byte) Repeated current address read. One byte address write message followed by repeated current address read messages. 3. i2cdump -y 6 0x65 i (NOK, each 32 byte block repeats the 1st byte of block) Sequential read using SMBus Block Read. For each 32 byte block a byte address write followed by 32 sequental reads in a same message. These findings are explained because the implementation has had a mismatch between hardware interrupts and what I2C slave events should be sent after those interrupts. Despite that the case 1 happened to have always the I2C slave events sent to a right order with a right data between backend and the I2C bus. Hardware generates the DW_IC_INTR_RD_REQ interrupt when another host is attempting to read and for sequential reads after. DW_IC_INTR_RX_DONE occurs when host does not acknowledge a transmitted byte which is an indication the end of transmission. Those interrupts do not match directly with I2C_SLAVE_READ_REQUESTED and I2C_SLAVE_READ_PROCESSED events which is how the code was and is practically using them. The slave-eeprom backend increases the buffer index with the I2C_SLAVE_READ_PROCESSED event and returns the data from current index when receiving only the I2C_SLAVE_READ_REQUESTED event. That explains the repeated bytes in case 3 and also case 2 before commit 3b5f7f10ff6e ("i2c: designware: slave should do WRITE_REQUESTED before WRITE_RECEIVED"). Patch fixes the case 3 while keep cases 1 and 2 working with following changes: - First DW_IC_INTR_RD_REQ interrupt will change the state machine to read in progress state, send I2C_SLAVE_READ_REQUESTED event and transmit the first byte from backend - Subsequent DW_IC_INTR_RD_REQ interrupts will send I2C_SLAVE_READ_PROCESSED events and transmit next bytes from backend - STOP won't change the state machine. Otherwise case 2 won't work since we cannot distinguish current address read from sequentiel read - DW_IC_INTR_RX_DONE interrupt is needless since there is no mechanism to inform it to a backend. It cannot be used to change state machine at the end of read either due the same reason than above - Next host write to us will change the state machine from read to write in progress state - STATUS_WRITE_IN_PROGRESS and STATUS_READ_IN_PROGRESS are considered now to be status flags not the state of the driver. This is how we treat them in i2c-designware-master.c While at it do not test the return code from i2c_slave_event() for I2C_SLAVE_READ_REQUESTED and I2C_SLAVE_READ_PROCESSED since it returns always 0. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 1 - drivers/i2c/busses/i2c-designware-slave.c | 32 +++++++++++------------ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 4d3a3b464ecd8..dbf6bdc5f01b3 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -103,7 +103,6 @@ #define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \ DW_IC_INTR_TX_EMPTY) #define DW_IC_INTR_SLAVE_MASK (DW_IC_INTR_DEFAULT_MASK | \ - DW_IC_INTR_RX_DONE | \ DW_IC_INTR_RX_UNDER | \ DW_IC_INTR_RD_REQ) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 0d15f4c1e9f7e..1eac4f4d5573b 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -173,8 +173,9 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) enabled, slave_activity, raw_stat, stat); if (stat & DW_IC_INTR_RX_FULL) { - if (dev->status != STATUS_WRITE_IN_PROGRESS) { - dev->status = STATUS_WRITE_IN_PROGRESS; + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { + dev->status |= STATUS_WRITE_IN_PROGRESS; + dev->status &= ~STATUS_READ_IN_PROGRESS; i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED, &val); } @@ -190,24 +191,23 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) if (slave_activity) { regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp); - dev->status = STATUS_READ_IN_PROGRESS; - if (!i2c_slave_event(dev->slave, - I2C_SLAVE_READ_REQUESTED, - &val)) - regmap_write(dev->map, DW_IC_DATA_CMD, val); + if (!(dev->status & STATUS_READ_IN_PROGRESS)) { + i2c_slave_event(dev->slave, + I2C_SLAVE_READ_REQUESTED, + &val); + dev->status |= STATUS_READ_IN_PROGRESS; + dev->status &= ~STATUS_WRITE_IN_PROGRESS; + } else { + i2c_slave_event(dev->slave, + I2C_SLAVE_READ_PROCESSED, + &val); + } + regmap_write(dev->map, DW_IC_DATA_CMD, val); } } - if (stat & DW_IC_INTR_RX_DONE) { - if (!i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED, - &val)) - regmap_read(dev->map, DW_IC_CLR_RX_DONE, &tmp); - } - - if (stat & DW_IC_INTR_STOP_DET) { - dev->status = STATUS_IDLE; + if (stat & DW_IC_INTR_STOP_DET) i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val); - } return 1; } -- GitLab From dcf1bf648f94d651a3e6fb433e9ba0a3e43c1047 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:38 +0200 Subject: [PATCH 0498/1480] i2c: designware: Empty receive FIFO in slave interrupt handler Writes from I2C bus often fail when testing the i2c-designware-slave.c with the slave-eeprom backend. The same writes work correctly when testing with a real 24c02 EEPROM chip. In the tests below an i2c-designware-slave.c instance with the slave-eeprom backend is configured to act as a simulated 24c02 at address 0x65 on an I2C host bus 6. 1. i2cset -y 6 0x65 0x00 0x55 Single byte 0x55 write into address 0x00. No data goes into simulated EEPROM. Debug prints from the i2c_dw_irq_handler_slave(): 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 2. i2ctransfer -y 6 w9@0x65 0x00 0xff- Write 8 bytes with decrementing value starting from 0xff at address 0x00 and forward. Only some of the data goes into arbitrary addresses. Content is something like below but varies: 00000000 f9 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 ff fe 00 00 00 00 00 00 00 00 |................| 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fb fa |................| In this case debug prints were: 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x510 : INTR_STAT=0x0 Both cases show there is more data coming from the receive FIFO still after detecting the STOP condition. This can be seen from interrupt status bits DW_IC_INTR_STOP_DET (0x200) and DW_IC_INTR_RX_FULL (0x4). Perhaps due interrupt latencies the receive FIFO is not read fast enough, STOP detection happens synchronously when it occurs on the I2C bus and the DW_IC_INTR_RX_FULL keeps coming as long as there are more bytes in the receive FIFO. Fix this by reading the receive FIFO completely empty whenever DW_IC_INTR_RX_FULL occurs. Use RFNE, Receive FIFO Not Empty bit in the DW_IC_STATUS register to loop through bytes in the FIFO. While at it do not test the return code from i2c_slave_event() for the I2C_SLAVE_WRITE_RECEIVED since to my understanding this hardware cannot generate NACK to incoming bytes and debug print itself does not have much value. Reported-by: Tian Ye Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 1 + drivers/i2c/busses/i2c-designware-slave.c | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index dbf6bdc5f01b3..6d1df28dd93b1 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -108,6 +108,7 @@ #define DW_IC_STATUS_ACTIVITY BIT(0) #define DW_IC_STATUS_TFE BIT(2) +#define DW_IC_STATUS_RFNE BIT(3) #define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) #define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 1eac4f4d5573b..295774a69b67a 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -180,11 +180,13 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) &val); } - regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); - val = tmp; - if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED, - &val)) - dev_vdbg(dev->dev, "Byte %X acked!", val); + do { + regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); + val = tmp; + i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED, + &val); + regmap_read(dev->map, DW_IC_STATUS, &tmp); + } while (tmp & DW_IC_STATUS_RFNE); } if (stat & DW_IC_INTR_RD_REQ) { -- GitLab From 4d827824b7bb29ce944172f6297db6d7a1ec37b3 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:39 +0200 Subject: [PATCH 0499/1480] i2c: designware: Define software status flags with BIT() Define software status flags with a BIT() macro. While at it remove STATUS_IDLE and replace its use with zero initialization and status flags clearing with a mask. Suggested-by: Andy Shevchenko Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 10 +++++----- drivers/i2c/busses/i2c-designware-master.c | 4 ++-- drivers/i2c/busses/i2c-designware-slave.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 6d1df28dd93b1..457e6966f85e0 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -123,12 +123,12 @@ #define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) /* - * status codes + * Sofware status flags */ -#define STATUS_IDLE 0x0 -#define STATUS_ACTIVE 0x1 -#define STATUS_WRITE_IN_PROGRESS 0x2 -#define STATUS_READ_IN_PROGRESS 0x4 +#define STATUS_ACTIVE BIT(0) +#define STATUS_WRITE_IN_PROGRESS BIT(1) +#define STATUS_READ_IN_PROGRESS BIT(2) +#define STATUS_MASK GENMASK(2, 0) /* * operation modes diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index dc3c5a15a95b9..1b7db2b58f311 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -574,7 +574,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev->msg_write_idx = 0; dev->msg_read_idx = 0; dev->msg_err = 0; - dev->status = STATUS_IDLE; + dev->status = 0; dev->abort_source = 0; dev->rx_outstanding = 0; @@ -731,7 +731,7 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; - dev->status = STATUS_IDLE; + dev->status &= ~STATUS_MASK; dev->rx_outstanding = 0; /* diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 295774a69b67a..84eb0bec70fa0 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -82,7 +82,7 @@ static int i2c_dw_reg_slave(struct i2c_client *slave) dev->msg_write_idx = 0; dev->msg_read_idx = 0; dev->msg_err = 0; - dev->status = STATUS_IDLE; + dev->status = 0; dev->abort_source = 0; dev->rx_outstanding = 0; -- GitLab From 40015c67533548986eaba42a3d9ba9d004bee41e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:40 +0200 Subject: [PATCH 0500/1480] i2c: designware: Remove needless initializations from i2c_dw_reg_slave() These struct dw_i2c_dev members are not used in i2c-designware-slave.c so remove re-initialization of them from i2c_dw_reg_slave(). Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-slave.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 84eb0bec70fa0..421a604bf68f2 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -78,13 +78,7 @@ static int i2c_dw_reg_slave(struct i2c_client *slave) __i2c_dw_enable(dev); - dev->cmd_err = 0; - dev->msg_write_idx = 0; - dev->msg_read_idx = 0; - dev->msg_err = 0; dev->status = 0; - dev->abort_source = 0; - dev->rx_outstanding = 0; return 0; } -- GitLab From 5cd69850308f7da3c2bfc117fca5fbfa3c530ade Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:41 +0200 Subject: [PATCH 0501/1480] i2c: designware: Remove unused completion code from i2c-designware-slave Remove unused completion code from i2c-designware-slave.c. Used only in i2c-designware-master.c. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-slave.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 421a604bf68f2..12f0417aa0ae3 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -214,8 +214,6 @@ static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) int ret; ret = i2c_dw_irq_handler_slave(dev); - if (ret > 0) - complete(&dev->cmd_complete); return IRQ_RETVAL(ret); } @@ -242,8 +240,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev) struct i2c_adapter *adap = &dev->adapter; int ret; - init_completion(&dev->cmd_complete); - dev->init = i2c_dw_init_slave; dev->disable = i2c_dw_disable; dev->disable_int = i2c_dw_disable_int; -- GitLab From 4c7107c2974270ff369342f6f1bd5d3669c182f1 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:42 +0200 Subject: [PATCH 0502/1480] i2c: designware: Simplify slave interrupt handler nesting Interrupt processing code in i2c-designware-slave.c is bit more readable if not divided into another subroutine. Also explicit IRQ_NONE and IRQ_HANDLED return values are more obvious. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-slave.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 12f0417aa0ae3..3c855cd45c34c 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -147,9 +147,9 @@ static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev) * Interrupt service routine. This gets called whenever an I2C slave interrupt * occurs. */ - -static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) +static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) { + struct dw_i2c_dev *dev = dev_id; u32 raw_stat, stat, enabled, tmp; u8 val = 0, slave_activity; @@ -159,7 +159,7 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) slave_activity = ((tmp & DW_IC_STATUS_SLAVE_ACTIVITY) >> 6); if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave) - return 0; + return IRQ_NONE; stat = i2c_dw_read_clear_intrbits_slave(dev); dev_dbg(dev->dev, @@ -205,17 +205,7 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) if (stat & DW_IC_INTR_STOP_DET) i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val); - return 1; -} - -static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) -{ - struct dw_i2c_dev *dev = dev_id; - int ret; - - ret = i2c_dw_irq_handler_slave(dev); - - return IRQ_RETVAL(ret); + return IRQ_HANDLED; } static const struct i2c_algorithm i2c_dw_algo = { -- GitLab From cdbd2f169bf1aff9f679a3e07d62244fc4341968 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:43 +0200 Subject: [PATCH 0503/1480] i2c: designware: Do not process interrupt when device is suspended Do not return with interrupt handled if host controller is off and thus interrupt is originating from other device or is spurious. Add a check to detect when controller is runtime suspended or transitioning/reset. In latter case all raw interrupt status register bits may read one. In both cases return IRQ_NONE to indicate interrupt was not from this device. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-master.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 1b7db2b58f311..d6fcf955dfc0b 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -778,6 +778,8 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) return IRQ_NONE; + if (pm_runtime_suspended(dev->dev) || stat == GENMASK(31, 0)) + return IRQ_NONE; i2c_dw_irq_handler_master(dev); -- GitLab From 184c475ace922e4029f157080be559d49d70009f Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:44 +0200 Subject: [PATCH 0504/1480] i2c: designware: Move debug print in i2c_dw_isr() It is kind of needless to print interrupt status when code immediately after that finds interrupt was not originating from this device. Therefore move it after spurious interrupt detection. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index d6fcf955dfc0b..9c2c9d002dc34 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -775,11 +775,11 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) regmap_read(dev->map, DW_IC_ENABLE, &enabled); regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat); - dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) return IRQ_NONE; if (pm_runtime_suspended(dev->dev) || stat == GENMASK(31, 0)) return IRQ_NONE; + dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); i2c_dw_irq_handler_master(dev); -- GitLab From a92c3388b4ce34ee83f8ea398c1e00676a3dc467 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:45 +0200 Subject: [PATCH 0505/1480] i2c: designware: Simplify master interrupt handler nesting In my opinion a few lines of spurious interrupt detection code can be moved to the actual master interrupt handling function i2c_dw_isr() without hurting readability. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-master.c | 33 ++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 9c2c9d002dc34..dfb499e54c05d 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -711,9 +711,18 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) * Interrupt service routine. This gets called whenever an I2C master interrupt * occurs. */ -static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) +static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) { - u32 stat; + struct dw_i2c_dev *dev = dev_id; + u32 stat, enabled; + + regmap_read(dev->map, DW_IC_ENABLE, &enabled); + regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat); + if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) + return IRQ_NONE; + if (pm_runtime_suspended(dev->dev) || stat == GENMASK(31, 0)) + return IRQ_NONE; + dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); stat = i2c_dw_read_clear_intrbits(dev); @@ -726,7 +735,7 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) * the HW active). */ regmap_write(dev->map, DW_IC_INTR_MASK, 0); - return 0; + return IRQ_HANDLED; } if (stat & DW_IC_INTR_TX_ABRT) { @@ -765,24 +774,6 @@ tx_aborted: regmap_write(dev->map, DW_IC_INTR_MASK, stat); } - return 0; -} - -static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) -{ - struct dw_i2c_dev *dev = dev_id; - u32 stat, enabled; - - regmap_read(dev->map, DW_IC_ENABLE, &enabled); - regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat); - if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) - return IRQ_NONE; - if (pm_runtime_suspended(dev->dev) || stat == GENMASK(31, 0)) - return IRQ_NONE; - dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); - - i2c_dw_irq_handler_master(dev); - return IRQ_HANDLED; } -- GitLab From fee61247b7f67a628bb24314b1a3a20d1f1c60f0 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:46 +0200 Subject: [PATCH 0506/1480] i2c: designware: Remove common i2c_dw_disable_int() Commit 90312351fd1e ("i2c: designware: MASTER mode as separated driver") introduced disable_int pointer but there is no real use for it. Both i2c-designware-master.c and i2c-designware-slave.c set it to the same i2c_dw_disable_int() and scope is inside the same kernel module. Since i2c_dw_disable_int() is just masking interrupts and the direct DW_IC_INTR_MASK register write looks more clear in the code use that and remove it from common code. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-common.c | 5 ----- drivers/i2c/busses/i2c-designware-core.h | 3 --- drivers/i2c/busses/i2c-designware-master.c | 9 ++++----- drivers/i2c/busses/i2c-designware-slave.c | 3 +-- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index c023b691441ea..a3240ece55b2b 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -625,10 +625,5 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) i2c_dw_release_lock(dev); } -void i2c_dw_disable_int(struct dw_i2c_dev *dev) -{ - regmap_write(dev->map, DW_IC_INTR_MASK, 0); -} - MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 457e6966f85e0..49e5860b16651 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -232,7 +232,6 @@ struct reset_control; * -1 if there is no semaphore. * @shared_with_punit: true if this bus is shared with the SoCs PUNIT * @disable: function to disable the controller - * @disable_int: function to disable all interrupts * @init: function to initialize the I2C hardware * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE @@ -290,7 +289,6 @@ struct dw_i2c_dev { int semaphore_idx; bool shared_with_punit; void (*disable)(struct dw_i2c_dev *dev); - void (*disable_int)(struct dw_i2c_dev *dev); int (*init)(struct dw_i2c_dev *dev); int (*set_sda_hold_time)(struct dw_i2c_dev *dev); int mode; @@ -331,7 +329,6 @@ int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); u32 i2c_dw_func(struct i2c_adapter *adap); void i2c_dw_disable(struct dw_i2c_dev *dev); -void i2c_dw_disable_int(struct dw_i2c_dev *dev); static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) { diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index dfb499e54c05d..45f569155bfe1 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -239,7 +239,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) msgs[dev->msg_write_idx].addr | ic_tar); /* Enforce disabled interrupts (due to HW issues) */ - i2c_dw_disable_int(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); /* Enable the adapter */ __i2c_dw_enable(dev); @@ -299,7 +299,7 @@ static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, dev->msgs = msgs; dev->msgs_num = num_msgs; i2c_dw_xfer_init(dev); - i2c_dw_disable_int(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); /* Initiate messages read/write transaction */ for (msg_wrt_idx = 0; msg_wrt_idx < num_msgs; msg_wrt_idx++) { @@ -770,7 +770,7 @@ tx_aborted: else if (unlikely(dev->flags & ACCESS_INTR_MASK)) { /* Workaround to trigger pending interrupt */ regmap_read(dev->map, DW_IC_INTR_MASK, &stat); - i2c_dw_disable_int(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); regmap_write(dev->map, DW_IC_INTR_MASK, stat); } @@ -871,7 +871,6 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) dev->init = i2c_dw_init_master; dev->disable = i2c_dw_disable; - dev->disable_int = i2c_dw_disable_int; ret = i2c_dw_init_regmap(dev); if (ret) @@ -910,7 +909,7 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) if (ret) return ret; - i2c_dw_disable_int(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); i2c_dw_release_lock(dev); ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 3c855cd45c34c..c6d2e4c2ac23c 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -87,7 +87,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) { struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); - dev->disable_int(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); dev->disable(dev); synchronize_irq(dev->irq); dev->slave = NULL; @@ -232,7 +232,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev) dev->init = i2c_dw_init_slave; dev->disable = i2c_dw_disable; - dev->disable_int = i2c_dw_disable_int; ret = i2c_dw_init_regmap(dev); if (ret) -- GitLab From 966b7d3c738ab8d82363eff9e4c62e429697893e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:47 +0200 Subject: [PATCH 0507/1480] i2c: designware: Align defines in i2c-designware-core.h Align all defines to the same column. Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 230 +++++++++++------------ 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 49e5860b16651..0668888d557d5 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -18,12 +18,12 @@ #include #include -#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \ - I2C_FUNC_SMBUS_BYTE | \ - I2C_FUNC_SMBUS_BYTE_DATA | \ - I2C_FUNC_SMBUS_WORD_DATA | \ - I2C_FUNC_SMBUS_BLOCK_DATA | \ - I2C_FUNC_SMBUS_I2C_BLOCK) +#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK) #define DW_IC_CON_MASTER BIT(0) #define DW_IC_CON_SPEED_STD (1 << 1) @@ -43,81 +43,81 @@ /* * Registers offset */ -#define DW_IC_CON 0x00 -#define DW_IC_TAR 0x04 -#define DW_IC_SAR 0x08 -#define DW_IC_DATA_CMD 0x10 -#define DW_IC_SS_SCL_HCNT 0x14 -#define DW_IC_SS_SCL_LCNT 0x18 -#define DW_IC_FS_SCL_HCNT 0x1c -#define DW_IC_FS_SCL_LCNT 0x20 -#define DW_IC_HS_SCL_HCNT 0x24 -#define DW_IC_HS_SCL_LCNT 0x28 -#define DW_IC_INTR_STAT 0x2c -#define DW_IC_INTR_MASK 0x30 -#define DW_IC_RAW_INTR_STAT 0x34 -#define DW_IC_RX_TL 0x38 -#define DW_IC_TX_TL 0x3c -#define DW_IC_CLR_INTR 0x40 -#define DW_IC_CLR_RX_UNDER 0x44 -#define DW_IC_CLR_RX_OVER 0x48 -#define DW_IC_CLR_TX_OVER 0x4c -#define DW_IC_CLR_RD_REQ 0x50 -#define DW_IC_CLR_TX_ABRT 0x54 -#define DW_IC_CLR_RX_DONE 0x58 -#define DW_IC_CLR_ACTIVITY 0x5c -#define DW_IC_CLR_STOP_DET 0x60 -#define DW_IC_CLR_START_DET 0x64 -#define DW_IC_CLR_GEN_CALL 0x68 -#define DW_IC_ENABLE 0x6c -#define DW_IC_STATUS 0x70 -#define DW_IC_TXFLR 0x74 -#define DW_IC_RXFLR 0x78 -#define DW_IC_SDA_HOLD 0x7c -#define DW_IC_TX_ABRT_SOURCE 0x80 -#define DW_IC_ENABLE_STATUS 0x9c -#define DW_IC_CLR_RESTART_DET 0xa8 -#define DW_IC_COMP_PARAM_1 0xf4 -#define DW_IC_COMP_VERSION 0xf8 -#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A -#define DW_IC_COMP_TYPE 0xfc -#define DW_IC_COMP_TYPE_VALUE 0x44570140 - -#define DW_IC_INTR_RX_UNDER BIT(0) -#define DW_IC_INTR_RX_OVER BIT(1) -#define DW_IC_INTR_RX_FULL BIT(2) -#define DW_IC_INTR_TX_OVER BIT(3) -#define DW_IC_INTR_TX_EMPTY BIT(4) -#define DW_IC_INTR_RD_REQ BIT(5) -#define DW_IC_INTR_TX_ABRT BIT(6) -#define DW_IC_INTR_RX_DONE BIT(7) -#define DW_IC_INTR_ACTIVITY BIT(8) -#define DW_IC_INTR_STOP_DET BIT(9) -#define DW_IC_INTR_START_DET BIT(10) -#define DW_IC_INTR_GEN_CALL BIT(11) -#define DW_IC_INTR_RESTART_DET BIT(12) - -#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ - DW_IC_INTR_TX_ABRT | \ - DW_IC_INTR_STOP_DET) -#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \ - DW_IC_INTR_TX_EMPTY) -#define DW_IC_INTR_SLAVE_MASK (DW_IC_INTR_DEFAULT_MASK | \ - DW_IC_INTR_RX_UNDER | \ - DW_IC_INTR_RD_REQ) - -#define DW_IC_STATUS_ACTIVITY BIT(0) -#define DW_IC_STATUS_TFE BIT(2) -#define DW_IC_STATUS_RFNE BIT(3) -#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) -#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) - -#define DW_IC_SDA_HOLD_RX_SHIFT 16 -#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) - -#define DW_IC_ERR_TX_ABRT 0x1 - -#define DW_IC_TAR_10BITADDR_MASTER BIT(12) +#define DW_IC_CON 0x00 +#define DW_IC_TAR 0x04 +#define DW_IC_SAR 0x08 +#define DW_IC_DATA_CMD 0x10 +#define DW_IC_SS_SCL_HCNT 0x14 +#define DW_IC_SS_SCL_LCNT 0x18 +#define DW_IC_FS_SCL_HCNT 0x1c +#define DW_IC_FS_SCL_LCNT 0x20 +#define DW_IC_HS_SCL_HCNT 0x24 +#define DW_IC_HS_SCL_LCNT 0x28 +#define DW_IC_INTR_STAT 0x2c +#define DW_IC_INTR_MASK 0x30 +#define DW_IC_RAW_INTR_STAT 0x34 +#define DW_IC_RX_TL 0x38 +#define DW_IC_TX_TL 0x3c +#define DW_IC_CLR_INTR 0x40 +#define DW_IC_CLR_RX_UNDER 0x44 +#define DW_IC_CLR_RX_OVER 0x48 +#define DW_IC_CLR_TX_OVER 0x4c +#define DW_IC_CLR_RD_REQ 0x50 +#define DW_IC_CLR_TX_ABRT 0x54 +#define DW_IC_CLR_RX_DONE 0x58 +#define DW_IC_CLR_ACTIVITY 0x5c +#define DW_IC_CLR_STOP_DET 0x60 +#define DW_IC_CLR_START_DET 0x64 +#define DW_IC_CLR_GEN_CALL 0x68 +#define DW_IC_ENABLE 0x6c +#define DW_IC_STATUS 0x70 +#define DW_IC_TXFLR 0x74 +#define DW_IC_RXFLR 0x78 +#define DW_IC_SDA_HOLD 0x7c +#define DW_IC_TX_ABRT_SOURCE 0x80 +#define DW_IC_ENABLE_STATUS 0x9c +#define DW_IC_CLR_RESTART_DET 0xa8 +#define DW_IC_COMP_PARAM_1 0xf4 +#define DW_IC_COMP_VERSION 0xf8 +#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A +#define DW_IC_COMP_TYPE 0xfc +#define DW_IC_COMP_TYPE_VALUE 0x44570140 + +#define DW_IC_INTR_RX_UNDER BIT(0) +#define DW_IC_INTR_RX_OVER BIT(1) +#define DW_IC_INTR_RX_FULL BIT(2) +#define DW_IC_INTR_TX_OVER BIT(3) +#define DW_IC_INTR_TX_EMPTY BIT(4) +#define DW_IC_INTR_RD_REQ BIT(5) +#define DW_IC_INTR_TX_ABRT BIT(6) +#define DW_IC_INTR_RX_DONE BIT(7) +#define DW_IC_INTR_ACTIVITY BIT(8) +#define DW_IC_INTR_STOP_DET BIT(9) +#define DW_IC_INTR_START_DET BIT(10) +#define DW_IC_INTR_GEN_CALL BIT(11) +#define DW_IC_INTR_RESTART_DET BIT(12) + +#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ + DW_IC_INTR_TX_ABRT | \ + DW_IC_INTR_STOP_DET) +#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \ + DW_IC_INTR_TX_EMPTY) +#define DW_IC_INTR_SLAVE_MASK (DW_IC_INTR_DEFAULT_MASK | \ + DW_IC_INTR_RX_UNDER | \ + DW_IC_INTR_RD_REQ) + +#define DW_IC_STATUS_ACTIVITY BIT(0) +#define DW_IC_STATUS_TFE BIT(2) +#define DW_IC_STATUS_RFNE BIT(3) +#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) +#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) + +#define DW_IC_SDA_HOLD_RX_SHIFT 16 +#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) + +#define DW_IC_ERR_TX_ABRT 0x1 + +#define DW_IC_TAR_10BITADDR_MASTER BIT(12) #define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) #define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) @@ -125,16 +125,16 @@ /* * Sofware status flags */ -#define STATUS_ACTIVE BIT(0) -#define STATUS_WRITE_IN_PROGRESS BIT(1) -#define STATUS_READ_IN_PROGRESS BIT(2) -#define STATUS_MASK GENMASK(2, 0) +#define STATUS_ACTIVE BIT(0) +#define STATUS_WRITE_IN_PROGRESS BIT(1) +#define STATUS_READ_IN_PROGRESS BIT(2) +#define STATUS_MASK GENMASK(2, 0) /* * operation modes */ -#define DW_IC_MASTER 0 -#define DW_IC_SLAVE 1 +#define DW_IC_MASTER 0 +#define DW_IC_SLAVE 1 /* * Hardware abort codes from the DW_IC_TX_ABRT_SOURCE register @@ -142,20 +142,20 @@ * Only expected abort codes are listed here * refer to the datasheet for the full list */ -#define ABRT_7B_ADDR_NOACK 0 -#define ABRT_10ADDR1_NOACK 1 -#define ABRT_10ADDR2_NOACK 2 -#define ABRT_TXDATA_NOACK 3 -#define ABRT_GCALL_NOACK 4 -#define ABRT_GCALL_READ 5 -#define ABRT_SBYTE_ACKDET 7 -#define ABRT_SBYTE_NORSTRT 9 -#define ABRT_10B_RD_NORSTRT 10 -#define ABRT_MASTER_DIS 11 -#define ARB_LOST 12 -#define ABRT_SLAVE_FLUSH_TXFIFO 13 -#define ABRT_SLAVE_ARBLOST 14 -#define ABRT_SLAVE_RD_INTX 15 +#define ABRT_7B_ADDR_NOACK 0 +#define ABRT_10ADDR1_NOACK 1 +#define ABRT_10ADDR2_NOACK 2 +#define ABRT_TXDATA_NOACK 3 +#define ABRT_GCALL_NOACK 4 +#define ABRT_GCALL_READ 5 +#define ABRT_SBYTE_ACKDET 7 +#define ABRT_SBYTE_NORSTRT 9 +#define ABRT_10B_RD_NORSTRT 10 +#define ABRT_MASTER_DIS 11 +#define ARB_LOST 12 +#define ABRT_SLAVE_FLUSH_TXFIFO 13 +#define ABRT_SLAVE_ARBLOST 14 +#define ABRT_SLAVE_RD_INTX 15 #define DW_IC_TX_ABRT_7B_ADDR_NOACK BIT(ABRT_7B_ADDR_NOACK) #define DW_IC_TX_ABRT_10ADDR1_NOACK BIT(ABRT_10ADDR1_NOACK) @@ -172,11 +172,11 @@ #define DW_IC_RX_ABRT_SLAVE_ARBLOST BIT(ABRT_SLAVE_ARBLOST) #define DW_IC_RX_ABRT_SLAVE_FLUSH_TXFIFO BIT(ABRT_SLAVE_FLUSH_TXFIFO) -#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ - DW_IC_TX_ABRT_10ADDR1_NOACK | \ - DW_IC_TX_ABRT_10ADDR2_NOACK | \ - DW_IC_TX_ABRT_TXDATA_NOACK | \ - DW_IC_TX_ABRT_GCALL_NOACK) +#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ + DW_IC_TX_ABRT_10ADDR1_NOACK | \ + DW_IC_TX_ABRT_10ADDR2_NOACK | \ + DW_IC_TX_ABRT_TXDATA_NOACK | \ + DW_IC_TX_ABRT_GCALL_NOACK) struct clk; struct device; @@ -295,21 +295,21 @@ struct dw_i2c_dev { struct i2c_bus_recovery_info rinfo; }; -#define ACCESS_INTR_MASK BIT(0) -#define ACCESS_NO_IRQ_SUSPEND BIT(1) -#define ARBITRATION_SEMAPHORE BIT(2) +#define ACCESS_INTR_MASK BIT(0) +#define ACCESS_NO_IRQ_SUSPEND BIT(1) +#define ARBITRATION_SEMAPHORE BIT(2) -#define MODEL_MSCC_OCELOT BIT(8) -#define MODEL_BAIKAL_BT1 BIT(9) -#define MODEL_AMD_NAVI_GPU BIT(10) -#define MODEL_MASK GENMASK(11, 8) +#define MODEL_MSCC_OCELOT BIT(8) +#define MODEL_BAIKAL_BT1 BIT(9) +#define MODEL_AMD_NAVI_GPU BIT(10) +#define MODEL_MASK GENMASK(11, 8) /* * Enable UCSI interrupt by writing 0xd at register * offset 0x474 specified in hardware specification. */ -#define AMD_UCSI_INTR_REG 0x474 -#define AMD_UCSI_INTR_EN 0xd +#define AMD_UCSI_INTR_REG 0x474 +#define AMD_UCSI_INTR_EN 0xd struct i2c_dw_semaphore_callbacks { int (*probe)(struct dw_i2c_dev *dev); -- GitLab From 4bae6da1cbf4658a92e6f58da30bf536746d1e5d Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Nov 2022 15:42:48 +0200 Subject: [PATCH 0508/1480] i2c: designware: Add comment to custom register value constants DW_IC_COMP_VERSION register contains the ASCII representation of the Synopsys component version. Here 0x3131312A == "111*" means version 1.11* required for DW_IC_SDA_HOLD register availability where '*' means any letter starting from 'a'. DW_IC_COMP_TYPE is constant and is derived from two ASCII letters "DW" followed by a 16-bit unsigned number. Suggested-by: Andy Shevchenko Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 0668888d557d5..95ebc5eaa5d12 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -79,9 +79,9 @@ #define DW_IC_CLR_RESTART_DET 0xa8 #define DW_IC_COMP_PARAM_1 0xf4 #define DW_IC_COMP_VERSION 0xf8 -#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A +#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */ #define DW_IC_COMP_TYPE 0xfc -#define DW_IC_COMP_TYPE_VALUE 0x44570140 +#define DW_IC_COMP_TYPE_VALUE 0x44570140 /* "DW" + 0x0140 */ #define DW_IC_INTR_RX_UNDER BIT(0) #define DW_IC_INTR_RX_OVER BIT(1) -- GitLab From 8502bee5584235943c4d371597c740d6779991db Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Thu, 10 Nov 2022 17:23:42 +0800 Subject: [PATCH 0509/1480] i2c: imx: use devm_platform_get_and_ioremap_resource() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Reviewed-by: Mukesh Ojha Reviewed-by: Uwe Kleine-König Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 3082183bd66a4..1ce0cf7a323fa 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1449,8 +1449,7 @@ static int i2c_imx_probe(struct platform_device *pdev) if (irq < 0) return irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) return PTR_ERR(base); -- GitLab From e826192cc26bd69746bbf22e6bdf72b87cb3d97b Mon Sep 17 00:00:00 2001 From: Arminder Singh Date: Sat, 5 Nov 2022 07:56:49 -0400 Subject: [PATCH 0510/1480] i2c: /pasemi: PASemi I2C controller IRQ enablement This patch adds IRQ support to the PASemi I2C controller driver to increase the performace of I2C transactions on platforms with PASemi I2C controllers. While primarily intended for Apple silicon platforms, this patch should also help in enabling IRQ support for older PASemi hardware as well should the need arise. This version of the patch has been tested on an M1 Ultra Mac Studio, as well as an M1 MacBook Pro, and userspace launches successfully while using the IRQ path for I2C transactions. Signed-off-by: Arminder Singh Reviewed-by: Sven Peter Reviewed-by: Hector Martin Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-pasemi-core.c | 32 ++++++++++++++++++++---- drivers/i2c/busses/i2c-pasemi-core.h | 5 ++++ drivers/i2c/busses/i2c-pasemi-platform.c | 6 +++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c index 9028ffb58cc07..7d54a9f34c74b 100644 --- a/drivers/i2c/busses/i2c-pasemi-core.c +++ b/drivers/i2c/busses/i2c-pasemi-core.c @@ -21,6 +21,7 @@ #define REG_MTXFIFO 0x00 #define REG_MRXFIFO 0x04 #define REG_SMSTA 0x14 +#define REG_IMASK 0x18 #define REG_CTL 0x1c #define REG_REV 0x28 @@ -66,6 +67,7 @@ static void pasemi_reset(struct pasemi_smbus *smbus) val |= CTL_EN; reg_write(smbus, REG_CTL, val); + reinit_completion(&smbus->irq_completion); } static void pasemi_smb_clear(struct pasemi_smbus *smbus) @@ -78,14 +80,21 @@ static void pasemi_smb_clear(struct pasemi_smbus *smbus) static int pasemi_smb_waitready(struct pasemi_smbus *smbus) { - int timeout = 10; + int timeout = 100; unsigned int status; - status = reg_read(smbus, REG_SMSTA); - - while (!(status & SMSTA_XEN) && timeout--) { - msleep(1); + if (smbus->use_irq) { + reinit_completion(&smbus->irq_completion); + reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN); + wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100)); + reg_write(smbus, REG_IMASK, 0); status = reg_read(smbus, REG_SMSTA); + } else { + status = reg_read(smbus, REG_SMSTA); + while (!(status & SMSTA_XEN) && timeout--) { + msleep(1); + status = reg_read(smbus, REG_SMSTA); + } } /* Got NACK? */ @@ -344,10 +353,14 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) /* set up the sysfs linkage to our parent device */ smbus->adapter.dev.parent = smbus->dev; + smbus->use_irq = 0; + init_completion(&smbus->irq_completion); if (smbus->hw_rev != PASEMI_HW_REV_PCI) smbus->hw_rev = reg_read(smbus, REG_REV); + reg_write(smbus, REG_IMASK, 0); + pasemi_reset(smbus); error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter); @@ -356,3 +369,12 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) return 0; } + +irqreturn_t pasemi_irq_handler(int irq, void *dev_id) +{ + struct pasemi_smbus *smbus = dev_id; + + reg_write(smbus, REG_IMASK, 0); + complete(&smbus->irq_completion); + return IRQ_HANDLED; +} diff --git a/drivers/i2c/busses/i2c-pasemi-core.h b/drivers/i2c/busses/i2c-pasemi-core.h index 4655124a37f3a..88821f4e8a9f8 100644 --- a/drivers/i2c/busses/i2c-pasemi-core.h +++ b/drivers/i2c/busses/i2c-pasemi-core.h @@ -7,6 +7,7 @@ #include #include #include +#include #define PASEMI_HW_REV_PCI -1 @@ -16,6 +17,10 @@ struct pasemi_smbus { void __iomem *ioaddr; unsigned int clk_div; int hw_rev; + int use_irq; + struct completion irq_completion; }; int pasemi_i2c_common_probe(struct pasemi_smbus *smbus); + +irqreturn_t pasemi_irq_handler(int irq, void *dev_id); diff --git a/drivers/i2c/busses/i2c-pasemi-platform.c b/drivers/i2c/busses/i2c-pasemi-platform.c index 88a54aaf7e3c3..e35945a91dbef 100644 --- a/drivers/i2c/busses/i2c-pasemi-platform.c +++ b/drivers/i2c/busses/i2c-pasemi-platform.c @@ -49,6 +49,7 @@ static int pasemi_platform_i2c_probe(struct platform_device *pdev) struct pasemi_smbus *smbus; u32 frequency; int error; + int irq_num; data = devm_kzalloc(dev, sizeof(struct pasemi_platform_i2c_data), GFP_KERNEL); @@ -82,6 +83,11 @@ static int pasemi_platform_i2c_probe(struct platform_device *pdev) if (error) goto out_clk_disable; + irq_num = platform_get_irq(pdev, 0); + error = devm_request_irq(smbus->dev, irq_num, pasemi_irq_handler, 0, "pasemi_apple_i2c", (void *)smbus); + + if (!error) + smbus->use_irq = 1; platform_set_drvdata(pdev, data); return 0; -- GitLab From f613facc82cfd4b02b937b14872f24e27da4b909 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sun, 13 Nov 2022 21:10:27 +0200 Subject: [PATCH 0511/1480] mfd: vexpress-sysreg: Fix resource compound literal assignments Since DEFINE_RES_*() macros were converted to provide a compound literal the user doesn't need to repeat it. Moreover, it may not be compiled. Fixes: 52c4d11f1dce ("resource: Convert DEFINE_RES_NAMED() to be compound literal") Reported-by: kernel test robot Reported-by: Stephen Rothwell Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221113191027.2327-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/vexpress-sysreg.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index aaf24af287dd3..eab82619ec314 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c @@ -61,35 +61,27 @@ static struct mfd_cell vexpress_sysreg_cells[] = { .name = "basic-mmio-gpio", .of_compatible = "arm,vexpress-sysreg,sys_led", .num_resources = 1, - .resources = (struct resource []) { - DEFINE_RES_MEM_NAMED(SYS_LED, 0x4, "dat"), - }, + .resources = &DEFINE_RES_MEM_NAMED(SYS_LED, 0x4, "dat"), .platform_data = &vexpress_sysreg_sys_led_pdata, .pdata_size = sizeof(vexpress_sysreg_sys_led_pdata), }, { .name = "basic-mmio-gpio", .of_compatible = "arm,vexpress-sysreg,sys_mci", .num_resources = 1, - .resources = (struct resource []) { - DEFINE_RES_MEM_NAMED(SYS_MCI, 0x4, "dat"), - }, + .resources = &DEFINE_RES_MEM_NAMED(SYS_MCI, 0x4, "dat"), .platform_data = &vexpress_sysreg_sys_mci_pdata, .pdata_size = sizeof(vexpress_sysreg_sys_mci_pdata), }, { .name = "basic-mmio-gpio", .of_compatible = "arm,vexpress-sysreg,sys_flash", .num_resources = 1, - .resources = (struct resource []) { - DEFINE_RES_MEM_NAMED(SYS_FLASH, 0x4, "dat"), - }, + .resources = &DEFINE_RES_MEM_NAMED(SYS_FLASH, 0x4, "dat"), .platform_data = &vexpress_sysreg_sys_flash_pdata, .pdata_size = sizeof(vexpress_sysreg_sys_flash_pdata), }, { .name = "vexpress-syscfg", .num_resources = 1, - .resources = (struct resource []) { - DEFINE_RES_MEM(SYS_MISC, 0x4c), - }, + .resources = &DEFINE_RES_MEM(SYS_MISC, 0x4c), } }; -- GitLab From e8433659bf701b6f53a6c2168262c9b2c363c049 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Nov 2022 10:03:38 +0100 Subject: [PATCH 0512/1480] Revert "drivers: bus: simple-pm-bus: Use clocks" This reverts commit 882cf4c913d730a74175db039d941005b883de38 as it breaks the build in linux-next. Link: https://lore.kernel.org/r/20221114181752.08a850f0@canb.auug.org.au Reported-by: Stephen Rothwell Cc: Geert Uytterhoeven Cc: Liu Ying Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/bus/simple-pm-bus.c | 48 ------------------------------------- 1 file changed, 48 deletions(-) diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c index d7b043fefde9e..6b8d6257ed8a4 100644 --- a/drivers/bus/simple-pm-bus.c +++ b/drivers/bus/simple-pm-bus.c @@ -8,24 +8,17 @@ * for more details. */ -#include #include #include #include #include -struct simple_pm_bus { - struct clk_bulk_data *clks; - int num_clks; -}; - static int simple_pm_bus_probe(struct platform_device *pdev) { const struct device *dev = &pdev->dev; const struct of_dev_auxdata *lookup = dev_get_platdata(dev); struct device_node *np = dev->of_node; const struct of_device_id *match; - struct simple_pm_bus *bus; /* * Allow user to use driver_override to bind this driver to a @@ -51,16 +44,6 @@ static int simple_pm_bus_probe(struct platform_device *pdev) return -ENODEV; } - bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); - if (!bus) - return -ENOMEM; - - bus->num_clks = devm_clk_bulk_get_all(&pdev->dev, &bus->clks); - if (bus->num_clks < 0) - return dev_err_probe(&pdev->dev, bus->num_clks, "failed to get clocks\n"); - - dev_set_drvdata(&pdev->dev, bus); - dev_dbg(&pdev->dev, "%s\n", __func__); pm_runtime_enable(&pdev->dev); @@ -84,36 +67,6 @@ static int simple_pm_bus_remove(struct platform_device *pdev) return 0; } -static int simple_pm_bus_runtime_suspend(struct device *dev) -{ - struct simple_pm_bus *bus = dev_get_drvdata(dev); - - clk_bulk_disable_unprepare(bus->num_clks, bus->clks); - - return 0; -} - -static int simple_pm_bus_runtime_resume(struct device *dev) -{ - struct simple_pm_bus *bus = dev_get_drvdata(dev); - int ret; - - ret = clk_bulk_prepare_enable(bus->num_clks, bus->clks); - if (ret) { - dev_err(dev, "failed to enable clocks: %d\n", ret); - return ret; - } - - return 0; -} - -static const struct dev_pm_ops simple_pm_bus_pm_ops = { - SET_RUNTIME_PM_OPS(simple_pm_bus_runtime_suspend, - simple_pm_bus_runtime_resume, NULL) - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) -}; - #define ONLY_BUS ((void *) 1) /* Match if the device is only a bus. */ static const struct of_device_id simple_pm_bus_of_match[] = { @@ -132,7 +85,6 @@ static struct platform_driver simple_pm_bus_driver = { .driver = { .name = "simple-pm-bus", .of_match_table = simple_pm_bus_of_match, - .pm = &simple_pm_bus_pm_ops, }, }; -- GitLab From 4529992c947401adac53111cf15958a7ea97b1ef Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:06 -0800 Subject: [PATCH 0513/1480] interconnect: qcom: osm-l3: Use platform-independent node ids The identifiers used for nodes needs to be unique in the running system, but defining them per platform results in a lot of duplicated definitions and prevents us from using generic compatibles. As these identifiers are not exposed outside the kernel, change to use driver-local numbers, picked completely at random. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-2-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/osm-l3.c | 87 +++++++++++------------------- 1 file changed, 30 insertions(+), 57 deletions(-) diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index ddbdf0943f94e..d23769844419c 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -74,6 +74,11 @@ struct qcom_osm_l3_desc { unsigned int reg_perf_state; }; +enum { + OSM_L3_MASTER_NODE = 10000, + OSM_L3_SLAVE_NODE, +}; + #define DEFINE_QNODE(_name, _id, _buswidth, ...) \ static const struct qcom_osm_l3_node _name = { \ .name = #_name, \ @@ -83,97 +88,65 @@ struct qcom_osm_l3_desc { .links = { __VA_ARGS__ }, \ } -DEFINE_QNODE(sdm845_osm_apps_l3, SDM845_MASTER_OSM_L3_APPS, 16, SDM845_SLAVE_OSM_L3); -DEFINE_QNODE(sdm845_osm_l3, SDM845_SLAVE_OSM_L3, 16); +DEFINE_QNODE(osm_l3_master, OSM_L3_MASTER_NODE, 16, OSM_L3_SLAVE_NODE); +DEFINE_QNODE(osm_l3_slave, OSM_L3_SLAVE_NODE, 16); + +static const struct qcom_osm_l3_node * const osm_l3_nodes[] = { + [MASTER_OSM_L3_APPS] = &osm_l3_master, + [SLAVE_OSM_L3] = &osm_l3_slave, +}; + +DEFINE_QNODE(epss_l3_master, OSM_L3_MASTER_NODE, 32, OSM_L3_SLAVE_NODE); +DEFINE_QNODE(epss_l3_slave, OSM_L3_SLAVE_NODE, 32); -static const struct qcom_osm_l3_node * const sdm845_osm_l3_nodes[] = { - [MASTER_OSM_L3_APPS] = &sdm845_osm_apps_l3, - [SLAVE_OSM_L3] = &sdm845_osm_l3, +static const struct qcom_osm_l3_node * const epss_l3_nodes[] = { + [MASTER_EPSS_L3_APPS] = &epss_l3_master, + [SLAVE_EPSS_L3_SHARED] = &epss_l3_slave, }; static const struct qcom_osm_l3_desc sdm845_icc_osm_l3 = { - .nodes = sdm845_osm_l3_nodes, - .num_nodes = ARRAY_SIZE(sdm845_osm_l3_nodes), + .nodes = osm_l3_nodes, + .num_nodes = ARRAY_SIZE(osm_l3_nodes), .lut_row_size = OSM_LUT_ROW_SIZE, .reg_freq_lut = OSM_REG_FREQ_LUT, .reg_perf_state = OSM_REG_PERF_STATE, }; -DEFINE_QNODE(sc7180_osm_apps_l3, SC7180_MASTER_OSM_L3_APPS, 16, SC7180_SLAVE_OSM_L3); -DEFINE_QNODE(sc7180_osm_l3, SC7180_SLAVE_OSM_L3, 16); - -static const struct qcom_osm_l3_node * const sc7180_osm_l3_nodes[] = { - [MASTER_OSM_L3_APPS] = &sc7180_osm_apps_l3, - [SLAVE_OSM_L3] = &sc7180_osm_l3, -}; - static const struct qcom_osm_l3_desc sc7180_icc_osm_l3 = { - .nodes = sc7180_osm_l3_nodes, - .num_nodes = ARRAY_SIZE(sc7180_osm_l3_nodes), + .nodes = osm_l3_nodes, + .num_nodes = ARRAY_SIZE(osm_l3_nodes), .lut_row_size = OSM_LUT_ROW_SIZE, .reg_freq_lut = OSM_REG_FREQ_LUT, .reg_perf_state = OSM_REG_PERF_STATE, }; -DEFINE_QNODE(sc7280_epss_apps_l3, SC7280_MASTER_EPSS_L3_APPS, 32, SC7280_SLAVE_EPSS_L3); -DEFINE_QNODE(sc7280_epss_l3, SC7280_SLAVE_EPSS_L3, 32); - -static const struct qcom_osm_l3_node * const sc7280_epss_l3_nodes[] = { - [MASTER_EPSS_L3_APPS] = &sc7280_epss_apps_l3, - [SLAVE_EPSS_L3_SHARED] = &sc7280_epss_l3, -}; - static const struct qcom_osm_l3_desc sc7280_icc_epss_l3 = { - .nodes = sc7280_epss_l3_nodes, - .num_nodes = ARRAY_SIZE(sc7280_epss_l3_nodes), + .nodes = epss_l3_nodes, + .num_nodes = ARRAY_SIZE(epss_l3_nodes), .lut_row_size = EPSS_LUT_ROW_SIZE, .reg_freq_lut = EPSS_REG_FREQ_LUT, .reg_perf_state = EPSS_REG_PERF_STATE, }; -DEFINE_QNODE(sc8180x_osm_apps_l3, SC8180X_MASTER_OSM_L3_APPS, 32, SC8180X_SLAVE_OSM_L3); -DEFINE_QNODE(sc8180x_osm_l3, SC8180X_SLAVE_OSM_L3, 32); - -static const struct qcom_osm_l3_node * const sc8180x_osm_l3_nodes[] = { - [MASTER_OSM_L3_APPS] = &sc8180x_osm_apps_l3, - [SLAVE_OSM_L3] = &sc8180x_osm_l3, -}; - static const struct qcom_osm_l3_desc sc8180x_icc_osm_l3 = { - .nodes = sc8180x_osm_l3_nodes, - .num_nodes = ARRAY_SIZE(sc8180x_osm_l3_nodes), + .nodes = osm_l3_nodes, + .num_nodes = ARRAY_SIZE(osm_l3_nodes), .lut_row_size = OSM_LUT_ROW_SIZE, .reg_freq_lut = OSM_REG_FREQ_LUT, .reg_perf_state = OSM_REG_PERF_STATE, }; -DEFINE_QNODE(sm8150_osm_apps_l3, SM8150_MASTER_OSM_L3_APPS, 32, SM8150_SLAVE_OSM_L3); -DEFINE_QNODE(sm8150_osm_l3, SM8150_SLAVE_OSM_L3, 32); - -static const struct qcom_osm_l3_node * const sm8150_osm_l3_nodes[] = { - [MASTER_OSM_L3_APPS] = &sm8150_osm_apps_l3, - [SLAVE_OSM_L3] = &sm8150_osm_l3, -}; - static const struct qcom_osm_l3_desc sm8150_icc_osm_l3 = { - .nodes = sm8150_osm_l3_nodes, - .num_nodes = ARRAY_SIZE(sm8150_osm_l3_nodes), + .nodes = osm_l3_nodes, + .num_nodes = ARRAY_SIZE(osm_l3_nodes), .lut_row_size = OSM_LUT_ROW_SIZE, .reg_freq_lut = OSM_REG_FREQ_LUT, .reg_perf_state = OSM_REG_PERF_STATE, }; -DEFINE_QNODE(sm8250_epss_apps_l3, SM8250_MASTER_EPSS_L3_APPS, 32, SM8250_SLAVE_EPSS_L3); -DEFINE_QNODE(sm8250_epss_l3, SM8250_SLAVE_EPSS_L3, 32); - -static const struct qcom_osm_l3_node * const sm8250_epss_l3_nodes[] = { - [MASTER_EPSS_L3_APPS] = &sm8250_epss_apps_l3, - [SLAVE_EPSS_L3_SHARED] = &sm8250_epss_l3, -}; - static const struct qcom_osm_l3_desc sm8250_icc_epss_l3 = { - .nodes = sm8250_epss_l3_nodes, - .num_nodes = ARRAY_SIZE(sm8250_epss_l3_nodes), + .nodes = epss_l3_nodes, + .num_nodes = ARRAY_SIZE(epss_l3_nodes), .lut_row_size = EPSS_LUT_ROW_SIZE, .reg_freq_lut = EPSS_REG_FREQ_LUT, .reg_perf_state = EPSS_REG_PERF_STATE, -- GitLab From d623264f62d40ca2d2380437f8a6318a2a9e4c66 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:07 -0800 Subject: [PATCH 0514/1480] interconnect: qcom: osm-l3: Squash common descriptors Each platform defines their own OSM L3 descriptor, but in practice there's only two: one for OSM and one for EPSS. Remove the duplicated definitions. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-3-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/osm-l3.c | 48 +++++------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index d23769844419c..7d68442532412 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -104,7 +104,7 @@ static const struct qcom_osm_l3_node * const epss_l3_nodes[] = { [SLAVE_EPSS_L3_SHARED] = &epss_l3_slave, }; -static const struct qcom_osm_l3_desc sdm845_icc_osm_l3 = { +static const struct qcom_osm_l3_desc osm_l3 = { .nodes = osm_l3_nodes, .num_nodes = ARRAY_SIZE(osm_l3_nodes), .lut_row_size = OSM_LUT_ROW_SIZE, @@ -112,39 +112,7 @@ static const struct qcom_osm_l3_desc sdm845_icc_osm_l3 = { .reg_perf_state = OSM_REG_PERF_STATE, }; -static const struct qcom_osm_l3_desc sc7180_icc_osm_l3 = { - .nodes = osm_l3_nodes, - .num_nodes = ARRAY_SIZE(osm_l3_nodes), - .lut_row_size = OSM_LUT_ROW_SIZE, - .reg_freq_lut = OSM_REG_FREQ_LUT, - .reg_perf_state = OSM_REG_PERF_STATE, -}; - -static const struct qcom_osm_l3_desc sc7280_icc_epss_l3 = { - .nodes = epss_l3_nodes, - .num_nodes = ARRAY_SIZE(epss_l3_nodes), - .lut_row_size = EPSS_LUT_ROW_SIZE, - .reg_freq_lut = EPSS_REG_FREQ_LUT, - .reg_perf_state = EPSS_REG_PERF_STATE, -}; - -static const struct qcom_osm_l3_desc sc8180x_icc_osm_l3 = { - .nodes = osm_l3_nodes, - .num_nodes = ARRAY_SIZE(osm_l3_nodes), - .lut_row_size = OSM_LUT_ROW_SIZE, - .reg_freq_lut = OSM_REG_FREQ_LUT, - .reg_perf_state = OSM_REG_PERF_STATE, -}; - -static const struct qcom_osm_l3_desc sm8150_icc_osm_l3 = { - .nodes = osm_l3_nodes, - .num_nodes = ARRAY_SIZE(osm_l3_nodes), - .lut_row_size = OSM_LUT_ROW_SIZE, - .reg_freq_lut = OSM_REG_FREQ_LUT, - .reg_perf_state = OSM_REG_PERF_STATE, -}; - -static const struct qcom_osm_l3_desc sm8250_icc_epss_l3 = { +static const struct qcom_osm_l3_desc epss_l3 = { .nodes = epss_l3_nodes, .num_nodes = ARRAY_SIZE(epss_l3_nodes), .lut_row_size = EPSS_LUT_ROW_SIZE, @@ -317,12 +285,12 @@ err: } static const struct of_device_id osm_l3_of_match[] = { - { .compatible = "qcom,sc7180-osm-l3", .data = &sc7180_icc_osm_l3 }, - { .compatible = "qcom,sc7280-epss-l3", .data = &sc7280_icc_epss_l3 }, - { .compatible = "qcom,sdm845-osm-l3", .data = &sdm845_icc_osm_l3 }, - { .compatible = "qcom,sm8150-osm-l3", .data = &sm8150_icc_osm_l3 }, - { .compatible = "qcom,sc8180x-osm-l3", .data = &sc8180x_icc_osm_l3 }, - { .compatible = "qcom,sm8250-epss-l3", .data = &sm8250_icc_epss_l3 }, + { .compatible = "qcom,sc7180-osm-l3", .data = &osm_l3 }, + { .compatible = "qcom,sc7280-epss-l3", .data = &epss_l3 }, + { .compatible = "qcom,sdm845-osm-l3", .data = &osm_l3 }, + { .compatible = "qcom,sm8150-osm-l3", .data = &osm_l3 }, + { .compatible = "qcom,sc8180x-osm-l3", .data = &osm_l3 }, + { .compatible = "qcom,sm8250-epss-l3", .data = &epss_l3 }, { } }; MODULE_DEVICE_TABLE(of, osm_l3_of_match); -- GitLab From 9235253ec73dfd71cc83d154693476930fc8dd77 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:08 -0800 Subject: [PATCH 0515/1480] interconnect: qcom: osm-l3: Add per-core EPSS L3 support The EPSS instance in e.g. SM8350 and SC8280XP has per-core L3 voting enabled. In this configuration, the "shared" vote is done using the REG_L3_VOTE register instead of PERF_STATE. Rename epss_l3 to clarify that it's affecting the PERF_STATE register and add a new L3_VOTE description. Given platform lineage it's assumed that the L3_VOTE-based case will be the predominant one, so use this for a new generic qcom,epss-l3 compatible. While adding the EPSS generic, also add qcom,osm-l3. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-4-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/osm-l3.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index 7d68442532412..469be732a00bb 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -34,6 +34,7 @@ /* EPSS Register offsets */ #define EPSS_LUT_ROW_SIZE 4 +#define EPSS_REG_L3_VOTE 0x90 #define EPSS_REG_FREQ_LUT 0x100 #define EPSS_REG_PERF_STATE 0x320 @@ -112,7 +113,7 @@ static const struct qcom_osm_l3_desc osm_l3 = { .reg_perf_state = OSM_REG_PERF_STATE, }; -static const struct qcom_osm_l3_desc epss_l3 = { +static const struct qcom_osm_l3_desc epss_l3_perf_state = { .nodes = epss_l3_nodes, .num_nodes = ARRAY_SIZE(epss_l3_nodes), .lut_row_size = EPSS_LUT_ROW_SIZE, @@ -120,6 +121,14 @@ static const struct qcom_osm_l3_desc epss_l3 = { .reg_perf_state = EPSS_REG_PERF_STATE, }; +static const struct qcom_osm_l3_desc epss_l3_l3_vote = { + .nodes = epss_l3_nodes, + .num_nodes = ARRAY_SIZE(epss_l3_nodes), + .lut_row_size = EPSS_LUT_ROW_SIZE, + .reg_freq_lut = EPSS_REG_FREQ_LUT, + .reg_perf_state = EPSS_REG_L3_VOTE, +}; + static int qcom_osm_l3_set(struct icc_node *src, struct icc_node *dst) { struct qcom_osm_l3_icc_provider *qp; @@ -285,12 +294,14 @@ err: } static const struct of_device_id osm_l3_of_match[] = { + { .compatible = "qcom,epss-l3", .data = &epss_l3_l3_vote }, + { .compatible = "qcom,osm-l3", .data = &osm_l3 }, { .compatible = "qcom,sc7180-osm-l3", .data = &osm_l3 }, - { .compatible = "qcom,sc7280-epss-l3", .data = &epss_l3 }, + { .compatible = "qcom,sc7280-epss-l3", .data = &epss_l3_perf_state }, { .compatible = "qcom,sdm845-osm-l3", .data = &osm_l3 }, { .compatible = "qcom,sm8150-osm-l3", .data = &osm_l3 }, { .compatible = "qcom,sc8180x-osm-l3", .data = &osm_l3 }, - { .compatible = "qcom,sm8250-epss-l3", .data = &epss_l3 }, + { .compatible = "qcom,sm8250-epss-l3", .data = &epss_l3_perf_state }, { } }; MODULE_DEVICE_TABLE(of, osm_l3_of_match); -- GitLab From b6bcef163ae0c4329187eea8431a735a60b1d7bb Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:09 -0800 Subject: [PATCH 0516/1480] interconnect: qcom: osm-l3: Simplify osm_l3_set() The aggregation over votes for all nodes in the provider will always only find the bandwidth votes for the destination side of the path. Further more, the average kBps value will always be 0. Simplify the logic by directly looking at the destination node's peak bandwidth request. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-5-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/osm-l3.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index 469be732a00bb..5fa1710874258 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -134,22 +134,14 @@ static int qcom_osm_l3_set(struct icc_node *src, struct icc_node *dst) struct qcom_osm_l3_icc_provider *qp; struct icc_provider *provider; const struct qcom_osm_l3_node *qn; - struct icc_node *n; unsigned int index; - u32 agg_peak = 0; - u32 agg_avg = 0; u64 rate; qn = src->data; provider = src->provider; qp = to_osm_l3_provider(provider); - list_for_each_entry(n, &provider->nodes, node_list) - provider->aggregate(n, 0, n->avg_bw, n->peak_bw, - &agg_avg, &agg_peak); - - rate = max(agg_avg, agg_peak); - rate = icc_units_to_bps(rate); + rate = icc_units_to_bps(dst->peak_bw); do_div(rate, qn->buswidth); for (index = 0; index < qp->max_state - 1; index++) { -- GitLab From 4ea0be1f0db588afdb2d4d94dfa921b01f34a3c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:07 -0800 Subject: [PATCH 0517/1480] perf stat: Increase metric length to align outputs When perf stat is called with very detailed events, the output doesn't align well like below: $ sudo perf stat -a -ddd sleep 1 Performance counter stats for 'system wide': 8,020.23 msec cpu-clock # 7.997 CPUs utilized 3,970 context-switches # 494.998 /sec 169 cpu-migrations # 21.072 /sec 586 page-faults # 73.065 /sec 649,568,060 cycles # 0.081 GHz (30.42%) 304,044,345 instructions # 0.47 insn per cycle (38.40%) 60,313,022 branches # 7.520 M/sec (38.89%) 2,766,919 branch-misses # 4.59% of all branches (39.26%) 74,422,951 L1-dcache-loads # 9.279 M/sec (39.39%) 8,025,568 L1-dcache-load-misses # 10.78% of all L1-dcache accesses (39.22%) 3,314,995 LLC-loads # 413.329 K/sec (30.83%) 1,225,619 LLC-load-misses # 36.97% of all LL-cache accesses (30.45%) L1-icache-loads 20,420,493 L1-icache-load-misses # 0.00% of all L1-icache accesses (30.29%) 58,017,947 dTLB-loads # 7.234 M/sec (30.37%) 704,677 dTLB-load-misses # 1.21% of all dTLB cache accesses (30.27%) 234,225 iTLB-loads # 29.204 K/sec (30.29%) 417,166 iTLB-load-misses # 178.10% of all iTLB cache accesses (30.32%) L1-dcache-prefetches L1-dcache-prefetch-misses 1.002947355 seconds time elapsed Increase the METRIC_LEN by 3 so that it can align properly. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 657434cd29eea..576283afa319c 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -218,7 +218,7 @@ struct outstate { struct evsel *evsel; }; -#define METRIC_LEN 35 +#define METRIC_LEN 38 static void new_line_std(struct perf_stat_config *config __maybe_unused, void *ctx) -- GitLab From 81a02c6577ecfee7056ccafbd028984d0d670c0c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:08 -0800 Subject: [PATCH 0518/1480] perf stat: Clear screen only if output file is a tty The --interval-clear option makes perf stat to clear the terminal at each interval. But it doesn't need to clear the screen when it saves to a file. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 576283afa319c..ccb804546d5a3 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -890,7 +890,7 @@ static void print_interval(struct perf_stat_config *config, FILE *output = config->output; static int num_print_interval; - if (config->interval_clear) + if (config->interval_clear && isatty(fileno(output))) puts(CONSOLE_CLEAR); if (!config->iostat_run && !config->json_output) -- GitLab From f4e55f88da923f39f0b76edc3da3c52d0b72d429 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:09 -0800 Subject: [PATCH 0519/1480] perf stat: Move common code in print_metric_headers() The struct perf_stat_output_ctx is set in a loop with the same values. Move the code out of the loop and keep the loop minimal. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index ccb804546d5a3..173f4715189c9 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -835,11 +835,16 @@ static void print_metric_headers(struct perf_stat_config *config, struct evlist *evlist, const char *prefix, bool no_indent) { - struct perf_stat_output_ctx out; struct evsel *counter; struct outstate os = { .fh = config->output }; + struct perf_stat_output_ctx out = { + .ctx = &os, + .print_metric = print_metric_header, + .new_line = new_line_metric, + .force_header = true, + }; bool first = true; if (config->json_output && !config->interval) @@ -863,13 +868,11 @@ static void print_metric_headers(struct perf_stat_config *config, /* Print metrics headers only */ evlist__for_each_entry(evlist, counter) { os.evsel = counter; - out.ctx = &os; - out.print_metric = print_metric_header; + if (!first && config->json_output) fprintf(config->output, ", "); first = false; - out.new_line = new_line_metric; - out.force_header = true; + perf_stat__print_shadow_stats(config, counter, 0, 0, &out, -- GitLab From fdc7d6082459aa6705dd39b827214f6cfc1fa054 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:10 -0800 Subject: [PATCH 0520/1480] perf stat: Fix --metric-only --json output Currently it prints all metric headers for JSON output. But actually it skips some metrics with valid_only_metric(). So the output looks like: $ perf stat --metric-only --json true {"unit" : "CPUs utilized", "unit" : "/sec", "unit" : "/sec", "unit" : "/sec", "unit" : "GHz", "unit" : "insn per cycle", "unit" : "/sec", "unit" : "branch-misses of all branches"} {"metric-value" : "3.861"}{"metric-value" : "0.79"}{"metric-value" : "3.04"} As you can see there are 8 units in the header but only 3 metric-values are there. It should skip the unused headers as well. Also each unit should be printed as a separate object like metric values. With this patch: $ perf stat --metric-only --json true {"unit" : "GHz"}{"unit" : "insn per cycle"}{"unit" : "branch-misses of all branches"} {"metric-value" : "4.166"}{"metric-value" : "0.73"}{"metric-value" : "2.96"} Fixes: df936cadfb58ba93 ("perf stat: Add JSON output option") Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Claire Jensen Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 173f4715189c9..5c10cf49fd12c 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -430,12 +430,12 @@ static void print_metric_header(struct perf_stat_config *config, os->evsel->priv != os->evsel->evlist->selected->priv) return; - if (!valid_only_metric(unit) && !config->json_output) + if (!valid_only_metric(unit)) return; unit = fixunit(tbuf, os->evsel, unit); if (config->json_output) - fprintf(os->fh, "\"unit\" : \"%s\"", unit); + fprintf(os->fh, "{\"unit\" : \"%s\"}", unit); else if (config->csv_output) fprintf(os->fh, "%s%s", unit, config->csv_sep); else @@ -845,10 +845,6 @@ static void print_metric_headers(struct perf_stat_config *config, .new_line = new_line_metric, .force_header = true, }; - bool first = true; - - if (config->json_output && !config->interval) - fprintf(config->output, "{"); if (prefix && !config->json_output) fprintf(config->output, "%s", prefix); @@ -869,18 +865,12 @@ static void print_metric_headers(struct perf_stat_config *config, evlist__for_each_entry(evlist, counter) { os.evsel = counter; - if (!first && config->json_output) - fprintf(config->output, ", "); - first = false; - perf_stat__print_shadow_stats(config, counter, 0, 0, &out, &config->metric_events, &rt_stat); } - if (config->json_output) - fprintf(config->output, "}"); fputc('\n', config->output); } @@ -952,14 +942,8 @@ static void print_interval(struct perf_stat_config *config, } } - if ((num_print_interval == 0 || config->interval_clear) - && metric_only && !config->json_output) + if ((num_print_interval == 0 || config->interval_clear) && metric_only) print_metric_headers(config, evlist, " ", true); - if ((num_print_interval == 0 || config->interval_clear) - && metric_only && config->json_output) { - fprintf(output, "{"); - print_metric_headers(config, evlist, " ", true); - } if (++num_print_interval == 25) num_print_interval = 0; } -- GitLab From 6d0a7e394eabd456f70c2f2f8e958b2343074360 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:11 -0800 Subject: [PATCH 0521/1480] perf stat: Do not indent headers for JSON Currently --metric-only with --json indents header lines. This is not needed for JSON. $ perf stat -aA --metric-only -j true {"unit" : "GHz"}{"unit" : "insn per cycle"}{"unit" : "branch-misses of all branches"} {"cpu" : "0", {"metric-value" : "0.101"}{"metric-value" : "0.86"}{"metric-value" : "1.91"} {"cpu" : "1", {"metric-value" : "0.102"}{"metric-value" : "0.87"}{"metric-value" : "2.02"} {"cpu" : "2", {"metric-value" : "0.085"}{"metric-value" : "1.02"}{"metric-value" : "1.69"} ... Note that the other lines are broken JSON, but it will be handled later. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 5c10cf49fd12c..99bc0db8f068a 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -849,7 +849,7 @@ static void print_metric_headers(struct perf_stat_config *config, if (prefix && !config->json_output) fprintf(config->output, "%s", prefix); - if (!config->csv_output && !no_indent) + if (!config->csv_output && !config->json_output && !no_indent) fprintf(config->output, "%*s", aggr_header_lens[config->aggr_mode], ""); if (config->csv_output) { -- GitLab From 1cc7642abba7b281ecd836bfb56fc6dedac32555 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:12 -0800 Subject: [PATCH 0522/1480] perf stat: Add header for interval in JSON output It missed to print a matching header line for intervals. Before: # perf stat -a -e cycles,instructions --metric-only -j -I 500 {"unit" : "insn per cycle"} {"interval" : 0.500544283}{"metric-value" : "1.96"} ^C After: # perf stat -a -e cycles,instructions --metric-only -j -I 500 {"unit" : "sec"}{"unit" : "insn per cycle"} {"interval" : 0.500515681}{"metric-value" : "2.31"} ^C Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 99bc0db8f068a..2a08c66121ec5 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -858,6 +858,10 @@ static void print_metric_headers(struct perf_stat_config *config, if (!config->iostat_run) fputs(aggr_header_csv[config->aggr_mode], config->output); } + if (config->json_output) { + if (config->interval) + fputs("{\"unit\" : \"sec\"}", config->output); + } if (config->iostat_run) iostat_print_header_prefix(config); -- GitLab From f1db5a1d1d4de248534567fd95efa570bc693f73 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:13 -0800 Subject: [PATCH 0523/1480] perf stat: Fix condition in print_interval() The num_print_interval and config->interval_clear should be checked together like other places like later in the function. Otherwise, the --interval-clear option could print the headers for the CSV or JSON output unnecessarily. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 2a08c66121ec5..7b2ec400813e9 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -900,8 +900,8 @@ static void print_interval(struct perf_stat_config *config, sprintf(prefix, "{\"interval\" : %lu.%09lu}", (unsigned long) ts->tv_sec, ts->tv_nsec); - if ((num_print_interval == 0 && !config->csv_output && !config->json_output) - || config->interval_clear) { + if ((num_print_interval == 0 || config->interval_clear) && + !config->csv_output && !config->json_output) { switch (config->aggr_mode) { case AGGR_NODE: fprintf(output, "# time node cpus"); -- GitLab From 20e2e31779377b36ada04c06d572ce0b4e234bb1 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Nov 2022 13:33:14 -0800 Subject: [PATCH 0524/1480] perf stat: Consolidate condition to print metrics The pm variable holds an appropriate function to print metrics for CSV anf JSON already. So we can combine the if statement to simplify the code a little bit. This also matches to the above condition for non-CSV and non-JSON case. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221107213314.3239159-10-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 7b2ec400813e9..cb2a116bded6d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -600,9 +600,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int pm(config, &os, NULL, NULL, "", 0); print_noise(config, counter, noise); print_running(config, run, ena); - if (config->csv_output) - pm(config, &os, NULL, NULL, "", 0); - else if (config->json_output) + if (config->csv_output || config->json_output) pm(config, &os, NULL, NULL, "", 0); return; } -- GitLab From 4e016f969529f2aec0545e90119e7eb3cb124c46 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Sun, 6 Nov 2022 19:46:18 +0200 Subject: [PATCH 0525/1480] vfio: Add an option to get migration data size Add an option to get migration data size by introducing a new migration feature named VFIO_DEVICE_FEATURE_MIG_DATA_SIZE. Upon VFIO_DEVICE_FEATURE_GET the estimated data length that will be required to complete STOP_COPY is returned. This option may better enable user space to consider before moving to STOP_COPY whether it can meet the downtime SLA based on the returned data. The patch also includes the implementation for mlx5 and hisi for this new option to make it feature complete for the existing drivers in this area. Signed-off-by: Yishai Hadas Reviewed-by: Jason Gunthorpe Reviewed-by: Longfang Liu Link: https://lore.kernel.org/r/20221106174630.25909-2-yishaih@nvidia.com Signed-off-by: Alex Williamson --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 9 ++++++ drivers/vfio/pci/mlx5/main.c | 18 +++++++++++ drivers/vfio/pci/vfio_pci_core.c | 3 +- drivers/vfio/vfio_main.c | 32 +++++++++++++++++++ include/linux/vfio.h | 5 +++ include/uapi/linux/vfio.h | 13 ++++++++ 6 files changed, 79 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 39eeca18a0f7c..0c0c0c7f05215 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -957,6 +957,14 @@ hisi_acc_vfio_pci_set_device_state(struct vfio_device *vdev, return res; } +static int +hisi_acc_vfio_pci_get_data_size(struct vfio_device *vdev, + unsigned long *stop_copy_length) +{ + *stop_copy_length = sizeof(struct acc_vf_data); + return 0; +} + static int hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev, enum vfio_device_mig_state *curr_state) @@ -1213,6 +1221,7 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev) static const struct vfio_migration_ops hisi_acc_vfio_pci_migrn_state_ops = { .migration_set_state = hisi_acc_vfio_pci_set_device_state, .migration_get_state = hisi_acc_vfio_pci_get_device_state, + .migration_get_data_size = hisi_acc_vfio_pci_get_data_size, }; static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 457138b92f134..6e9cf2aacc527 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -512,6 +512,23 @@ mlx5vf_pci_set_device_state(struct vfio_device *vdev, return res; } +static int mlx5vf_pci_get_data_size(struct vfio_device *vdev, + unsigned long *stop_copy_length) +{ + struct mlx5vf_pci_core_device *mvdev = container_of( + vdev, struct mlx5vf_pci_core_device, core_device.vdev); + size_t state_size; + int ret; + + mutex_lock(&mvdev->state_mutex); + ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, + &state_size); + if (!ret) + *stop_copy_length = state_size; + mlx5vf_state_mutex_unlock(mvdev); + return ret; +} + static int mlx5vf_pci_get_device_state(struct vfio_device *vdev, enum vfio_device_mig_state *curr_state) { @@ -577,6 +594,7 @@ static void mlx5vf_pci_close_device(struct vfio_device *core_vdev) static const struct vfio_migration_ops mlx5vf_pci_mig_ops = { .migration_set_state = mlx5vf_pci_set_device_state, .migration_get_state = mlx5vf_pci_get_device_state, + .migration_get_data_size = mlx5vf_pci_get_data_size, }; static const struct vfio_log_ops mlx5vf_pci_log_ops = { diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 9be2d5be5d959..189d4930c276d 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -2127,7 +2127,8 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) if (vdev->vdev.mig_ops) { if (!(vdev->vdev.mig_ops->migration_get_state && - vdev->vdev.mig_ops->migration_set_state) || + vdev->vdev.mig_ops->migration_set_state && + vdev->vdev.mig_ops->migration_get_data_size) || !(vdev->vdev.migration_flags & VFIO_MIGRATION_STOP_COPY)) return -EINVAL; } diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 9835757e2bee4..662e267a3e13d 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1242,6 +1242,34 @@ out_copy: return 0; } +static int +vfio_ioctl_device_feature_migration_data_size(struct vfio_device *device, + u32 flags, void __user *arg, + size_t argsz) +{ + struct vfio_device_feature_mig_data_size data_size = {}; + unsigned long stop_copy_length; + int ret; + + if (!device->mig_ops) + return -ENOTTY; + + ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET, + sizeof(data_size)); + if (ret != 1) + return ret; + + ret = device->mig_ops->migration_get_data_size(device, &stop_copy_length); + if (ret) + return ret; + + data_size.stop_copy_length = stop_copy_length; + if (copy_to_user(arg, &data_size, sizeof(data_size))) + return -EFAULT; + + return 0; +} + static int vfio_ioctl_device_feature_migration(struct vfio_device *device, u32 flags, void __user *arg, size_t argsz) @@ -1469,6 +1497,10 @@ static int vfio_ioctl_device_feature(struct vfio_device *device, return vfio_ioctl_device_feature_logging_report( device, feature.flags, arg->data, feature.argsz - minsz); + case VFIO_DEVICE_FEATURE_MIG_DATA_SIZE: + return vfio_ioctl_device_feature_migration_data_size( + device, feature.flags, arg->data, + feature.argsz - minsz); default: if (unlikely(!device->ops->device_feature)) return -EINVAL; diff --git a/include/linux/vfio.h b/include/linux/vfio.h index e7480154825ec..43b67e46a2cb5 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -107,6 +107,9 @@ struct vfio_device_ops { * @migration_get_state: Optional callback to get the migration state for * devices that support migration. It's mandatory for * VFIO_DEVICE_FEATURE_MIGRATION migration support. + * @migration_get_data_size: Optional callback to get the estimated data + * length that will be required to complete stop copy. It's mandatory for + * VFIO_DEVICE_FEATURE_MIGRATION migration support. */ struct vfio_migration_ops { struct file *(*migration_set_state)( @@ -114,6 +117,8 @@ struct vfio_migration_ops { enum vfio_device_mig_state new_state); int (*migration_get_state)(struct vfio_device *device, enum vfio_device_mig_state *curr_state); + int (*migration_get_data_size)(struct vfio_device *device, + unsigned long *stop_copy_length); }; /** diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index d7d8e0922376c..3e45dbaf190ef 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -1128,6 +1128,19 @@ struct vfio_device_feature_dma_logging_report { #define VFIO_DEVICE_FEATURE_DMA_LOGGING_REPORT 8 +/* + * Upon VFIO_DEVICE_FEATURE_GET read back the estimated data length that will + * be required to complete stop copy. + * + * Note: Can be called on each device state. + */ + +struct vfio_device_feature_mig_data_size { + __aligned_u64 stop_copy_length; +}; + +#define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9 + /* -------- API for Type1 VFIO IOMMU -------- */ /** -- GitLab From 2f5d8cef45c30edcf3972d345f606df563d3a48e Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Sun, 6 Nov 2022 19:46:19 +0200 Subject: [PATCH 0526/1480] vfio/mlx5: Fix a typo in mlx5vf_cmd_load_vhca_state() Fix a typo in mlx5vf_cmd_load_vhca_state() to use the 'load' memory layout. As in/out sizes are equal for save and load commands there wasn't any functional issue. Fixes: f1d98f346ee3 ("vfio/mlx5: Expose migration commands over mlx5 device") Signed-off-by: Yishai Hadas Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/20221106174630.25909-3-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index c604b70437a5d..0848bc905d3ea 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -378,8 +378,8 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf) { struct mlx5_core_dev *mdev; - u32 out[MLX5_ST_SZ_DW(save_vhca_state_out)] = {}; - u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {}; + u32 out[MLX5_ST_SZ_DW(load_vhca_state_out)] = {}; + u32 in[MLX5_ST_SZ_DW(load_vhca_state_in)] = {}; u32 pdn, mkey; int err; -- GitLab From a80e0e156ca6d7c339e314d15db2f038755da6c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 11 Nov 2022 19:22:43 -0800 Subject: [PATCH 0527/1480] perf stat: Fix summary output in CSV with --metric-only It should not print "summary" for each event when --metric-only is set. Before: $ sudo perf stat -a --per-socket --summary -x, --metric-only true time,socket,cpusGhz,insn per cycle,branch-misses of all branches, 0.000709079,S0,8,0.893,2.40,0.45, S0,8, summary, summary, summary, summary, summary,0.893, summary,2.40, summary, summary,0.45, After: $ sudo perf stat -a --per-socket --summary -x, --metric-only true time,socket,cpusGHz,insn per cycle,branch-misses of all branches, 0.000882297,S0,8,0.598,1.64,0.64, summary,S0,8,0.598,1.64,0.64, Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221112032244.1077370-11-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index cc206781c57cc..6ea7314032706 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -549,7 +549,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int } if (!config->no_csv_summary && config->csv_output && - config->summary && !config->interval) { + config->summary && !config->interval && !config->metric_only) { fprintf(config->output, "%16s%s", "summary", config->csv_sep); } @@ -732,8 +732,13 @@ static void print_aggr(struct perf_stat_config *config, * Without each counter has its own line. */ for (s = 0; s < config->aggr_map->nr; s++) { - if (prefix && metric_only) - fprintf(output, "%s", prefix); + if (metric_only) { + if (prefix) + fprintf(output, "%s", prefix); + else if (config->summary && !config->no_csv_summary && + config->csv_output && !config->interval) + fprintf(output, "%16s%s", "summary", config->csv_sep); + } first = true; evlist__for_each_entry(evlist, counter) { -- GitLab From 7565f9617efac0c0c8e2dbd08dbe0695d56684f5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 11 Nov 2022 19:22:44 -0800 Subject: [PATCH 0528/1480] perf stat: Add missing separator in the CSV header It should have a comma after 'cpus' for socket and die aggregation mode. The output of the following command shows the issue. $ sudo perf stat -a --per-socket -x, --metric-only -I1 true Before: +--- here V time,socket,cpusGhz,insn per cycle,branch-misses of all branches, 0.000908461,S0,8,0.950,1.65,1.21, After: time,socket,cpus,GHz,insn per cycle,branch-misses of all branches, 0.000683094,S0,8,0.593,2.00,0.60, Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221112032244.1077370-12-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 6ea7314032706..2a3c1e0098b9a 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -828,8 +828,8 @@ static int aggr_header_lens[] = { static const char *aggr_header_csv[] = { [AGGR_CORE] = "core,cpus,", - [AGGR_DIE] = "die,cpus", - [AGGR_SOCKET] = "socket,cpus", + [AGGR_DIE] = "die,cpus,", + [AGGR_SOCKET] = "socket,cpus,", [AGGR_NONE] = "cpu,", [AGGR_THREAD] = "comm-pid,", [AGGR_NODE] = "node,", -- GitLab From e5f4afbe395f1248e7501d470118a2a947fe87e6 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:14 -0800 Subject: [PATCH 0529/1480] perf pmu: Remove mostly unused 'struct perf_pmu' 'is_hybrid' member Replace usage with perf_pmu__is_hybrid(). Suggested-by: Kan Liang Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 5 +---- tools/perf/util/evsel.h | 2 +- tools/perf/util/pmu.c | 3 +-- tools/perf/util/pmu.h | 1 - tools/perf/util/stat.c | 11 +++-------- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index cdde5b5f8ad2b..ca6abb64c91d2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3124,11 +3124,8 @@ void evsel__zero_per_pkg(struct evsel *evsel) } } -bool evsel__is_hybrid(struct evsel *evsel) +bool evsel__is_hybrid(const struct evsel *evsel) { - if (evsel->pmu) - return evsel->pmu->is_hybrid; - return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name); } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 989865e16aadd..467bb0b32fef8 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -498,7 +498,7 @@ struct perf_env *evsel__env(struct evsel *evsel); int evsel__store_ids(struct evsel *evsel, struct evlist *evlist); void evsel__zero_per_pkg(struct evsel *evsel); -bool evsel__is_hybrid(struct evsel *evsel); +bool evsel__is_hybrid(const struct evsel *evsel); struct evsel *evsel__leader(struct evsel *evsel); bool evsel__has_leader(struct evsel *evsel, struct evsel *leader); bool evsel__is_leader(struct evsel *evsel); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 6a86e6af0903c..48e7be6f3baa1 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -980,7 +980,6 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name) pmu->is_uncore = pmu_is_uncore(name); if (pmu->is_uncore) pmu->id = pmu_id(name); - pmu->is_hybrid = is_hybrid; pmu->max_precise = pmu_max_precise(name); pmu_add_cpu_aliases(&aliases, pmu); pmu_add_sys_aliases(&aliases, pmu); @@ -992,7 +991,7 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name) list_splice(&aliases, &pmu->aliases); list_add_tail(&pmu->list, &pmus); - if (pmu->is_hybrid) + if (is_hybrid) list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus); pmu->default_config = perf_pmu__get_default_config(pmu); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 68e15c38ae710..0d556d02ce525 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -40,7 +40,6 @@ struct perf_pmu { __u32 type; bool selectable; bool is_uncore; - bool is_hybrid; bool auxtrace; int max_precise; struct perf_event_attr *default_config; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 3a432a949d469..acf0edf5fdd1a 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -604,15 +604,10 @@ static void evsel__merge_aliases(struct evsel *evsel) } } -static bool evsel__should_merge_hybrid(struct evsel *evsel, struct perf_stat_config *config) +static bool evsel__should_merge_hybrid(const struct evsel *evsel, + const struct perf_stat_config *config) { - struct perf_pmu *pmu; - - if (!config->hybrid_merge) - return false; - - pmu = evsel__find_pmu(evsel); - return pmu && pmu->is_hybrid; + return config->hybrid_merge && evsel__is_hybrid(evsel); } static void evsel__merge_stats(struct evsel *evsel, struct perf_stat_config *config) -- GitLab From fe13d43d07393f46957c2fc09f09f097f7969a5d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:15 -0800 Subject: [PATCH 0530/1480] perf pmu: Add data structure documentation Add documentation to 'struct perf_pmu' and the associated structs of 'perf_pmu_alias' and 'perf_pmu_format'. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 16 ++++++ tools/perf/util/pmu.h | 122 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 132 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 48e7be6f3baa1..057e1528c32fe 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -31,10 +31,26 @@ struct perf_pmu perf_pmu__fake; +/** + * struct perf_pmu_format - Values from a format file read from + * /devices/cpu/format/ held in struct perf_pmu. + * + * For example, the contents of /devices/cpu/format/event may be + * "config:0-7" and will be represented here as name="event", + * value=PERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set. + */ struct perf_pmu_format { + /** @name: The modifier/file name. */ char *name; + /** + * @value : Which config value the format relates to. Supported values + * are from PERF_PMU_FORMAT_VALUE_CONFIG to + * PERF_PMU_FORMAT_VALUE_CONFIG_END. + */ int value; + /** @bits: Which config bits are set by this format value. */ DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); + /** @list: Element on list within struct perf_pmu. */ struct list_head list; }; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 0d556d02ce525..ee02e1ef91878 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -33,30 +33,101 @@ struct perf_pmu_caps { struct list_head list; }; +/** + * struct perf_pmu - hi + */ struct perf_pmu { + /** @name: The name of the PMU such as "cpu". */ char *name; + /** + * @alias_name: Optional alternate name for the PMU determined in + * architecture specific code. + */ char *alias_name; + /** + * @id: Optional PMU identifier read from + * /bus/event_source/devices//identifier. + */ char *id; + /** + * @type: Perf event attributed type value, read from + * /bus/event_source/devices//type. + */ __u32 type; + /** + * @selectable: Can the PMU name be selected as if it were an event? + */ bool selectable; + /** + * @is_uncore: Is the PMU not within the CPU core? Determined by the + * presence of /bus/event_source/devices//cpumask. + */ bool is_uncore; + /** + * @auxtrace: Are events auxiliary events? Determined in architecture + * specific code. + */ bool auxtrace; + /** + * @max_precise: Number of levels of :ppp precision supported by the + * PMU, read from + * /bus/event_source/devices//caps/max_precise. + */ int max_precise; + /** + * @default_config: Optional default perf_event_attr determined in + * architecture specific code. + */ struct perf_event_attr *default_config; + /** + * @cpus: Empty or the contents of either of: + * /bus/event_source/devices//cpumask. + * /bus/event_source/devices//cpus. + */ struct perf_cpu_map *cpus; - struct list_head format; /* HEAD struct perf_pmu_format -> list */ - struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ + /** + * @format: Holds the contents of files read from + * /bus/event_source/devices//format/. The contents specify + * which event parameter changes what config, config1 or config2 bits. + */ + struct list_head format; + /** + * @aliases: List of struct perf_pmu_alias. Each alias corresponds to an + * event read from /bus/event_source/devices//events/ or + * from json events in pmu-events.c. + */ + struct list_head aliases; + /** @caps_initialized: Has the list caps been initialized? */ bool caps_initialized; + /** @nr_caps: The length of the list caps. */ u32 nr_caps; - struct list_head caps; /* HEAD struct perf_pmu_caps -> list */ - struct list_head list; /* ELEM */ + /** + * @caps: Holds the contents of files read from + * /bus/event_source/devices//caps/. + * + * The contents are pairs of the filename with the value of its + * contents, for example, max_precise (see above) may have a value of 3. + */ + struct list_head caps; + /** @list: Element on pmus list in pmu.c. */ + struct list_head list; + /** @hybrid_list: Element on perf_pmu__hybrid_pmus. */ struct list_head hybrid_list; + /** + * @missing_features: Features to inhibit when events on this PMU are + * opened. + */ struct { + /** + * @exclude_guest: Disables perf_event_attr exclude_guest and + * exclude_host. + */ bool exclude_guest; } missing_features; }; +/** @perf_pmu__fake: A special global PMU used for testing. */ extern struct perf_pmu perf_pmu__fake; struct perf_pmu_info { @@ -70,21 +141,60 @@ struct perf_pmu_info { #define UNIT_MAX_LEN 31 /* max length for event unit name */ +/** + * struct perf_pmu_alias - An event either read from sysfs or builtin in + * pmu-events.c, created by parsing the pmu-events json files. + */ struct perf_pmu_alias { + /** @name: Name of the event like "mem-loads". */ char *name; + /** @desc: Optional short description of the event. */ char *desc; + /** @long_desc: Optional long description. */ char *long_desc; + /** + * @topic: Optional topic such as cache or pipeline, particularly for + * json events. + */ char *topic; + /** + * @str: Comma separated parameter list like + * "event=0xcd,umask=0x1,ldlat=0x3". + */ char *str; - struct list_head terms; /* HEAD struct parse_events_term -> list */ - struct list_head list; /* ELEM */ + /** @terms: Owned list of the original parsed parameters. */ + struct list_head terms; + /** @list: List element of struct perf_pmu aliases. */ + struct list_head list; + /** @unit: Units for the event, such as bytes or cache lines. */ char unit[UNIT_MAX_LEN+1]; + /** @scale: Value to scale read counter values by. */ double scale; + /** + * @per_pkg: Does the file + * /bus/event_source/devices//events/.per-pkg or + * equivalent json value exist and have the value 1. + */ bool per_pkg; + /** + * @snapshot: Does the file + * /bus/event_source/devices//events/.snapshot + * exist and have the value 1. + */ bool snapshot; + /** + * @deprecated: Is the event hidden and so not shown in perf list by + * default. + */ bool deprecated; + /** + * @metric_expr: A metric expression associated with an event. Doing + * this makes little sense due to scale and unit applying to both. + */ char *metric_expr; + /** @metric_name: A name for the metric. unit applying to both. */ char *metric_name; + /** @pmu_name: The name copied from struct perf_pmu. */ char *pmu_name; }; -- GitLab From 1504b6f97bad166b484d6f27dc99746fdca5f467 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:16 -0800 Subject: [PATCH 0531/1480] tools lib api fs tracing_path: Add scandir alphasort tracing_events__opendir() allows iteration over files in /tracing/events but with an arbitrary sort order. Add a scandir alternative where the results are alphabetically sorted. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/fs/tracing_path.c | 16 ++++++++++++++++ tools/lib/api/fs/tracing_path.h | 1 + 2 files changed, 17 insertions(+) diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 5afb11b30fca4..b8e457c841aba 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -113,6 +113,22 @@ DIR *tracing_events__opendir(void) return dir; } +int tracing_events__scandir_alphasort(struct dirent ***namelist) +{ + char *path = get_tracing_file("events"); + int ret; + + if (!path) { + *namelist = NULL; + return 0; + } + + ret = scandir(path, namelist, NULL, alphasort); + put_events_file(path); + + return ret; +} + int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) { diff --git a/tools/lib/api/fs/tracing_path.h b/tools/lib/api/fs/tracing_path.h index a19136b086dce..fc6347c11deb3 100644 --- a/tools/lib/api/fs/tracing_path.h +++ b/tools/lib/api/fs/tracing_path.h @@ -6,6 +6,7 @@ #include DIR *tracing_events__opendir(void); +int tracing_events__scandir_alphasort(struct dirent ***namelist); void tracing_path_set(const char *mountpoint); const char *tracing_path_mount(void); -- GitLab From d74060c03368063c64e63004319e2a39930c4297 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:17 -0800 Subject: [PATCH 0532/1480] perf tracepoint: Sort events in iterator In print_tracepoint_events() use tracing_events__scandir_alphasort() and scandir alphasort so that the subsystem and events are sorted and don't need a secondary qsort. Locally this results in the following change: ... ext4:ext4_zero_range [Tracepoint event] - fib6:fib6_table_lookup [Tracepoint event] fib:fib_table_lookup [Tracepoint event] + fib6:fib6_table_lookup [Tracepoint event] filelock:break_lease_block [Tracepoint event] ... ie fib6 now is after fib and not before it. This is more consistent with how numbers are more generally sorted, such as: ... syscalls:sys_enter_renameat [Tracepoint event] syscalls:sys_enter_renameat2 [Tracepoint event] ... and so an improvement over the qsort approach. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/print-events.c | 108 +++++++++++---------------------- 1 file changed, 37 insertions(+), 71 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 6df947df1c0fc..dae927250826a 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -66,26 +66,21 @@ static int cmp_string(const void *a, const void *b) void print_tracepoint_events(const char *subsys_glob, const char *event_glob, bool name_only) { - DIR *sys_dir, *evt_dir; - struct dirent *sys_dirent, *evt_dirent; - char evt_path[MAXPATHLEN]; - char *dir_path; - char **evt_list = NULL; - unsigned int evt_i = 0, evt_num = 0; - bool evt_num_known = false; - -restart: - sys_dir = tracing_events__opendir(); - if (!sys_dir) - return; - - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_close_sys_dir; - } + struct dirent **sys_namelist = NULL; + bool printed = false; + int sys_items = tracing_events__scandir_alphasort(&sys_namelist); + + for (int i = 0; i < sys_items; i++) { + struct dirent *sys_dirent = sys_namelist[i]; + struct dirent **evt_namelist = NULL; + char *dir_path; + int evt_items; + + if (sys_dirent->d_type != DT_DIR || + !strcmp(sys_dirent->d_name, ".") || + !strcmp(sys_dirent->d_name, "..")) + continue; - for_each_subsystem(sys_dir, sys_dirent) { if (subsys_glob != NULL && !strglobmatch(sys_dirent->d_name, subsys_glob)) continue; @@ -93,69 +88,40 @@ restart: dir_path = get_events_file(sys_dirent->d_name); if (!dir_path) continue; - evt_dir = opendir(dir_path); - if (!evt_dir) - goto next; - for_each_event(dir_path, evt_dir, evt_dirent) { - if (event_glob != NULL && - !strglobmatch(evt_dirent->d_name, event_glob)) + evt_items = scandir(dir_path, &evt_namelist, NULL, alphasort); + for (int j = 0; j < evt_items; j++) { + struct dirent *evt_dirent = evt_namelist[j]; + char evt_path[MAXPATHLEN]; + + if (evt_dirent->d_type != DT_DIR || + !strcmp(evt_dirent->d_name, ".") || + !strcmp(evt_dirent->d_name, "..")) continue; - if (!evt_num_known) { - evt_num++; + if (tp_event_has_id(dir_path, evt_dirent) != 0) + continue; + + if (event_glob != NULL && + !strglobmatch(evt_dirent->d_name, event_glob)) continue; - } snprintf(evt_path, MAXPATHLEN, "%s:%s", sys_dirent->d_name, evt_dirent->d_name); - - evt_list[evt_i] = strdup(evt_path); - if (evt_list[evt_i] == NULL) { - put_events_file(dir_path); - goto out_close_evt_dir; + if (name_only) + printf("%s ", evt_path); + else { + printf(" %-50s [%s]\n", evt_path, + event_type_descriptors[PERF_TYPE_TRACEPOINT]); } - evt_i++; + printed = true; } - closedir(evt_dir); -next: - put_events_file(dir_path); + free(dir_path); + free(evt_namelist); } - closedir(sys_dir); - - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { - if (name_only) { - printf("%s ", evt_list[evt_i++]); - continue; - } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - } - if (evt_num && pager_in_use()) + free(sys_namelist); + if (printed && pager_in_use()) printf("\n"); - -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_close_evt_dir: - closedir(evt_dir); -out_close_sys_dir: - closedir(sys_dir); - - printf("FATAL: not enough memory to print %s\n", - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - if (evt_list) - goto out_free; } void print_sdt_events(const char *subsys_glob, const char *event_glob, -- GitLab From ca0fe62413f3f536201d788672cd6cf7c4ed52dd Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:18 -0800 Subject: [PATCH 0533/1480] perf list: Generalize limiting to a PMU name Deprecate the --cputype option and add a --unit option where '--unit cpu_atom' behaves like '--cputype atom'. The --unit option can be used with arbitrary PMUs, for example: ``` $ perf list --unit msr pmu List of pre-defined events (to be used in -e or -M): msr/aperf/ [Kernel PMU event] msr/cpu_thermal_margin/ [Kernel PMU event] msr/mperf/ [Kernel PMU event] msr/pperf/ [Kernel PMU event] msr/smi/ [Kernel PMU event] msr/tsc/ [Kernel PMU event] ``` Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-list.txt | 6 +++--- tools/perf/builtin-list.c | 18 ++++++++++++------ tools/perf/util/metricgroup.c | 3 ++- tools/perf/util/pmu.c | 4 +--- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 57384a97c04f4..44a819af573de 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt @@ -39,9 +39,9 @@ any extra expressions computed by perf stat. --deprecated:: Print deprecated events. By default the deprecated events are hidden. ---cputype:: -Print events applying cpu with this type for hybrid platform -(e.g. --cputype core or --cputype atom) +--unit:: +Print PMU events and metrics limited to the specific PMU name. +(e.g. --unit cpu, --unit msr, --unit cpu_core, --unit cpu_atom) [[EVENT_MODIFIERS]] EVENT MODIFIERS diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 58e1ec1654ef4..cc84ced6da266 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -21,7 +21,6 @@ static bool desc_flag = true; static bool details_flag; -static const char *hybrid_type; int cmd_list(int argc, const char **argv) { @@ -30,6 +29,8 @@ int cmd_list(int argc, const char **argv) bool long_desc_flag = false; bool deprecated = false; char *pmu_name = NULL; + const char *hybrid_name = NULL; + const char *unit_name = NULL; struct option list_options[] = { OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), OPT_BOOLEAN('d', "desc", &desc_flag, @@ -40,9 +41,10 @@ int cmd_list(int argc, const char **argv) "Print information on the perf event names and expressions used internally by events."), OPT_BOOLEAN(0, "deprecated", &deprecated, "Print deprecated events."), - OPT_STRING(0, "cputype", &hybrid_type, "hybrid cpu type", - "Print events applying cpu with this type for hybrid platform " - "(e.g. core or atom)"), + OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", + "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), + OPT_STRING(0, "unit", &unit_name, "PMU name", + "Limit PMU or metric printing to the specified PMU."), OPT_INCR(0, "debug", &verbose, "Enable debugging output"), OPT_END() @@ -53,6 +55,8 @@ int cmd_list(int argc, const char **argv) }; set_option_flag(list_options, 0, "raw-dump", PARSE_OPT_HIDDEN); + /* Hide hybrid flag for the more generic 'unit' flag. */ + set_option_flag(list_options, 0, "cputype", PARSE_OPT_HIDDEN); argc = parse_options(argc, argv, list_options, list_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -62,8 +66,10 @@ int cmd_list(int argc, const char **argv) if (!raw_dump && pager_in_use()) printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); - if (hybrid_type) { - pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_type); + if (unit_name) + pmu_name = strdup(unit_name); + else if (hybrid_name) { + pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_name); if (!pmu_name) pr_warning("WARNING: hybrid cputype is not supported!\n"); } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 4c98ac29ee13f..1943fed9b6d92 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -556,11 +556,12 @@ static int metricgroup__print_callback(const struct pmu_event *pe, void *vdata) { struct metricgroup_print_data *data = vdata; + const char *pmu = pe->pmu ?: "cpu"; if (!pe->metric_expr) return 0; - if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_name, pe->pmu)) + if (data->pmu_name && strcmp(data->pmu_name, pmu)) return 0; return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 057e1528c32fe..e6790175307b4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1695,10 +1695,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - if (pmu_name && perf_pmu__is_hybrid(pmu->name) && - strcmp(pmu_name, pmu->name)) { + if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) continue; - } list_for_each_entry(alias, &pmu->aliases, list) { char *name = alias->desc ? alias->name : -- GitLab From 3301b3fe9bdcfcb109e44e31160e830fe558faec Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:19 -0800 Subject: [PATCH 0534/1480] perf list: Simplify cache event printing The current code computes an array of cache names then sorts and prints them. Use a strlist to create a list of names that is sorted. Keep the hybrid names, it is unclear how to generalize it, but drop the computation of evt_pmus that is never used. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Kang Minchul Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-7-irogers@google.com [ Fixed up clash with cf9f67b36303de65 ("perf print-events: Remove redundant comparison with zero")] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/print-events.c | 130 +++++++-------------------------- 1 file changed, 27 insertions(+), 103 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index dae927250826a..ff7793944246e 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -206,135 +206,59 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, int print_hwcache_events(const char *event_glob, bool name_only) { - unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; - char name[64], new_name[128]; - char **evt_list = NULL, **evt_pmus = NULL; - bool evt_num_known = false; - struct perf_pmu *pmu = NULL; - - if (perf_pmu__has_hybrid()) { - npmus = perf_pmu__hybrid_pmu_num(); - evt_pmus = zalloc(sizeof(char *) * npmus); - if (!evt_pmus) - goto out_enomem; - } + struct strlist *evt_name_list = strlist__new(NULL, NULL); + struct str_node *nd; -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; + if (!evt_name_list) { + pr_debug("Failed to allocate new strlist for hwcache events\n"); + return -ENOMEM; } - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + for (int type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (int op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { /* skip invalid cache type */ if (!evsel__is_cache_op_valid(type, op)) continue; - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - unsigned int hybrid_supported = 0, j; - bool supported; + for (int i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + struct perf_pmu *pmu = NULL; + char name[64]; __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); if (event_glob != NULL && !strglobmatch(name, event_glob)) continue; if (!perf_pmu__has_hybrid()) { - if (!is_event_supported(PERF_TYPE_HW_CACHE, - type | (op << 8) | (i << 16))) { - continue; - } - } else { - perf_pmu__for_each_hybrid_pmu(pmu) { - if (!evt_num_known) { - evt_num++; - continue; - } - - supported = is_event_supported( - PERF_TYPE_HW_CACHE, - type | (op << 8) | (i << 16) | - ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)); - if (supported) { - snprintf(new_name, sizeof(new_name), - "%s/%s/", pmu->name, name); - evt_pmus[hybrid_supported] = - strdup(new_name); - hybrid_supported++; - } - } - - if (hybrid_supported == 0) - continue; - } - - if (!evt_num_known) { - evt_num++; + if (is_event_supported(PERF_TYPE_HW_CACHE, + type | (op << 8) | (i << 16))) + strlist__add(evt_name_list, name); continue; } - - if ((hybrid_supported == 0) || - (hybrid_supported == npmus)) { - evt_list[evt_i] = strdup(name); - for (j = 0; j < npmus; j++) - zfree(&evt_pmus[j]); - } else { - for (j = 0; j < hybrid_supported; j++) { - evt_list[evt_i++] = evt_pmus[j]; - evt_pmus[j] = NULL; + perf_pmu__for_each_hybrid_pmu(pmu) { + if (is_event_supported(PERF_TYPE_HW_CACHE, + type | (op << 8) | (i << 16) | + ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT))) { + char new_name[128]; + snprintf(new_name, sizeof(new_name), + "%s/%s/", pmu->name, name); + strlist__add(evt_name_list, new_name); } - continue; } - - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; } } } - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - - for (evt_i = 0; evt_i < evt_num; evt_i++) { - if (!evt_list[evt_i]) - break; - } - - evt_num = evt_i; - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { + strlist__for_each_entry(nd, evt_name_list) { if (name_only) { - printf("%s ", evt_list[evt_i++]); + printf("%s ", nd->s); continue; } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_HW_CACHE]); + printf(" %-50s [%s]\n", nd->s, event_type_descriptors[PERF_TYPE_HW_CACHE]); } - if (evt_num && pager_in_use()) + if (!strlist__empty(evt_name_list) && pager_in_use()) printf("\n"); -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - - for (evt_i = 0; evt_i < npmus; evt_i++) - zfree(&evt_pmus[evt_i]); - zfree(&evt_pmus); - return evt_num; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", - event_type_descriptors[PERF_TYPE_HW_CACHE]); - if (evt_list) - goto out_free; - return evt_num; + strlist__delete(evt_name_list); + return 0; } static void print_tool_event(const struct event_symbol *syms, const char *event_glob, -- GitLab From de3752a7d6c4435087ce7cb8537bfa987b93ec8b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:20 -0800 Subject: [PATCH 0535/1480] perf list: Simplify symbol event printing The current code computes an array of symbol names then sorts and prints them. Use a strlist to create a list of names that is sorted and then print it. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/print-events.c | 79 +++++++++------------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index ff7793944246e..d53dba033597b 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -52,14 +52,6 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { }, }; -static int cmp_string(const void *a, const void *b) -{ - const char * const *as = a; - const char * const *bs = b; - - return strcmp(*as, *bs); -} - /* * Print the events from /tracing/events */ @@ -298,77 +290,48 @@ void print_symbol_events(const char *event_glob, unsigned int type, struct event_symbol *syms, unsigned int max, bool name_only) { - unsigned int i, evt_i = 0, evt_num = 0; - char name[MAX_NAME_LEN]; - char **evt_list = NULL; - bool evt_num_known = false; - -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; - syms -= max; - } + struct strlist *evt_name_list = strlist__new(NULL, NULL); + struct str_node *nd; - for (i = 0; i < max; i++, syms++) { + if (!evt_name_list) { + pr_debug("Failed to allocate new strlist for symbol events\n"); + return; + } + for (unsigned int i = 0; i < max; i++) { /* * New attr.config still not supported here, the latest * example was PERF_COUNT_SW_CGROUP_SWITCHES */ - if (syms->symbol == NULL) + if (syms[i].symbol == NULL) continue; - if (event_glob != NULL && !(strglobmatch(syms->symbol, event_glob) || - (syms->alias && strglobmatch(syms->alias, event_glob)))) + if (event_glob != NULL && !(strglobmatch(syms[i].symbol, event_glob) || + (syms[i].alias && strglobmatch(syms[i].alias, event_glob)))) continue; if (!is_event_supported(type, i)) continue; - if (!evt_num_known) { - evt_num++; - continue; - } - - if (!name_only && strlen(syms->alias)) - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); - else - strlcpy(name, syms->symbol, MAX_NAME_LEN); + if (strlen(syms[i].alias)) { + char name[MAX_NAME_LEN]; - evt_list[evt_i] = strdup(name); - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; + snprintf(name, MAX_NAME_LEN, "%s OR %s", syms[i].symbol, syms[i].alias); + strlist__add(evt_name_list, name); + } else + strlist__add(evt_name_list, syms[i].symbol); } - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { + strlist__for_each_entry(nd, evt_name_list) { if (name_only) { - printf("%s ", evt_list[evt_i++]); + printf("%s ", nd->s); continue; } - printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); + printf(" %-50s [%s]\n", nd->s, event_type_descriptors[type]); } - if (evt_num && pager_in_use()) + if (!strlist__empty(evt_name_list) && pager_in_use()) printf("\n"); -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); - if (evt_list) - goto out_free; + strlist__delete(evt_name_list); } /* -- GitLab From eb2d4514a5971444f67ac8b95bcd63e7702fa6bf Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:21 -0800 Subject: [PATCH 0536/1480] perf pmu: Restructure print_pmu_events() to avoid memory allocations Previously print_pmu_events() would compute the values to be printed, place them in struct sevent, sort them and then print them. Modify the code so that struct sevent holds just the PMU and event, sort these and then in the main print loop calculate aliases for names, etc. This avoids memory allocations for copied values as they are computed then printed. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 208 ++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 98 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index e6790175307b4..075c82dd1347f 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1553,8 +1553,8 @@ static int sub_non_neg(int a, int b) return a - b; } -static char *format_alias(char *buf, int len, struct perf_pmu *pmu, - struct perf_pmu_alias *alias) +static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, + const struct perf_pmu_alias *alias) { struct parse_events_term *term; int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name); @@ -1579,51 +1579,67 @@ static char *format_alias(char *buf, int len, struct perf_pmu *pmu, return buf; } -static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, - struct perf_pmu_alias *alias) +static char *format_alias_or(char *buf, int len, const struct perf_pmu *pmu, + const struct perf_pmu_alias *alias) { snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); return buf; } +/** Struct for ordering events as output in perf list. */ struct sevent { - char *name; - char *desc; - char *topic; - char *str; - char *pmu; - char *metric_expr; - char *metric_name; - int is_cpu; + /** PMU for event. */ + const struct perf_pmu *pmu; + /** + * Optional event for name, desc, etc. If not present then this is a + * selectable PMU and the event name is shown as "//". + */ + const struct perf_pmu_alias *event; + /** Is the PMU for the CPU? */ + bool is_cpu; }; static int cmp_sevent(const void *a, const void *b) { const struct sevent *as = a; const struct sevent *bs = b; + const char *a_pmu_name, *b_pmu_name; + const char *a_name = "//", *a_desc = NULL, *a_topic = ""; + const char *b_name = "//", *b_desc = NULL, *b_topic = ""; int ret; - /* Put extra events last */ - if (!!as->desc != !!bs->desc) - return !!as->desc - !!bs->desc; - if (as->topic && bs->topic) { - int n = strcmp(as->topic, bs->topic); - - if (n) - return n; + if (as->event) { + a_name = as->event->name; + a_desc = as->event->desc; + a_topic = as->event->topic ?: ""; } + if (bs->event) { + b_name = bs->event->name; + b_desc = bs->event->desc; + b_topic = bs->event->topic ?: ""; + } + /* Put extra events last. */ + if (!!a_desc != !!b_desc) + return !!a_desc - !!b_desc; + + /* Order by topics. */ + ret = strcmp(a_topic, b_topic); + if (ret) + return ret; /* Order CPU core events to be first */ if (as->is_cpu != bs->is_cpu) return bs->is_cpu - as->is_cpu; - ret = strcmp(as->name, bs->name); - if (!ret) { - if (as->pmu && bs->pmu) - return strcmp(as->pmu, bs->pmu); - } + /* Order by PMU name. */ + a_pmu_name = as->pmu->name ?: ""; + b_pmu_name = bs->pmu->name ?: ""; + ret = strcmp(a_pmu_name, b_pmu_name); + if (ret) + return ret; - return ret; + /* Order by event name. */ + return strcmp(a_name, b_name); } static void wordwrap(char *s, int start, int max, int corr) @@ -1655,16 +1671,18 @@ bool is_pmu_core(const char *name) static bool pmu_alias_is_duplicate(struct sevent *alias_a, struct sevent *alias_b) { - /* Different names -> never duplicates */ - if (strcmp(alias_a->name, alias_b->name)) - return false; + const char *a_pmu_name, *b_pmu_name; + const char *a_name = alias_a->event ? alias_a->event->name : "//"; + const char *b_name = alias_b->event ? alias_b->event->name : "//"; - /* Don't remove duplicates for hybrid PMUs */ - if (perf_pmu__is_hybrid(alias_a->pmu) && - perf_pmu__is_hybrid(alias_b->pmu)) + /* Different names -> never duplicates */ + if (strcmp(a_name, b_name)) return false; - return true; + /* Don't remove duplicates for different PMUs */ + a_pmu_name = alias_a->pmu->name ?: ""; + b_pmu_name = alias_b->pmu->name ?: ""; + return strcmp(a_pmu_name, b_pmu_name) == 0; } void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, @@ -1690,110 +1708,104 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, len++; } aliases = zalloc(sizeof(struct sevent) * len); - if (!aliases) - goto out_enomem; + if (!aliases) { + pr_err("FATAL: not enough memory to print PMU events\n"); + return; + } pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { + bool is_cpu; + if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) continue; - list_for_each_entry(alias, &pmu->aliases, list) { - char *name = alias->desc ? alias->name : - format_alias(buf, sizeof(buf), pmu, alias); - bool is_cpu = is_pmu_core(pmu->name) || - perf_pmu__is_hybrid(pmu->name); + is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); + list_for_each_entry(alias, &pmu->aliases, list) { if (alias->deprecated && !deprecated) continue; if (event_glob != NULL && - !(strglobmatch_nocase(name, event_glob) || - (!is_cpu && strglobmatch_nocase(alias->name, - event_glob)) || + !(strglobmatch_nocase(alias->name, event_glob) || + (!is_cpu && + strglobmatch_nocase(alias->name, event_glob)) || (alias->topic && strglobmatch_nocase(alias->topic, event_glob)))) continue; - if (is_cpu && !name_only && !alias->desc) - name = format_alias_or(buf, sizeof(buf), pmu, alias); - - aliases[j].name = name; - if (is_cpu && !name_only && !alias->desc) - aliases[j].name = format_alias_or(buf, - sizeof(buf), - pmu, alias); - aliases[j].name = strdup(aliases[j].name); - if (!aliases[j].name) - goto out_enomem; - - aliases[j].desc = long_desc ? alias->long_desc : - alias->desc; - aliases[j].topic = alias->topic; - aliases[j].str = alias->str; - aliases[j].pmu = pmu->name; - aliases[j].metric_expr = alias->metric_expr; - aliases[j].metric_name = alias->metric_name; + aliases[j].event = alias; + aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; j++; } if (pmu->selectable && (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { - char *s; - if (asprintf(&s, "%s//", pmu->name) < 0) - goto out_enomem; - aliases[j].name = s; + aliases[j].event = NULL; + aliases[j].pmu = pmu; + aliases[j].is_cpu = is_cpu; j++; } } len = j; qsort(aliases, len, sizeof(struct sevent), cmp_sevent); for (j = 0; j < len; j++) { + char *name, *desc; + /* Skip duplicates */ if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) continue; + if (!aliases[j].event) { + /* A selectable event. */ + snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name); + name = buf; + } else if (aliases[j].event->desc) { + name = aliases[j].event->name; + } else { + if (!name_only && aliases[j].is_cpu) { + name = format_alias_or(buf, sizeof(buf), aliases[j].pmu, + aliases[j].event); + } else { + name = format_alias(buf, sizeof(buf), aliases[j].pmu, + aliases[j].event); + } + } if (name_only) { - printf("%s ", aliases[j].name); + printf("%s ", name); continue; } - if (aliases[j].desc && !quiet_flag) { - if (numdesc++ == 0) - printf("\n"); - if (aliases[j].topic && (!topic || - strcmp(topic, aliases[j].topic))) { - printf("%s%s:\n", topic ? "\n" : "", - aliases[j].topic); - topic = aliases[j].topic; - } - printf(" %-50s\n", aliases[j].name); - printf("%*s", 8, "["); - wordwrap(aliases[j].desc, 8, columns, 0); - printf("]\n"); - if (details_flag) { - printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str); - if (aliases[j].metric_name) - printf(" MetricName: %s", aliases[j].metric_name); - if (aliases[j].metric_expr) - printf(" MetricExpr: %s", aliases[j].metric_expr); - putchar('\n'); - } - } else - printf(" %-50s [Kernel PMU event]\n", aliases[j].name); printed++; + if (!aliases[j].event || !aliases[j].event->desc || quiet_flag) { + printf(" %-50s [Kernel PMU event]\n", name); + continue; + } + if (numdesc++ == 0) + printf("\n"); + if (aliases[j].event->topic && (!topic || + strcmp(topic, aliases[j].event->topic))) { + printf("%s%s:\n", topic ? "\n" : "", aliases[j].event->topic); + topic = aliases[j].event->topic; + } + printf(" %-50s\n", name); + printf("%*s", 8, "["); + desc = long_desc ? aliases[j].event->long_desc : aliases[j].event->desc; + wordwrap(desc, 8, columns, 0); + printf("]\n"); + if (details_flag) { + printf("%*s%s/%s/ ", 8, "", aliases[j].pmu->name, aliases[j].event->str); + if (aliases[j].event->metric_name) + printf(" MetricName: %s", aliases[j].event->metric_name); + if (aliases[j].event->metric_expr) + printf(" MetricExpr: %s", aliases[j].event->metric_expr); + putchar('\n'); + } } if (printed && pager_in_use()) printf("\n"); -out_free: - for (j = 0; j < len; j++) - zfree(&aliases[j].name); + zfree(&aliases); return; - -out_enomem: - printf("FATAL: not enough memory to print PMU events\n"); - if (aliases) - goto out_free; } bool pmu_have_event(const char *pname, const char *name) -- GitLab From f5bc4428cc6e096170d35fc79a640d90e33dd9c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:09 -0800 Subject: [PATCH 0537/1480] perf stat: Clear screen only if output file is a tty The --interval-clear option makes perf stat to clear the terminal at each interval. But it doesn't need to clear the screen when it saves to a file. Make it fail when it's enabled with the output options. $ perf stat -I 1 --interval-clear -o myfile true --interval-clear does not work with output Usage: perf stat [] [] -o, --output output file name --log-fd log output to fd, instead of stderr --interval-clear clear screen in between new interval Signed-off-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d5e1670bca204..1d79801f4e844 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2403,6 +2403,14 @@ int cmd_stat(int argc, const char **argv) } } + if (stat_config.interval_clear && !isatty(fileno(output))) { + fprintf(stderr, "--interval-clear does not work with output\n"); + parse_options_usage(stat_usage, stat_options, "o", 1); + parse_options_usage(NULL, stat_options, "log-fd", 0); + parse_options_usage(NULL, stat_options, "interval-clear", 0); + return -1; + } + stat_config.output = output; /* -- GitLab From 31bf6aea997674a030be02999560d8e6f7a6b974 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:10 -0800 Subject: [PATCH 0538/1480] perf stat: Split print_running() function To make the code more obvious and hopefully simpler, factor out the code for each output mode - stdio, CSV, JSON. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 37 +++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 2a3c1e0098b9a..281b811f8574d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -25,24 +25,41 @@ #define CNTR_NOT_SUPPORTED "" #define CNTR_NOT_COUNTED "" -static void print_running(struct perf_stat_config *config, - u64 run, u64 ena) +static void print_running_std(struct perf_stat_config *config, u64 run, u64 ena) +{ + if (run != ena) + fprintf(config->output, " (%.2f%%)", 100.0 * run / ena); +} + +static void print_running_csv(struct perf_stat_config *config, u64 run, u64 ena) { + double enabled_percent = 100; + + if (run != ena) + enabled_percent = 100 * run / ena; + fprintf(config->output, "%s%" PRIu64 "%s%.2f", + config->csv_sep, run, config->csv_sep, enabled_percent); +} +static void print_running_json(struct perf_stat_config *config, u64 run, u64 ena) +{ double enabled_percent = 100; if (run != ena) enabled_percent = 100 * run / ena; + fprintf(config->output, "\"event-runtime\" : %" PRIu64 ", \"pcnt-running\" : %.2f, ", + run, enabled_percent); +} + +static void print_running(struct perf_stat_config *config, + u64 run, u64 ena) +{ if (config->json_output) - fprintf(config->output, - "\"event-runtime\" : %" PRIu64 ", \"pcnt-running\" : %.2f, ", - run, enabled_percent); + print_running_json(config, run, ena); else if (config->csv_output) - fprintf(config->output, - "%s%" PRIu64 "%s%.2f", config->csv_sep, - run, config->csv_sep, enabled_percent); - else if (run != ena) - fprintf(config->output, " (%.2f%%)", 100.0 * run / ena); + print_running_csv(config, run, ena); + else + print_running_std(config, run, ena); } static void print_noise_pct(struct perf_stat_config *config, -- GitLab From def99d60df6f21b4c36d23f0071ec8a73f39f28b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:11 -0800 Subject: [PATCH 0539/1480] perf stat: Split print_noise_pct() function Likewise, split print_noise_pct() for each output mode. Although it's a tiny function, more logic will be added soon so it'd be better split it and treat it in the same way. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 281b811f8574d..a230f65efa624 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -62,17 +62,36 @@ static void print_running(struct perf_stat_config *config, print_running_std(config, run, ena); } +static void print_noise_pct_std(struct perf_stat_config *config, + double pct) +{ + if (pct) + fprintf(config->output, " ( +-%6.2f%% )", pct); +} + +static void print_noise_pct_csv(struct perf_stat_config *config, + double pct) +{ + fprintf(config->output, "%s%.2f%%", config->csv_sep, pct); +} + +static void print_noise_pct_json(struct perf_stat_config *config, + double pct) +{ + fprintf(config->output, "\"variance\" : %.2f, ", pct); +} + static void print_noise_pct(struct perf_stat_config *config, double total, double avg) { double pct = rel_stddev_stats(total, avg); if (config->json_output) - fprintf(config->output, "\"variance\" : %.2f, ", pct); + print_noise_pct_json(config, pct); else if (config->csv_output) - fprintf(config->output, "%s%.2f%%", config->csv_sep, pct); - else if (pct) - fprintf(config->output, " ( +-%6.2f%% )", pct); + print_noise_pct_csv(config, pct); + else + print_noise_pct_std(config, pct); } static void print_noise(struct perf_stat_config *config, -- GitLab From 41cb875242e71bf1bf5539a724bc65a0b470bb12 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:12 -0800 Subject: [PATCH 0540/1480] perf stat: Split print_cgroup() function Likewise, split print_cgroup() for each output mode. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index a230f65efa624..af2a561eb20c2 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -106,15 +106,32 @@ static void print_noise(struct perf_stat_config *config, print_noise_pct(config, stddev_stats(&ps->res_stats), avg); } +static void print_cgroup_std(struct perf_stat_config *config, const char *cgrp_name) +{ + fprintf(config->output, " %s", cgrp_name); +} + +static void print_cgroup_csv(struct perf_stat_config *config, const char *cgrp_name) +{ + fprintf(config->output, "%s%s", config->csv_sep, cgrp_name); +} + +static void print_cgroup_json(struct perf_stat_config *config, const char *cgrp_name) +{ + fprintf(config->output, "\"cgroup\" : \"%s\", ", cgrp_name); +} + static void print_cgroup(struct perf_stat_config *config, struct evsel *evsel) { if (nr_cgroups) { const char *cgrp_name = evsel->cgrp ? evsel->cgrp->name : ""; if (config->json_output) - fprintf(config->output, "\"cgroup\" : \"%s\", ", cgrp_name); + print_cgroup_json(config, cgrp_name); + if (config->csv_output) + print_cgroup_csv(config, cgrp_name); else - fprintf(config->output, "%s%s", config->csv_sep, cgrp_name); + print_cgroup_std(config, cgrp_name); } } -- GitLab From 33b2e2c2ad68489bc0c97660ef1e6bf7df0c9d7d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:13 -0800 Subject: [PATCH 0541/1480] perf stat: Split aggr_printout() function The aggr_printout() function is to print aggr_id and count (nr). Split it for each output mode to simplify the code. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 220 ++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 99 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index af2a561eb20c2..ed421f6d512f4 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -135,124 +135,135 @@ static void print_cgroup(struct perf_stat_config *config, struct evsel *evsel) } } - -static void aggr_printout(struct perf_stat_config *config, - struct evsel *evsel, struct aggr_cpu_id id, int nr) +static void print_aggr_id_std(struct perf_stat_config *config, + struct evsel *evsel, struct aggr_cpu_id id, int nr) { + FILE *output = config->output; + switch (config->aggr_mode) { + case AGGR_CORE: + fprintf(output, "S%d-D%d-C%*d %*d ", + id.socket, id.die, -8, id.core, 4, nr); + break; + case AGGR_DIE: + fprintf(output, "S%d-D%*d %*d ", + id.socket, -8, id.die, 4, nr); + break; + case AGGR_SOCKET: + fprintf(output, "S%*d %*d ", + -5, id.socket, 4, nr); + break; + case AGGR_NODE: + fprintf(output, "N%*d %*d ", + -5, id.node, 4, nr); + break; + case AGGR_NONE: + if (evsel->percore && !config->percore_show_thread) { + fprintf(output, "S%d-D%d-C%*d ", + id.socket, id.die, -3, id.core); + } else if (id.cpu.cpu > -1) { + fprintf(output, "CPU%*d ", + -7, id.cpu.cpu); + } + break; + case AGGR_THREAD: + fprintf(output, "%*s-%*d ", + 16, perf_thread_map__comm(evsel->core.threads, id.thread_idx), + -8, perf_thread_map__pid(evsel->core.threads, id.thread_idx)); + break; + case AGGR_GLOBAL: + case AGGR_UNSET: + case AGGR_MAX: + default: + break; + } +} - if (config->json_output && !config->interval) - fprintf(config->output, "{"); +static void print_aggr_id_csv(struct perf_stat_config *config, + struct evsel *evsel, struct aggr_cpu_id id, int nr) +{ + FILE *output = config->output; + const char *sep = config->csv_sep; switch (config->aggr_mode) { case AGGR_CORE: - if (config->json_output) { - fprintf(config->output, - "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ", - id.socket, - id.die, - id.core, - nr); - } else { - fprintf(config->output, "S%d-D%d-C%*d%s%*d%s", - id.socket, - id.die, - config->csv_output ? 0 : -8, - id.core, - config->csv_sep, - config->csv_output ? 0 : 4, - nr, - config->csv_sep); - } + fprintf(output, "S%d-D%d-C%d%s%d%s", + id.socket, id.die, id.core, sep, nr, sep); break; case AGGR_DIE: - if (config->json_output) { - fprintf(config->output, - "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ", - id.socket, - id.die, - nr); - } else { - fprintf(config->output, "S%d-D%*d%s%*d%s", - id.socket, - config->csv_output ? 0 : -8, - id.die, - config->csv_sep, - config->csv_output ? 0 : 4, - nr, - config->csv_sep); - } + fprintf(output, "S%d-D%d%s%d%s", + id.socket, id.die, sep, nr, sep); break; case AGGR_SOCKET: - if (config->json_output) { - fprintf(config->output, - "\"socket\" : \"S%d\", \"aggregate-number\" : %d, ", - id.socket, - nr); - } else { - fprintf(config->output, "S%*d%s%*d%s", - config->csv_output ? 0 : -5, - id.socket, - config->csv_sep, - config->csv_output ? 0 : 4, - nr, - config->csv_sep); - } + fprintf(output, "S%d%s%d%s", + id.socket, sep, nr, sep); break; case AGGR_NODE: - if (config->json_output) { - fprintf(config->output, "\"node\" : \"N%d\", \"aggregate-number\" : %d, ", - id.node, - nr); - } else { - fprintf(config->output, "N%*d%s%*d%s", - config->csv_output ? 0 : -5, - id.node, - config->csv_sep, - config->csv_output ? 0 : 4, - nr, - config->csv_sep); - } + fprintf(output, "N%d%s%d%s", + id.node, sep, nr, sep); break; case AGGR_NONE: - if (config->json_output) { - if (evsel->percore && !config->percore_show_thread) { - fprintf(config->output, "\"core\" : \"S%d-D%d-C%d\"", - id.socket, - id.die, - id.core); - } else if (id.cpu.cpu > -1) { - fprintf(config->output, "\"cpu\" : \"%d\", ", - id.cpu.cpu); - } - } else { - if (evsel->percore && !config->percore_show_thread) { - fprintf(config->output, "S%d-D%d-C%*d%s", - id.socket, - id.die, - config->csv_output ? 0 : -3, - id.core, config->csv_sep); - } else if (id.cpu.cpu > -1) { - fprintf(config->output, "CPU%*d%s", - config->csv_output ? 0 : -7, - id.cpu.cpu, config->csv_sep); - } + if (evsel->percore && !config->percore_show_thread) { + fprintf(output, "S%d-D%d-C%d%s", + id.socket, id.die, id.core, sep); + } else if (id.cpu.cpu > -1) { + fprintf(output, "CPU%d%s", + id.cpu.cpu, sep); } break; case AGGR_THREAD: - if (config->json_output) { - fprintf(config->output, "\"thread\" : \"%s-%d\", ", - perf_thread_map__comm(evsel->core.threads, id.thread_idx), - perf_thread_map__pid(evsel->core.threads, id.thread_idx)); - } else { - fprintf(config->output, "%*s-%*d%s", - config->csv_output ? 0 : 16, - perf_thread_map__comm(evsel->core.threads, id.thread_idx), - config->csv_output ? 0 : -8, - perf_thread_map__pid(evsel->core.threads, id.thread_idx), - config->csv_sep); + fprintf(output, "%s-%d%s", + perf_thread_map__comm(evsel->core.threads, id.thread_idx), + perf_thread_map__pid(evsel->core.threads, id.thread_idx), + sep); + break; + case AGGR_GLOBAL: + case AGGR_UNSET: + case AGGR_MAX: + default: + break; + } +} + +static void print_aggr_id_json(struct perf_stat_config *config, + struct evsel *evsel, struct aggr_cpu_id id, int nr) +{ + FILE *output = config->output; + + if (!config->interval) + fputc('{', output); + + switch (config->aggr_mode) { + case AGGR_CORE: + fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ", + id.socket, id.die, id.core, nr); + break; + case AGGR_DIE: + fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ", + id.socket, id.die, nr); + break; + case AGGR_SOCKET: + fprintf(output, "\"socket\" : \"S%d\", \"aggregate-number\" : %d, ", + id.socket, nr); + break; + case AGGR_NODE: + fprintf(output, "\"node\" : \"N%d\", \"aggregate-number\" : %d, ", + id.node, nr); + break; + case AGGR_NONE: + if (evsel->percore && !config->percore_show_thread) { + fprintf(output, "\"core\" : \"S%d-D%d-C%d\"", + id.socket, id.die, id.core); + } else if (id.cpu.cpu > -1) { + fprintf(output, "\"cpu\" : \"%d\", ", + id.cpu.cpu); } break; + case AGGR_THREAD: + fprintf(output, "\"thread\" : \"%s-%d\", ", + perf_thread_map__comm(evsel->core.threads, id.thread_idx), + perf_thread_map__pid(evsel->core.threads, id.thread_idx)); + break; case AGGR_GLOBAL: case AGGR_UNSET: case AGGR_MAX: @@ -261,6 +272,17 @@ static void aggr_printout(struct perf_stat_config *config, } } +static void aggr_printout(struct perf_stat_config *config, + struct evsel *evsel, struct aggr_cpu_id id, int nr) +{ + if (config->json_output) + print_aggr_id_json(config, evsel, id, nr); + else if (config->csv_output) + print_aggr_id_csv(config, evsel, id, nr); + else + print_aggr_id_std(config, evsel, id, nr); +} + struct outstate { FILE *fh; bool newline; -- GitLab From c2019f844eacd06decc435bdcee9eab1e1a6f4ec Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:14 -0800 Subject: [PATCH 0542/1480] perf stat: Factor out print_counter_value() function And split it for each output mode like others. I believe it makes the code simpler and more intuitive. Now abs_printout() becomes just to call sub-functions. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 81 ++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index ed421f6d512f4..a72c7442ff3dd 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -517,46 +517,71 @@ static void print_metric_header(struct perf_stat_config *config, fprintf(os->fh, "%*s ", config->metric_only_len, unit); } -static void abs_printout(struct perf_stat_config *config, - struct aggr_cpu_id id, int nr, struct evsel *evsel, double avg) +static void print_counter_value_std(struct perf_stat_config *config, + struct evsel *evsel, double avg) { FILE *output = config->output; double sc = evsel->scale; const char *fmt; - if (config->csv_output) { - fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s"; - } else { - if (config->big_num) - fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s"; - else - fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s"; - } + if (config->big_num) + fmt = floor(sc) != sc ? "%'18.2f " : "%'18.0f "; + else + fmt = floor(sc) != sc ? "%18.2f " : "%18.0f "; - aggr_printout(config, evsel, id, nr); + fprintf(output, fmt, avg); - if (config->json_output) - fprintf(output, "\"counter-value\" : \"%f\", ", avg); - else - fprintf(output, fmt, avg, config->csv_sep); + if (evsel->unit) + fprintf(output, "%-*s ", config->unit_width, evsel->unit); - if (config->json_output) { - if (evsel->unit) { - fprintf(output, "\"unit\" : \"%s\", ", - evsel->unit); - } - } else { - if (evsel->unit) - fprintf(output, "%-*s%s", - config->csv_output ? 0 : config->unit_width, - evsel->unit, config->csv_sep); - } + fprintf(output, "%-*s", 32, evsel__name(evsel)); +} +static void print_counter_value_csv(struct perf_stat_config *config, + struct evsel *evsel, double avg) +{ + FILE *output = config->output; + double sc = evsel->scale; + const char *sep = config->csv_sep; + const char *fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s"; + + fprintf(output, fmt, avg, sep); + + if (evsel->unit) + fprintf(output, "%s%s", evsel->unit, sep); + + fprintf(output, "%s", evsel__name(evsel)); +} + +static void print_counter_value_json(struct perf_stat_config *config, + struct evsel *evsel, double avg) +{ + FILE *output = config->output; + + fprintf(output, "\"counter-value\" : \"%f\", ", avg); + + if (evsel->unit) + fprintf(output, "\"unit\" : \"%s\", ", evsel->unit); + + fprintf(output, "\"event\" : \"%s\", ", evsel__name(evsel)); +} + +static void print_counter_value(struct perf_stat_config *config, + struct evsel *evsel, double avg) +{ if (config->json_output) - fprintf(output, "\"event\" : \"%s\", ", evsel__name(evsel)); + print_counter_value_json(config, evsel, avg); + else if (config->csv_output) + print_counter_value_csv(config, evsel, avg); else - fprintf(output, "%-*s", config->csv_output ? 0 : 32, evsel__name(evsel)); + print_counter_value_std(config, evsel, avg); +} +static void abs_printout(struct perf_stat_config *config, + struct aggr_cpu_id id, int nr, struct evsel *evsel, double avg) +{ + aggr_printout(config, evsel, id, nr); + print_counter_value(config, evsel, avg); print_cgroup(config, evsel); } -- GitLab From d6aeb861b1fb26f55c1b5be4b6e900ad1e734516 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:15 -0800 Subject: [PATCH 0543/1480] perf stat: Handle bad events in abs_printout() In the printout() function, it checks if the event is bad (i.e. not counted or not supported) and print the result. But it does the same what abs_printout() is doing. So add an argument to indicate the value is ok or not and use the same function in both cases. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 68 ++++++++++++++-------------------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index a72c7442ff3dd..fe54838932894 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -518,18 +518,22 @@ static void print_metric_header(struct perf_stat_config *config, } static void print_counter_value_std(struct perf_stat_config *config, - struct evsel *evsel, double avg) + struct evsel *evsel, double avg, bool ok) { FILE *output = config->output; double sc = evsel->scale; const char *fmt; + const char *bad_count = evsel->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED; if (config->big_num) fmt = floor(sc) != sc ? "%'18.2f " : "%'18.0f "; else fmt = floor(sc) != sc ? "%18.2f " : "%18.0f "; - fprintf(output, fmt, avg); + if (ok) + fprintf(output, fmt, avg); + else + fprintf(output, "%18s ", bad_count); if (evsel->unit) fprintf(output, "%-*s ", config->unit_width, evsel->unit); @@ -538,14 +542,18 @@ static void print_counter_value_std(struct perf_stat_config *config, } static void print_counter_value_csv(struct perf_stat_config *config, - struct evsel *evsel, double avg) + struct evsel *evsel, double avg, bool ok) { FILE *output = config->output; double sc = evsel->scale; const char *sep = config->csv_sep; const char *fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s"; + const char *bad_count = evsel->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED; - fprintf(output, fmt, avg, sep); + if (ok) + fprintf(output, fmt, avg, sep); + else + fprintf(output, "%s%s", bad_count, sep); if (evsel->unit) fprintf(output, "%s%s", evsel->unit, sep); @@ -554,11 +562,15 @@ static void print_counter_value_csv(struct perf_stat_config *config, } static void print_counter_value_json(struct perf_stat_config *config, - struct evsel *evsel, double avg) + struct evsel *evsel, double avg, bool ok) { FILE *output = config->output; + const char *bad_count = evsel->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED; - fprintf(output, "\"counter-value\" : \"%f\", ", avg); + if (ok) + fprintf(output, "\"counter-value\" : \"%f\", ", avg); + else + fprintf(output, "\"counter-value\" : \"%s\", ", bad_count); if (evsel->unit) fprintf(output, "\"unit\" : \"%s\", ", evsel->unit); @@ -567,21 +579,22 @@ static void print_counter_value_json(struct perf_stat_config *config, } static void print_counter_value(struct perf_stat_config *config, - struct evsel *evsel, double avg) + struct evsel *evsel, double avg, bool ok) { if (config->json_output) - print_counter_value_json(config, evsel, avg); + print_counter_value_json(config, evsel, avg, ok); else if (config->csv_output) - print_counter_value_csv(config, evsel, avg); + print_counter_value_csv(config, evsel, avg, ok); else - print_counter_value_std(config, evsel, avg); + print_counter_value_std(config, evsel, avg, ok); } static void abs_printout(struct perf_stat_config *config, - struct aggr_cpu_id id, int nr, struct evsel *evsel, double avg) + struct aggr_cpu_id id, int nr, + struct evsel *evsel, double avg, bool ok) { aggr_printout(config, evsel, id, nr); - print_counter_value(config, evsel, avg); + print_counter_value(config, evsel, avg, ok); print_cgroup(config, evsel); } @@ -658,17 +671,8 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int pm(config, &os, NULL, "", "", 0); return; } - aggr_printout(config, counter, id, nr); - if (config->json_output) { - fprintf(config->output, "\"counter-value\" : \"%s\", ", - counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED); - } else { - fprintf(config->output, "%*s%s", - config->csv_output ? 0 : 18, - counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, - config->csv_sep); - } + abs_printout(config, id, nr, counter, uval, /*ok=*/false); if (counter->supported) { if (!evlist__has_hybrid(counter->evlist)) { @@ -678,24 +682,6 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int } } - if (config->json_output) { - fprintf(config->output, "\"unit\" : \"%s\", ", counter->unit); - } else { - fprintf(config->output, "%-*s%s", - config->csv_output ? 0 : config->unit_width, - counter->unit, config->csv_sep); - } - - if (config->json_output) { - fprintf(config->output, "\"event\" : \"%s\", ", - evsel__name(counter)); - } else { - fprintf(config->output, "%*s", - config->csv_output ? 0 : -25, evsel__name(counter)); - } - - print_cgroup(config, counter); - if (!config->csv_output && !config->json_output) pm(config, &os, NULL, NULL, "", 0); print_noise(config, counter, noise); @@ -706,7 +692,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int } if (!config->metric_only) - abs_printout(config, id, nr, counter, uval); + abs_printout(config, id, nr, counter, uval, /*ok=*/true); out.print_metric = pm; out.new_line = nl; -- GitLab From df46a3c92b510b7776fed14728a271f8836ef19b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:16 -0800 Subject: [PATCH 0544/1480] perf stat: Add before_metric argument Unfortunately, event running time, percentage and noise data are printed in different positions in normal output than CSV/JSON. I think it's better to put such details in where it actually prints. So add before_metric argument to print_noise() and print_running() and call them twice before and after the metric. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 82 +++++++++++++++++----------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index fe54838932894..bf3f2f9d5deec 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -52,14 +52,18 @@ static void print_running_json(struct perf_stat_config *config, u64 run, u64 ena } static void print_running(struct perf_stat_config *config, - u64 run, u64 ena) + u64 run, u64 ena, bool before_metric) { - if (config->json_output) - print_running_json(config, run, ena); - else if (config->csv_output) - print_running_csv(config, run, ena); - else - print_running_std(config, run, ena); + if (config->json_output) { + if (before_metric) + print_running_json(config, run, ena); + } else if (config->csv_output) { + if (before_metric) + print_running_csv(config, run, ena); + } else { + if (!before_metric) + print_running_std(config, run, ena); + } } static void print_noise_pct_std(struct perf_stat_config *config, @@ -82,20 +86,24 @@ static void print_noise_pct_json(struct perf_stat_config *config, } static void print_noise_pct(struct perf_stat_config *config, - double total, double avg) + double total, double avg, bool before_metric) { double pct = rel_stddev_stats(total, avg); - if (config->json_output) - print_noise_pct_json(config, pct); - else if (config->csv_output) - print_noise_pct_csv(config, pct); - else - print_noise_pct_std(config, pct); + if (config->json_output) { + if (before_metric) + print_noise_pct_json(config, pct); + } else if (config->csv_output) { + if (before_metric) + print_noise_pct_csv(config, pct); + } else { + if (!before_metric) + print_noise_pct_std(config, pct); + } } static void print_noise(struct perf_stat_config *config, - struct evsel *evsel, double avg) + struct evsel *evsel, double avg, bool before_metric) { struct perf_stat_evsel *ps; @@ -103,7 +111,7 @@ static void print_noise(struct perf_stat_config *config, return; ps = evsel->stats; - print_noise_pct(config, stddev_stats(&ps->res_stats), avg); + print_noise_pct(config, stddev_stats(&ps->res_stats), avg, before_metric); } static void print_cgroup_std(struct perf_stat_config *config, const char *cgrp_name) @@ -637,6 +645,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int }; print_metric_t pm; new_line_t nl; + bool ok = true; if (config->csv_output) { static const int aggr_fields[AGGR_MAX] = { @@ -672,7 +681,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int return; } - abs_printout(config, id, nr, counter, uval, /*ok=*/false); + ok = false; if (counter->supported) { if (!evlist__has_hybrid(counter->evlist)) { @@ -681,37 +690,30 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int config->print_mixed_hw_group_error = 1; } } - - if (!config->csv_output && !config->json_output) - pm(config, &os, NULL, NULL, "", 0); - print_noise(config, counter, noise); - print_running(config, run, ena); - if (config->csv_output || config->json_output) - pm(config, &os, NULL, NULL, "", 0); - return; } - if (!config->metric_only) - abs_printout(config, id, nr, counter, uval, /*ok=*/true); - out.print_metric = pm; out.new_line = nl; out.ctx = &os; out.force_header = false; - if (config->csv_output && !config->metric_only) { - print_noise(config, counter, noise); - print_running(config, run, ena); - } else if (config->json_output && !config->metric_only) { - print_noise(config, counter, noise); - print_running(config, run, ena); + if (!config->metric_only) { + abs_printout(config, id, nr, counter, uval, ok); + + print_noise(config, counter, noise, /*before_metric=*/true); + print_running(config, run, ena, /*before_metric=*/true); + } + + if (ok) { + perf_stat__print_shadow_stats(config, counter, uval, map_idx, + &out, &config->metric_events, st); + } else { + pm(config, &os, /*color=*/NULL, /*format=*/NULL, /*unit=*/"", /*val=*/0); } - perf_stat__print_shadow_stats(config, counter, uval, map_idx, - &out, &config->metric_events, st); - if (!config->csv_output && !config->metric_only && !config->json_output) { - print_noise(config, counter, noise); - print_running(config, run, ena); + if (!config->metric_only) { + print_noise(config, counter, noise, /*before_metric=*/false); + print_running(config, run, ena, /*before_metric=*/false); } } @@ -1151,7 +1153,7 @@ static void print_footer(struct perf_stat_config *config) fprintf(output, " %17.*f +- %.*f seconds time elapsed", precision, avg, precision, sd); - print_noise_pct(config, sd, avg); + print_noise_pct(config, sd, avg, /*before_metric=*/false); } fprintf(output, "\n\n"); -- GitLab From 8d500292bd55c05130c96f6e84cc3e6ba3ebed99 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:17 -0800 Subject: [PATCH 0545/1480] perf stat: Align cgroup names We don't know how long cgroup name is, but at least we can align short ones like below. $ perf stat -a --for-each-cgroup system.slice,user.slice true Performance counter stats for 'system wide': 0.13 msec cpu-clock system.slice # 0.010 CPUs utilized 4 context-switches system.slice # 31.989 K/sec 1 cpu-migrations system.slice # 7.997 K/sec 0 page-faults system.slice # 0.000 /sec 450,673 cycles system.slice # 3.604 GHz (92.41%) 161,216 instructions system.slice # 0.36 insn per cycle (92.41%) 32,678 branches system.slice # 261.332 M/sec (92.41%) 2,628 branch-misses system.slice # 8.04% of all branches (92.41%) 14.29 msec cpu-clock user.slice # 1.163 CPUs utilized 35 context-switches user.slice # 2.449 K/sec 12 cpu-migrations user.slice # 839.691 /sec 57 page-faults user.slice # 3.989 K/sec 49,683,026 cycles user.slice # 3.477 GHz (99.38%) 110,790,266 instructions user.slice # 2.23 insn per cycle (99.38%) 24,552,255 branches user.slice # 1.718 G/sec (99.38%) 127,779 branch-misses user.slice # 0.52% of all branches (99.38%) 0.012289431 seconds time elapsed Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-10-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bf3f2f9d5deec..e66f766a3d786 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -116,7 +116,7 @@ static void print_noise(struct perf_stat_config *config, static void print_cgroup_std(struct perf_stat_config *config, const char *cgrp_name) { - fprintf(config->output, " %s", cgrp_name); + fprintf(config->output, " %-16s", cgrp_name); } static void print_cgroup_csv(struct perf_stat_config *config, const char *cgrp_name) -- GitLab From b2d9832e00a0d93ad6127fa8ccf2b8e0cfe67397 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:18 -0800 Subject: [PATCH 0546/1480] perf stat: Split print_metric_headers() function The print_metric_headers() shows metric headers a little bit for each mode. Split it out to make the code clearer. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-11-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 52 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index e66f766a3d786..bb2791459f5f0 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -924,6 +924,37 @@ static const char *aggr_header_csv[] = { [AGGR_GLOBAL] = "" }; +static void print_metric_headers_std(struct perf_stat_config *config, + const char *prefix, bool no_indent) +{ + if (prefix) + fprintf(config->output, "%s", prefix); + if (!no_indent) { + fprintf(config->output, "%*s", + aggr_header_lens[config->aggr_mode], ""); + } +} + +static void print_metric_headers_csv(struct perf_stat_config *config, + const char *prefix, + bool no_indent __maybe_unused) +{ + if (prefix) + fprintf(config->output, "%s", prefix); + if (config->interval) + fputs("time,", config->output); + if (!config->iostat_run) + fputs(aggr_header_csv[config->aggr_mode], config->output); +} + +static void print_metric_headers_json(struct perf_stat_config *config, + const char *prefix __maybe_unused, + bool no_indent __maybe_unused) +{ + if (config->interval) + fputs("{\"unit\" : \"sec\"}", config->output); +} + static void print_metric_headers(struct perf_stat_config *config, struct evlist *evlist, const char *prefix, bool no_indent) @@ -939,22 +970,13 @@ static void print_metric_headers(struct perf_stat_config *config, .force_header = true, }; - if (prefix && !config->json_output) - fprintf(config->output, "%s", prefix); + if (config->json_output) + print_metric_headers_json(config, prefix, no_indent); + else if (config->csv_output) + print_metric_headers_csv(config, prefix, no_indent); + else + print_metric_headers_std(config, prefix, no_indent); - if (!config->csv_output && !config->json_output && !no_indent) - fprintf(config->output, "%*s", - aggr_header_lens[config->aggr_mode], ""); - if (config->csv_output) { - if (config->interval) - fputs("time,", config->output); - if (!config->iostat_run) - fputs(aggr_header_csv[config->aggr_mode], config->output); - } - if (config->json_output) { - if (config->interval) - fputs("{\"unit\" : \"sec\"}", config->output); - } if (config->iostat_run) iostat_print_header_prefix(config); -- GitLab From 208cbcd21bf57c80ceaf90fcec16cfdfb55a0a4d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:19 -0800 Subject: [PATCH 0547/1480] perf stat: Factor out prepare_interval() This logic does not print the time directly, but it just puts the timestamp in the buffer as a prefix. To reduce the confusion, factor out the code into a separate function. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-12-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 39 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bb2791459f5f0..c234be656db93 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -993,9 +993,25 @@ static void print_metric_headers(struct perf_stat_config *config, fputc('\n', config->output); } +static void prepare_interval(struct perf_stat_config *config, + char *prefix, struct timespec *ts) +{ + if (config->iostat_run) + return; + + if (!config->json_output) + sprintf(prefix, "%6lu.%09lu%s", (unsigned long) ts->tv_sec, + ts->tv_nsec, config->csv_sep); + else if (!config->metric_only) + sprintf(prefix, "{\"interval\" : %lu.%09lu, ", (unsigned long) + ts->tv_sec, ts->tv_nsec); + else + sprintf(prefix, "{\"interval\" : %lu.%09lu}", (unsigned long) + ts->tv_sec, ts->tv_nsec); +} + static void print_interval(struct perf_stat_config *config, - struct evlist *evlist, - char *prefix, struct timespec *ts) + struct evlist *evlist) { bool metric_only = config->metric_only; unsigned int unit_width = config->unit_width; @@ -1005,16 +1021,6 @@ static void print_interval(struct perf_stat_config *config, if (config->interval_clear && isatty(fileno(output))) puts(CONSOLE_CLEAR); - if (!config->iostat_run && !config->json_output) - sprintf(prefix, "%6lu.%09lu%s", (unsigned long) ts->tv_sec, - ts->tv_nsec, config->csv_sep); - if (!config->iostat_run && config->json_output && !config->metric_only) - sprintf(prefix, "{\"interval\" : %lu.%09lu, ", (unsigned long) - ts->tv_sec, ts->tv_nsec); - if (!config->iostat_run && config->json_output && config->metric_only) - sprintf(prefix, "{\"interval\" : %lu.%09lu}", (unsigned long) - ts->tv_sec, ts->tv_nsec); - if ((num_print_interval == 0 || config->interval_clear) && !config->csv_output && !config->json_output) { switch (config->aggr_mode) { @@ -1252,10 +1258,13 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf if (config->iostat_run) evlist->selected = evlist__first(evlist); - if (interval) - print_interval(config, evlist, prefix = buf, ts); - else + if (interval) { + prefix = buf; + prepare_interval(config, prefix, ts); + print_interval(config, evlist); + } else { print_header(config, _target, argc, argv); + } if (metric_only) { static int num_print_iv; -- GitLab From 33c4ed47990f3eaaa732d3fcc2760e6165c16c40 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:20 -0800 Subject: [PATCH 0548/1480] perf stat: Cleanup interval print alignment Instead of using magic values, define symbolic constants and use them. Also add aggr_header_std[] array to simplify aggr_mode handling. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-13-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 165 ++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 74 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index c234be656db93..f983432aaddde 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -25,6 +25,45 @@ #define CNTR_NOT_SUPPORTED "" #define CNTR_NOT_COUNTED "" +#define METRIC_LEN 38 +#define EVNAME_LEN 32 +#define COUNTS_LEN 18 +#define INTERVAL_LEN 16 +#define CGROUP_LEN 16 +#define COMM_LEN 16 +#define PID_LEN 7 +#define CPUS_LEN 4 + +static int aggr_header_lens[] = { + [AGGR_CORE] = 18, + [AGGR_DIE] = 12, + [AGGR_SOCKET] = 6, + [AGGR_NODE] = 6, + [AGGR_NONE] = 6, + [AGGR_THREAD] = 16, + [AGGR_GLOBAL] = 0, +}; + +static const char *aggr_header_csv[] = { + [AGGR_CORE] = "core,cpus,", + [AGGR_DIE] = "die,cpus,", + [AGGR_SOCKET] = "socket,cpus,", + [AGGR_NONE] = "cpu,", + [AGGR_THREAD] = "comm-pid,", + [AGGR_NODE] = "node,", + [AGGR_GLOBAL] = "" +}; + +static const char *aggr_header_std[] = { + [AGGR_CORE] = "core", + [AGGR_DIE] = "die", + [AGGR_SOCKET] = "socket", + [AGGR_NONE] = "cpu", + [AGGR_THREAD] = "comm-pid", + [AGGR_NODE] = "node", + [AGGR_GLOBAL] = "" +}; + static void print_running_std(struct perf_stat_config *config, u64 run, u64 ena) { if (run != ena) @@ -116,7 +155,7 @@ static void print_noise(struct perf_stat_config *config, static void print_cgroup_std(struct perf_stat_config *config, const char *cgrp_name) { - fprintf(config->output, " %-16s", cgrp_name); + fprintf(config->output, " %-*s", CGROUP_LEN, cgrp_name); } static void print_cgroup_csv(struct perf_stat_config *config, const char *cgrp_name) @@ -147,44 +186,46 @@ static void print_aggr_id_std(struct perf_stat_config *config, struct evsel *evsel, struct aggr_cpu_id id, int nr) { FILE *output = config->output; + int idx = config->aggr_mode; + char buf[128]; switch (config->aggr_mode) { case AGGR_CORE: - fprintf(output, "S%d-D%d-C%*d %*d ", - id.socket, id.die, -8, id.core, 4, nr); + snprintf(buf, sizeof(buf), "S%d-D%d-C%d", id.socket, id.die, id.core); break; case AGGR_DIE: - fprintf(output, "S%d-D%*d %*d ", - id.socket, -8, id.die, 4, nr); + snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die); break; case AGGR_SOCKET: - fprintf(output, "S%*d %*d ", - -5, id.socket, 4, nr); + snprintf(buf, sizeof(buf), "S%d", id.socket); break; case AGGR_NODE: - fprintf(output, "N%*d %*d ", - -5, id.node, 4, nr); + snprintf(buf, sizeof(buf), "N%d", id.node); break; case AGGR_NONE: if (evsel->percore && !config->percore_show_thread) { - fprintf(output, "S%d-D%d-C%*d ", - id.socket, id.die, -3, id.core); + snprintf(buf, sizeof(buf), "S%d-D%d-C%d ", + id.socket, id.die, id.core); + fprintf(output, "%-*s ", + aggr_header_lens[AGGR_CORE], buf); } else if (id.cpu.cpu > -1) { - fprintf(output, "CPU%*d ", - -7, id.cpu.cpu); + fprintf(output, "CPU%-*d ", + aggr_header_lens[AGGR_NONE] - 3, id.cpu.cpu); } - break; + return; case AGGR_THREAD: - fprintf(output, "%*s-%*d ", - 16, perf_thread_map__comm(evsel->core.threads, id.thread_idx), - -8, perf_thread_map__pid(evsel->core.threads, id.thread_idx)); - break; + fprintf(output, "%*s-%-*d ", + COMM_LEN, perf_thread_map__comm(evsel->core.threads, id.thread_idx), + PID_LEN, perf_thread_map__pid(evsel->core.threads, id.thread_idx)); + return; case AGGR_GLOBAL: case AGGR_UNSET: case AGGR_MAX: default: - break; + return; } + + fprintf(output, "%-*s %*d ", aggr_header_lens[idx], buf, 4, nr); } static void print_aggr_id_csv(struct perf_stat_config *config, @@ -301,8 +342,6 @@ struct outstate { struct evsel *evsel; }; -#define METRIC_LEN 38 - static void new_line_std(struct perf_stat_config *config __maybe_unused, void *ctx) { @@ -534,19 +573,19 @@ static void print_counter_value_std(struct perf_stat_config *config, const char *bad_count = evsel->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED; if (config->big_num) - fmt = floor(sc) != sc ? "%'18.2f " : "%'18.0f "; + fmt = floor(sc) != sc ? "%'*.2f " : "%'*.0f "; else - fmt = floor(sc) != sc ? "%18.2f " : "%18.0f "; + fmt = floor(sc) != sc ? "%*.2f " : "%*.0f "; if (ok) - fprintf(output, fmt, avg); + fprintf(output, fmt, COUNTS_LEN, avg); else - fprintf(output, "%18s ", bad_count); + fprintf(output, "%*s ", COUNTS_LEN, bad_count); if (evsel->unit) fprintf(output, "%-*s ", config->unit_width, evsel->unit); - fprintf(output, "%-*s", 32, evsel__name(evsel)); + fprintf(output, "%-*s", EVNAME_LEN, evsel__name(evsel)); } static void print_counter_value_csv(struct perf_stat_config *config, @@ -904,34 +943,19 @@ static void print_no_aggr_metric(struct perf_stat_config *config, } } -static int aggr_header_lens[] = { - [AGGR_CORE] = 24, - [AGGR_DIE] = 18, - [AGGR_SOCKET] = 12, - [AGGR_NONE] = 6, - [AGGR_THREAD] = 24, - [AGGR_NODE] = 6, - [AGGR_GLOBAL] = 0, -}; - -static const char *aggr_header_csv[] = { - [AGGR_CORE] = "core,cpus,", - [AGGR_DIE] = "die,cpus,", - [AGGR_SOCKET] = "socket,cpus,", - [AGGR_NONE] = "cpu,", - [AGGR_THREAD] = "comm-pid,", - [AGGR_NODE] = "node,", - [AGGR_GLOBAL] = "" -}; - static void print_metric_headers_std(struct perf_stat_config *config, const char *prefix, bool no_indent) { if (prefix) fprintf(config->output, "%s", prefix); + if (!no_indent) { - fprintf(config->output, "%*s", - aggr_header_lens[config->aggr_mode], ""); + int len = aggr_header_lens[config->aggr_mode]; + + if (nr_cgroups) + len += CGROUP_LEN + 1; + + fprintf(config->output, "%*s", len, ""); } } @@ -1025,46 +1049,39 @@ static void print_interval(struct perf_stat_config *config, !config->csv_output && !config->json_output) { switch (config->aggr_mode) { case AGGR_NODE: - fprintf(output, "# time node cpus"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); - break; case AGGR_SOCKET: - fprintf(output, "# time socket cpus"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); - break; case AGGR_DIE: - fprintf(output, "# time die cpus"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); - break; case AGGR_CORE: - fprintf(output, "# time core cpus"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); + fprintf(output, "#%*s %-*s cpus", + INTERVAL_LEN - 1, "time", + aggr_header_lens[config->aggr_mode], + aggr_header_std[config->aggr_mode]); break; case AGGR_NONE: - fprintf(output, "# time CPU "); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); + fprintf(output, "#%*s %-*s", + INTERVAL_LEN - 1, "time", + aggr_header_lens[config->aggr_mode], + aggr_header_std[config->aggr_mode]); break; case AGGR_THREAD: - fprintf(output, "# time comm-pid"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); + fprintf(output, "#%*s %*s-%-*s", + INTERVAL_LEN - 1, "time", + COMM_LEN, "comm", PID_LEN, "pid"); break; case AGGR_GLOBAL: default: - if (!config->iostat_run) { - fprintf(output, "# time"); - if (!metric_only) - fprintf(output, " counts %*s events\n", unit_width, "unit"); - } + if (!config->iostat_run) + fprintf(output, "#%*s", + INTERVAL_LEN - 1, "time"); case AGGR_UNSET: case AGGR_MAX: break; } + + if (!metric_only) { + fprintf(output, " %*s %*s events\n", + COUNTS_LEN, "counts", unit_width, "unit"); + } } if ((num_print_interval == 0 || config->interval_clear) && metric_only) -- GitLab From 6108712c07422f8ececb163ace7fad2ae0e9a24c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:21 -0800 Subject: [PATCH 0549/1480] perf stat: Remove impossible condition The print would run only if metric_only is not set, but it's already in a block that says it's in metric_only case. And there's no place to change the setting. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-14-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f983432aaddde..cc8bb6d07dcb2 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1292,9 +1292,6 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf num_print_iv = 0; if (config->aggr_mode == AGGR_GLOBAL && prefix && !config->iostat_run) fprintf(config->output, "%s", prefix); - - if (config->json_output && !config->metric_only) - fprintf(config->output, "}"); } switch (config->aggr_mode) { -- GitLab From 4c86b664f4cce6940c187ecfc019f434f8dbd4bc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:22 -0800 Subject: [PATCH 0550/1480] perf stat: Rework header display There are print_header() and print_interval() to print header lines before actual counter values. Also print_metric_headers() needs to be called for the metric-only case. Let's move all these logics to a single place including num_print_iv to refresh the headers for interval mode. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-15-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 185 +++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 79 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index cc8bb6d07dcb2..f97817628478d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1034,94 +1034,129 @@ static void prepare_interval(struct perf_stat_config *config, ts->tv_sec, ts->tv_nsec); } -static void print_interval(struct perf_stat_config *config, - struct evlist *evlist) +static void print_header_interval_std(struct perf_stat_config *config, + struct target *_target __maybe_unused, + struct evlist *evlist, + int argc __maybe_unused, + const char **argv __maybe_unused) { - bool metric_only = config->metric_only; - unsigned int unit_width = config->unit_width; FILE *output = config->output; - static int num_print_interval; - if (config->interval_clear && isatty(fileno(output))) - puts(CONSOLE_CLEAR); + switch (config->aggr_mode) { + case AGGR_NODE: + case AGGR_SOCKET: + case AGGR_DIE: + case AGGR_CORE: + fprintf(output, "#%*s %-*s cpus", + INTERVAL_LEN - 1, "time", + aggr_header_lens[config->aggr_mode], + aggr_header_std[config->aggr_mode]); + break; + case AGGR_NONE: + fprintf(output, "#%*s %-*s", + INTERVAL_LEN - 1, "time", + aggr_header_lens[config->aggr_mode], + aggr_header_std[config->aggr_mode]); + break; + case AGGR_THREAD: + fprintf(output, "#%*s %*s-%-*s", + INTERVAL_LEN - 1, "time", + COMM_LEN, "comm", PID_LEN, "pid"); + break; + case AGGR_GLOBAL: + default: + if (!config->iostat_run) + fprintf(output, "#%*s", + INTERVAL_LEN - 1, "time"); + case AGGR_UNSET: + case AGGR_MAX: + break; + } - if ((num_print_interval == 0 || config->interval_clear) && - !config->csv_output && !config->json_output) { - switch (config->aggr_mode) { - case AGGR_NODE: - case AGGR_SOCKET: - case AGGR_DIE: - case AGGR_CORE: - fprintf(output, "#%*s %-*s cpus", - INTERVAL_LEN - 1, "time", - aggr_header_lens[config->aggr_mode], - aggr_header_std[config->aggr_mode]); - break; - case AGGR_NONE: - fprintf(output, "#%*s %-*s", - INTERVAL_LEN - 1, "time", - aggr_header_lens[config->aggr_mode], - aggr_header_std[config->aggr_mode]); - break; - case AGGR_THREAD: - fprintf(output, "#%*s %*s-%-*s", - INTERVAL_LEN - 1, "time", - COMM_LEN, "comm", PID_LEN, "pid"); - break; - case AGGR_GLOBAL: - default: - if (!config->iostat_run) - fprintf(output, "#%*s", - INTERVAL_LEN - 1, "time"); - case AGGR_UNSET: - case AGGR_MAX: - break; - } + if (config->metric_only) + print_metric_headers(config, evlist, " ", true); + else + fprintf(output, " %*s %*s events\n", + COUNTS_LEN, "counts", config->unit_width, "unit"); +} - if (!metric_only) { - fprintf(output, " %*s %*s events\n", - COUNTS_LEN, "counts", unit_width, "unit"); - } - } +static void print_header_std(struct perf_stat_config *config, + struct target *_target, struct evlist *evlist, + int argc, const char **argv) +{ + FILE *output = config->output; + int i; + + fprintf(output, "\n"); + fprintf(output, " Performance counter stats for "); + if (_target->bpf_str) + fprintf(output, "\'BPF program(s) %s", _target->bpf_str); + else if (_target->system_wide) + fprintf(output, "\'system wide"); + else if (_target->cpu_list) + fprintf(output, "\'CPU(s) %s", _target->cpu_list); + else if (!target__has_task(_target)) { + fprintf(output, "\'%s", argv ? argv[0] : "pipe"); + for (i = 1; argv && (i < argc); i++) + fprintf(output, " %s", argv[i]); + } else if (_target->pid) + fprintf(output, "process id \'%s", _target->pid); + else + fprintf(output, "thread id \'%s", _target->tid); - if ((num_print_interval == 0 || config->interval_clear) && metric_only) + fprintf(output, "\'"); + if (config->run_count > 1) + fprintf(output, " (%d runs)", config->run_count); + fprintf(output, ":\n\n"); + + if (config->metric_only) + print_metric_headers(config, evlist, " ", false); +} + +static void print_header_csv(struct perf_stat_config *config, + struct target *_target __maybe_unused, + struct evlist *evlist, + int argc __maybe_unused, + const char **argv __maybe_unused) +{ + if (config->metric_only) + print_metric_headers(config, evlist, " ", true); +} +static void print_header_json(struct perf_stat_config *config, + struct target *_target __maybe_unused, + struct evlist *evlist, + int argc __maybe_unused, + const char **argv __maybe_unused) +{ + if (config->metric_only) print_metric_headers(config, evlist, " ", true); - if (++num_print_interval == 25) - num_print_interval = 0; } static void print_header(struct perf_stat_config *config, struct target *_target, + struct evlist *evlist, int argc, const char **argv) { - FILE *output = config->output; - int i; + static int num_print_iv; fflush(stdout); - if (!config->csv_output && !config->json_output) { - fprintf(output, "\n"); - fprintf(output, " Performance counter stats for "); - if (_target->bpf_str) - fprintf(output, "\'BPF program(s) %s", _target->bpf_str); - else if (_target->system_wide) - fprintf(output, "\'system wide"); - else if (_target->cpu_list) - fprintf(output, "\'CPU(s) %s", _target->cpu_list); - else if (!target__has_task(_target)) { - fprintf(output, "\'%s", argv ? argv[0] : "pipe"); - for (i = 1; argv && (i < argc); i++) - fprintf(output, " %s", argv[i]); - } else if (_target->pid) - fprintf(output, "process id \'%s", _target->pid); - else - fprintf(output, "thread id \'%s", _target->tid); + if (config->interval_clear) + puts(CONSOLE_CLEAR); - fprintf(output, "\'"); - if (config->run_count > 1) - fprintf(output, " (%d runs)", config->run_count); - fprintf(output, ":\n\n"); + if (num_print_iv == 0 || config->interval_clear) { + if (config->json_output) + print_header_json(config, _target, evlist, argc, argv); + else if (config->csv_output) + print_header_csv(config, _target, evlist, argc, argv); + else if (config->interval) + print_header_interval_std(config, _target, evlist, argc, argv); + else + print_header_std(config, _target, evlist, argc, argv); } + + if (num_print_iv++ == 25) + num_print_iv = 0; } static int get_precision(double num) @@ -1278,18 +1313,10 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf if (interval) { prefix = buf; prepare_interval(config, prefix, ts); - print_interval(config, evlist); - } else { - print_header(config, _target, argc, argv); } + print_header(config, _target, evlist, argc, argv); if (metric_only) { - static int num_print_iv; - - if (num_print_iv == 0 && !interval) - print_metric_headers(config, evlist, prefix, false); - if (num_print_iv++ == 25) - num_print_iv = 0; if (config->aggr_mode == AGGR_GLOBAL && prefix && !config->iostat_run) fprintf(config->output, "%s", prefix); } -- GitLab From 453279d5739f12cf27b604c84c061a8a7a3937da Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:23 -0800 Subject: [PATCH 0551/1480] perf stat: Move condition to print_footer() Likewise, I think it'd better to have the control inside the function, and keep the higher level function clearer. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-16-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f97817628478d..73cf898060c06 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1205,6 +1205,9 @@ static void print_footer(struct perf_stat_config *config) double avg = avg_stats(config->walltime_nsecs_stats) / NSEC_PER_SEC; FILE *output = config->output; + if (config->interval || config->csv_output || config->json_output) + return; + if (!config->null_run) fprintf(output, "\n"); @@ -1359,8 +1362,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf break; } - if (!interval && !config->csv_output && !config->json_output) - print_footer(config); + print_footer(config); fflush(config->output); } -- GitLab From 2cf38236d94605586da0ed0f9ec432bf0eb415c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:24 -0800 Subject: [PATCH 0552/1480] perf stat: Factor out prefix display The prefix is needed for interval mode to print timestamp at the beginning of each line. But the it's tricky for the metric only mode since it doesn't print every evsel and combines the metrics into a single line. So it needed to pass 'first' argument to print_counter_aggrdata() to determine if the current event is being printed at first. This makes the code hard to read. Let's move the logic out of the function and do it in the outer print loop. This would enable further cleanups later. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-17-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 43 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 73cf898060c06..bb40ed29300d0 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -805,8 +805,7 @@ static void uniquify_counter(struct perf_stat_config *config, struct evsel *coun static void print_counter_aggrdata(struct perf_stat_config *config, struct evsel *counter, int s, - char *prefix, bool metric_only, - bool *first) + char *prefix, bool metric_only) { FILE *output = config->output; u64 ena, run, val; @@ -825,10 +824,6 @@ static void print_counter_aggrdata(struct perf_stat_config *config, ena = aggr->counts.ena; run = aggr->counts.run; - if (*first && metric_only) { - *first = false; - aggr_printout(config, counter, id, aggr->nr); - } if (prefix && !metric_only) fprintf(output, "%s", prefix); @@ -849,7 +844,6 @@ static void print_aggr(struct perf_stat_config *config, FILE *output = config->output; struct evsel *counter; int s; - bool first; if (!config->aggr_map || !config->aggr_get_id) return; @@ -860,21 +854,23 @@ static void print_aggr(struct perf_stat_config *config, */ for (s = 0; s < config->aggr_map->nr; s++) { if (metric_only) { + struct perf_stat_aggr *aggr; + struct aggr_cpu_id id = config->aggr_map->map[s]; + if (prefix) fprintf(output, "%s", prefix); - else if (config->summary && !config->no_csv_summary && - config->csv_output && !config->interval) - fprintf(output, "%16s%s", "summary", config->csv_sep); + + counter = evlist__first(evlist); + aggr = &counter->stats->aggr[s]; + aggr_printout(config, counter, id, aggr->nr); } - first = true; evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) continue; - print_counter_aggrdata(config, counter, s, - prefix, metric_only, - &first); + print_counter_aggrdata(config, counter, s, prefix, + metric_only); } if (metric_only) fputc('\n', output); @@ -885,7 +881,6 @@ static void print_counter(struct perf_stat_config *config, struct evsel *counter, char *prefix) { bool metric_only = config->metric_only; - bool first = false; int s; /* AGGR_THREAD doesn't have config->aggr_get_id */ @@ -896,9 +891,8 @@ static void print_counter(struct perf_stat_config *config, return; for (s = 0; s < config->aggr_map->nr; s++) { - print_counter_aggrdata(config, counter, s, - prefix, metric_only, - &first); + print_counter_aggrdata(config, counter, s, prefix, + metric_only); } } @@ -1260,7 +1254,6 @@ static void print_percore(struct perf_stat_config *config, FILE *output = config->output; struct cpu_aggr_map *core_map; int s, c, i; - bool first = true; if (!config->aggr_map || !config->aggr_get_id) return; @@ -1288,11 +1281,7 @@ static void print_percore(struct perf_stat_config *config, if (found) continue; - if (prefix && metric_only) - fprintf(output, "%s", prefix); - - print_counter_aggrdata(config, counter, s, - prefix, metric_only, &first); + print_counter_aggrdata(config, counter, s, prefix, metric_only); core_map->map[c++] = core_id; } @@ -1319,10 +1308,6 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf } print_header(config, _target, evlist, argc, argv); - if (metric_only) { - if (config->aggr_mode == AGGR_GLOBAL && prefix && !config->iostat_run) - fprintf(config->output, "%s", prefix); - } switch (config->aggr_mode) { case AGGR_CORE: @@ -1337,6 +1322,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf iostat_print_counters(evlist, config, ts, prefix = buf, print_counter); else { + if (prefix && metric_only) + fprintf(config->output, "%s", prefix); evlist__for_each_entry(evlist, counter) { print_counter(config, counter, prefix); } -- GitLab From 78670daefd33c8e0a30b121a2a271a90bca57130 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:25 -0800 Subject: [PATCH 0553/1480] perf stat: Factor out print_metric_{begin,end}() For the metric-only case, add new functions to handle the start and the end of each metric display. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-18-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 56 +++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bb40ed29300d0..7a0673be720b8 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -836,12 +836,39 @@ static void print_counter_aggrdata(struct perf_stat_config *config, fputc('\n', output); } +static void print_metric_begin(struct perf_stat_config *config, + struct evlist *evlist, + char *prefix, int aggr_idx) +{ + struct perf_stat_aggr *aggr; + struct aggr_cpu_id id; + struct evsel *evsel; + + if (!config->metric_only) + return; + + if (prefix) + fprintf(config->output, "%s", prefix); + + evsel = evlist__first(evlist); + id = config->aggr_map->map[aggr_idx]; + aggr = &evsel->stats->aggr[aggr_idx]; + aggr_printout(config, evsel, id, aggr->nr); +} + +static void print_metric_end(struct perf_stat_config *config) +{ + if (!config->metric_only) + return; + + fputc('\n', config->output); +} + static void print_aggr(struct perf_stat_config *config, struct evlist *evlist, char *prefix) { bool metric_only = config->metric_only; - FILE *output = config->output; struct evsel *counter; int s; @@ -853,17 +880,7 @@ static void print_aggr(struct perf_stat_config *config, * Without each counter has its own line. */ for (s = 0; s < config->aggr_map->nr; s++) { - if (metric_only) { - struct perf_stat_aggr *aggr; - struct aggr_cpu_id id = config->aggr_map->map[s]; - - if (prefix) - fprintf(output, "%s", prefix); - - counter = evlist__first(evlist); - aggr = &counter->stats->aggr[s]; - aggr_printout(config, counter, id, aggr->nr); - } + print_metric_begin(config, evlist, prefix, s); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) @@ -872,8 +889,7 @@ static void print_aggr(struct perf_stat_config *config, print_counter_aggrdata(config, counter, s, prefix, metric_only); } - if (metric_only) - fputc('\n', output); + print_metric_end(config); } } @@ -919,9 +935,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); if (first) { - if (prefix) - fputs(prefix, config->output); - aggr_printout(config, counter, id, 0); + print_metric_begin(config, evlist, prefix, counter_idx); first = false; } val = ps->aggr[counter_idx].counts.val; @@ -933,7 +947,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, run, ena, 1.0, &rt_stat, counter_idx); } if (!first) - fputc('\n', config->output); + print_metric_end(config); } } @@ -1322,13 +1336,11 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf iostat_print_counters(evlist, config, ts, prefix = buf, print_counter); else { - if (prefix && metric_only) - fprintf(config->output, "%s", prefix); + print_metric_begin(config, evlist, prefix, /*aggr_idx=*/0); evlist__for_each_entry(evlist, counter) { print_counter(config, counter, prefix); } - if (metric_only) - fputc('\n', config->output); + print_metric_end(config); } break; case AGGR_NONE: -- GitLab From 67f8b7eb4e9195d037b60f1614880234aca15fee Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:26 -0800 Subject: [PATCH 0554/1480] perf stat: Support --for-each-cgroup and --metric-only When we have events for each cgroup, the metric should be printed for each cgroup separately. Add print_cgroup_counter() to handle that situation properly. Also change print_metric_headers() not to print duplicate headers by checking cgroups. $ perf stat -a --for-each-cgroup system.slice,user.slice --metric-only sleep 1 Performance counter stats for 'system wide': GHz insn per cycle branch-misses of all branches system.slice 3.792 0.61 3.24% user.slice 3.661 2.32 0.37% 1.016111516 seconds time elapsed Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-19-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 58 +++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 7a0673be720b8..cf25ed99b5df9 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -168,10 +168,10 @@ static void print_cgroup_json(struct perf_stat_config *config, const char *cgrp_ fprintf(config->output, "\"cgroup\" : \"%s\", ", cgrp_name); } -static void print_cgroup(struct perf_stat_config *config, struct evsel *evsel) +static void print_cgroup(struct perf_stat_config *config, struct cgroup *cgrp) { - if (nr_cgroups) { - const char *cgrp_name = evsel->cgrp ? evsel->cgrp->name : ""; + if (nr_cgroups || config->cgroup_list) { + const char *cgrp_name = cgrp ? cgrp->name : ""; if (config->json_output) print_cgroup_json(config, cgrp_name); @@ -340,6 +340,7 @@ struct outstate { int nr; struct aggr_cpu_id id; struct evsel *evsel; + struct cgroup *cgrp; }; static void new_line_std(struct perf_stat_config *config __maybe_unused, @@ -552,6 +553,9 @@ static void print_metric_header(struct perf_stat_config *config, os->evsel->priv != os->evsel->evlist->selected->priv) return; + if (os->evsel->cgrp != os->cgrp) + return; + if (!valid_only_metric(unit)) return; unit = fixunit(tbuf, os->evsel, unit); @@ -642,7 +646,7 @@ static void abs_printout(struct perf_stat_config *config, { aggr_printout(config, evsel, id, nr); print_counter_value(config, evsel, avg, ok); - print_cgroup(config, evsel); + print_cgroup(config, evsel->cgrp); } static bool is_mixed_hw_group(struct evsel *counter) @@ -838,7 +842,8 @@ static void print_counter_aggrdata(struct perf_stat_config *config, static void print_metric_begin(struct perf_stat_config *config, struct evlist *evlist, - char *prefix, int aggr_idx) + char *prefix, int aggr_idx, + struct cgroup *cgrp) { struct perf_stat_aggr *aggr; struct aggr_cpu_id id; @@ -854,6 +859,8 @@ static void print_metric_begin(struct perf_stat_config *config, id = config->aggr_map->map[aggr_idx]; aggr = &evsel->stats->aggr[aggr_idx]; aggr_printout(config, evsel, id, aggr->nr); + + print_cgroup(config, cgrp); } static void print_metric_end(struct perf_stat_config *config) @@ -880,7 +887,7 @@ static void print_aggr(struct perf_stat_config *config, * Without each counter has its own line. */ for (s = 0; s < config->aggr_map->nr; s++) { - print_metric_begin(config, evlist, prefix, s); + print_metric_begin(config, evlist, prefix, s, /*cgrp=*/NULL); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) @@ -935,7 +942,8 @@ static void print_no_aggr_metric(struct perf_stat_config *config, id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); if (first) { - print_metric_begin(config, evlist, prefix, counter_idx); + print_metric_begin(config, evlist, prefix, + counter_idx, /*cgrp=*/NULL); first = false; } val = ps->aggr[counter_idx].counts.val; @@ -960,7 +968,7 @@ static void print_metric_headers_std(struct perf_stat_config *config, if (!no_indent) { int len = aggr_header_lens[config->aggr_mode]; - if (nr_cgroups) + if (nr_cgroups || config->cgroup_list) len += CGROUP_LEN + 1; fprintf(config->output, "%*s", len, ""); @@ -1012,6 +1020,9 @@ static void print_metric_headers(struct perf_stat_config *config, if (config->iostat_run) iostat_print_header_prefix(config); + if (config->cgroup_list) + os.cgrp = evlist__first(evlist)->cgrp; + /* Print metrics headers only */ evlist__for_each_entry(evlist, counter) { os.evsel = counter; @@ -1305,6 +1316,28 @@ static void print_percore(struct perf_stat_config *config, fputc('\n', output); } +static void print_cgroup_counter(struct perf_stat_config *config, struct evlist *evlist, + char *prefix) +{ + struct cgroup *cgrp = NULL; + struct evsel *counter; + + evlist__for_each_entry(evlist, counter) { + if (cgrp != counter->cgrp) { + if (cgrp != NULL) + print_metric_end(config); + + cgrp = counter->cgrp; + print_metric_begin(config, evlist, prefix, + /*aggr_idx=*/0, cgrp); + } + + print_counter(config, counter, prefix); + } + if (cgrp) + print_metric_end(config); +} + void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, struct target *_target, struct timespec *ts, int argc, const char **argv) { @@ -1332,11 +1365,14 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf break; case AGGR_THREAD: case AGGR_GLOBAL: - if (config->iostat_run) + if (config->iostat_run) { iostat_print_counters(evlist, config, ts, prefix = buf, print_counter); - else { - print_metric_begin(config, evlist, prefix, /*aggr_idx=*/0); + } else if (config->cgroup_list) { + print_cgroup_counter(config, evlist, prefix); + } else { + print_metric_begin(config, evlist, prefix, + /*aggr_idx=*/0, /*cgrp=*/NULL); evlist__for_each_entry(evlist, counter) { print_counter(config, counter, prefix); } -- GitLab From 4dd7ff4a0311eee3ac946f0824442de94b34c42e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 14 Nov 2022 15:02:27 -0800 Subject: [PATCH 0555/1480] perf stat: Add print_aggr_cgroup() for --for-each-cgroup and --topdown Normally, --for-each-cgroup only works with AGGR_GLOBAL. However the --topdown on some cpu (e.g. Intel Skylake) converts it to the AGGR_CORE internally. To support those machines, add print_aggr_cgroup and handle the events like in print_cgroup_events(). $ perf stat -a --for-each-cgroup system.slice,user.slice --topdown sleep 1 nmi_watchdog enabled with topdown. May give wrong results. Disable with echo 0 > /proc/sys/kernel/nmi_watchdog Performance counter stats for 'system wide': retiring bad speculation frontend bound backend bound S0-D0-C0 2 system.slice 49.0% -46.6% 31.4% S0-D0-C1 2 system.slice 55.5% 8.0% 45.5% -9.0% S0-D0-C2 2 system.slice 87.8% 22.1% 30.3% -40.3% S0-D0-C3 2 system.slice 53.3% -11.9% 45.2% 13.4% S0-D0-C0 2 user.slice 123.5% 4.0% 48.5% -75.9% S0-D0-C1 2 user.slice 19.9% 6.5% 89.9% -16.3% S0-D0-C2 2 user.slice 29.9% 7.9% 71.3% -9.1 S0-D0-C3 2 user.slice 28.0% 7.2% 43.3% 21.5% 1.004136937 seconds time elapsed Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221114230227.1255976-20-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 41 +++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index cf25ed99b5df9..f5501760ff2e1 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -900,6 +900,42 @@ static void print_aggr(struct perf_stat_config *config, } } +static void print_aggr_cgroup(struct perf_stat_config *config, + struct evlist *evlist, + char *prefix) +{ + bool metric_only = config->metric_only; + struct evsel *counter, *evsel; + struct cgroup *cgrp = NULL; + int s; + + if (!config->aggr_map || !config->aggr_get_id) + return; + + evlist__for_each_entry(evlist, evsel) { + if (cgrp == evsel->cgrp) + continue; + + cgrp = evsel->cgrp; + + for (s = 0; s < config->aggr_map->nr; s++) { + print_metric_begin(config, evlist, prefix, s, cgrp); + + evlist__for_each_entry(evlist, counter) { + if (counter->merged_stat) + continue; + + if (counter->cgrp != cgrp) + continue; + + print_counter_aggrdata(config, counter, s, prefix, + metric_only); + } + print_metric_end(config); + } + } +} + static void print_counter(struct perf_stat_config *config, struct evsel *counter, char *prefix) { @@ -1361,7 +1397,10 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf case AGGR_DIE: case AGGR_SOCKET: case AGGR_NODE: - print_aggr(config, evlist, prefix); + if (config->cgroup_list) + print_aggr_cgroup(config, evlist, prefix); + else + print_aggr(config, evlist, prefix); break; case AGGR_THREAD: case AGGR_GLOBAL: -- GitLab From a6efaa2c89bf35c3cb7f21dee221dabf20dccf59 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:01 -0800 Subject: [PATCH 0556/1480] tools lib api: Add install target This allows libapi to be installed as a dependency. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cmc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Cc: nicolas schier Link: http://lore.kernel.org/lkml/20221109184914.1357295-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index e21e1b40b5257..6629d0fd01306 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -15,6 +15,16 @@ LD ?= $(CROSS_COMPILE)ld MAKEFLAGS += --no-print-directory +INSTALL = install + + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + LIBFILE = $(OUTPUT)libapi.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) @@ -45,10 +55,23 @@ RM = rm -f API_IN := $(OUTPUT)libapi-in.o +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif + +prefix ?= +libdir = $(prefix)/$(libdir_relative) + +# Shell quotes +libdir_SQ = $(subst ','\'',$(libdir)) + all: export srctree OUTPUT CC LD CFLAGS V include $(srctree)/tools/build/Makefile.include +include $(srctree)/tools/scripts/Makefile.include all: fixdep $(LIBFILE) @@ -58,6 +81,32 @@ $(API_IN): FORCE $(LIBFILE): $(API_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(API_IN) +define do_install_mkdir + if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ + fi +endef + +define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' +endef + +install_lib: $(LIBFILE) + $(call QUIET_INSTALL, $(LIBFILE)) \ + $(call do_install_mkdir,$(libdir_SQ)); \ + cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) + +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,cpu.h,$(prefix)/include/api,644); \ + $(call do_install,debug.h,$(prefix)/include/api,644); \ + $(call do_install,io.h,$(prefix)/include/api,644); + +install: install_lib install_headers + clean: $(call QUIET_CLEAN, libapi) $(RM) $(LIBFILE); \ find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) -- GitLab From 630ae80ea1dd253609cb50cff87f3248f901aca3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:02 -0800 Subject: [PATCH 0557/1480] tools lib subcmd: Add install target This allows libsubcmd to be installed as a dependency. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/Makefile | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 8f1a09cdfd17e..e96566f8991cc 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -17,6 +17,15 @@ RM = rm -f MAKEFLAGS += --no-print-directory +INSTALL = install + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + LIBFILE = $(OUTPUT)libsubcmd.a CFLAGS := -ggdb3 -Wall -Wextra -std=gnu99 -fPIC @@ -48,6 +57,18 @@ CFLAGS += $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) SUBCMD_IN := $(OUTPUT)libsubcmd-in.o +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif + +prefix ?= +libdir = $(prefix)/$(libdir_relative) + +# Shell quotes +libdir_SQ = $(subst ','\'',$(libdir)) + all: export srctree OUTPUT CC LD CFLAGS V @@ -61,6 +82,34 @@ $(SUBCMD_IN): FORCE $(LIBFILE): $(SUBCMD_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SUBCMD_IN) +define do_install_mkdir + if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ + fi +endef + +define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' +endef + +install_lib: $(LIBFILE) + $(call QUIET_INSTALL, $(LIBFILE)) \ + $(call do_install_mkdir,$(libdir_SQ)); \ + cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) + +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,exec-cmd.h,$(prefix)/include/subcmd,644); \ + $(call do_install,help.h,$(prefix)/include/subcmd,644); \ + $(call do_install,pager.h,$(prefix)/include/subcmd,644); \ + $(call do_install,parse-options.h,$(prefix)/include/subcmd,644); \ + $(call do_install,run-command.h,$(prefix)/include/subcmd,644); + +install: install_lib install_headers + clean: $(call QUIET_CLEAN, libsubcmd) $(RM) $(LIBFILE); \ find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) -- GitLab From 911920b06e6be3faf87450affb0dbbc6117fd0a5 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:03 -0800 Subject: [PATCH 0558/1480] perf build: Install libsubcmd locally when building The perf build currently has a '-Itools/lib' on the CC command line. This causes issues as the libapi, libsubcmd, libtraceevent, libbpf headers are all found via this path, making it impossible to override include behavior. Change the libsubcmd build mirroring the libbpf build, so that it is installed in a directory along with its headers. A later change will modify the include behavior. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 1 + tools/perf/Makefile.perf | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index fd7a6ff9e7aae..413ca7e4a02a8 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -40,6 +40,7 @@ pmu-events/pmu-events.c pmu-events/jevents feature/ libbpf/ +libsubcmd/ fixdep libtraceevent-dynamic-list Documentation/doc.dep diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 67819f9056116..4ec6b95a1c49a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -244,7 +244,7 @@ else # force_fixdep LIB_DIR = $(srctree)/tools/lib/api/ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ LIBBPF_DIR = $(srctree)/tools/lib/bpf/ -SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ +LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ LIBPERF_DIR = $(srctree)/tools/lib/perf/ DOC_DIR = $(srctree)/tools/perf/Documentation/ @@ -294,7 +294,6 @@ strip-libs = $(filter-out -l%,$(1)) ifneq ($(OUTPUT),) TE_PATH=$(OUTPUT) PLUGINS_PATH=$(OUTPUT) - SUBCMD_PATH=$(OUTPUT) LIBPERF_PATH=$(OUTPUT) ifneq ($(subdir),) API_PATH=$(OUTPUT)/../lib/api/ @@ -305,7 +304,6 @@ else TE_PATH=$(TRACE_EVENT_DIR) PLUGINS_PATH=$(TRACE_EVENT_DIR)plugins/ API_PATH=$(LIB_DIR) - SUBCMD_PATH=$(SUBCMD_DIR) LIBPERF_PATH=$(LIBPERF_DIR) endif @@ -332,7 +330,14 @@ LIBBPF_DESTDIR = $(LIBBPF_OUTPUT) LIBBPF_INCLUDE = $(LIBBPF_DESTDIR)/include LIBBPF = $(LIBBPF_OUTPUT)/libbpf.a -LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a +ifneq ($(OUTPUT),) + LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd +else + LIBSUBCMD_OUTPUT = $(CURDIR)/libsubcmd +endif +LIBSUBCMD_DESTDIR = $(LIBSUBCMD_OUTPUT) +LIBSUBCMD_INCLUDE = $(LIBSUBCMD_DESTDIR)/include +LIBSUBCMD = $(LIBSUBCMD_OUTPUT)/libsubcmd.a LIBPERF = $(LIBPERF_PATH)libperf.a export LIBPERF @@ -849,11 +854,14 @@ $(LIBPERF)-clean: $(call QUIET_CLEAN, libperf) $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) clean >/dev/null -$(LIBSUBCMD): FORCE - $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a +$(LIBSUBCMD): FORCE | $(LIBSUBCMD_OUTPUT) + $(Q)$(MAKE) -C $(LIBSUBCMD_DIR) O=$(LIBSUBCMD_OUTPUT) \ + DESTDIR=$(LIBSUBCMD_DESTDIR) prefix= \ + $@ install_headers $(LIBSUBCMD)-clean: - $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) clean + $(call QUIET_CLEAN, libsubcmd) + $(Q)$(RM) -r -- $(LIBSUBCMD_OUTPUT) help: @echo 'Perf make targets:' @@ -1039,7 +1047,7 @@ SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h -$(SKEL_TMP_OUT) $(LIBBPF_OUTPUT): +$(SKEL_TMP_OUT) $(LIBBPF_OUTPUT) $(LIBSUBCMD_OUTPUT): $(Q)$(MKDIR) -p $@ ifdef BUILD_BPF_SKEL -- GitLab From 00314c9bca8faad495e4e4f702491ecd37444784 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:04 -0800 Subject: [PATCH 0559/1480] perf build: Install libapi locally when building The perf build currently has a '-Itools/lib' on the CC command line. This causes issues as the libapi, libsubcmd, libtraceevent, libbpf headers are all found via this path, making it impossible to override include behavior. Change the libapi build mirroring the libbpf and libsubcmd build, so that it is installed in a directory along with its headers. A later change will modify the include behavior. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 1 + tools/perf/Makefile.perf | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 413ca7e4a02a8..4a8a76da861d4 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -39,6 +39,7 @@ trace/beauty/generated/ pmu-events/pmu-events.c pmu-events/jevents feature/ +libapi/ libbpf/ libsubcmd/ fixdep diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4ec6b95a1c49a..f8c712e26a693 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -241,7 +241,7 @@ sub-make: fixdep else # force_fixdep -LIB_DIR = $(srctree)/tools/lib/api/ +LIBAPI_DIR = $(srctree)/tools/lib/api/ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ LIBBPF_DIR = $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ @@ -295,15 +295,9 @@ ifneq ($(OUTPUT),) TE_PATH=$(OUTPUT) PLUGINS_PATH=$(OUTPUT) LIBPERF_PATH=$(OUTPUT) -ifneq ($(subdir),) - API_PATH=$(OUTPUT)/../lib/api/ -else - API_PATH=$(OUTPUT) -endif else TE_PATH=$(TRACE_EVENT_DIR) PLUGINS_PATH=$(TRACE_EVENT_DIR)plugins/ - API_PATH=$(LIB_DIR) LIBPERF_PATH=$(LIBPERF_DIR) endif @@ -318,7 +312,14 @@ LIBTRACEEVENT_DYNAMIC_LIST = $(PLUGINS_PATH)libtraceevent-dynamic-list DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = $(if $(findstring -static,$(LDFLAGS)),,$(DYNAMIC_LIST_LDFLAGS)) -LIBAPI = $(API_PATH)libapi.a +ifneq ($(OUTPUT),) + LIBAPI_OUTPUT = $(abspath $(OUTPUT))/libapi +else + LIBAPI_OUTPUT = $(CURDIR)/libapi +endif +LIBAPI_DESTDIR = $(LIBAPI_OUTPUT) +LIBAPI_INCLUDE = $(LIBAPI_DESTDIR)/include +LIBAPI = $(LIBAPI_OUTPUT)/libapi.a export LIBAPI ifneq ($(OUTPUT),) @@ -831,12 +832,14 @@ $(LIBTRACEEVENT)-clean: install-traceevent-plugins: libtraceevent_plugins $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins -$(LIBAPI): FORCE - $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a +$(LIBAPI): FORCE | $(LIBAPI_OUTPUT) + $(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \ + DESTDIR=$(LIBAPI_DESTDIR) prefix= \ + $@ install_headers $(LIBAPI)-clean: $(call QUIET_CLEAN, libapi) - $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null + $(Q)$(RM) -r -- $(LIBAPI_OUTPUT) $(LIBBPF): FORCE | $(LIBBPF_OUTPUT) $(Q)$(MAKE) -C $(LIBBPF_DIR) FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) \ @@ -1047,7 +1050,7 @@ SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h -$(SKEL_TMP_OUT) $(LIBBPF_OUTPUT) $(LIBSUBCMD_OUTPUT): +$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBSUBCMD_OUTPUT): $(Q)$(MKDIR) -p $@ ifdef BUILD_BPF_SKEL -- GitLab From 91009a3a9913f2755f8b9616a2124a51147c375c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:05 -0800 Subject: [PATCH 0560/1480] perf build: Install libperf locally when building The perf build currently has a '-Itools/lib' on the CC command line. This causes issues as the libapi, libsubcmd, libtraceevent, libbpf headers are all found via this path, making it impossible to override include behavior. Change the libperf build mirroring the libbpf, libsubcmd and libapi build, so that it is installed in a directory along with its headers. A later change will modify the include behavior. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 1 + tools/perf/Makefile.perf | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 4a8a76da861d4..b5f10d5603f1d 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -41,6 +41,7 @@ pmu-events/jevents feature/ libapi/ libbpf/ +libperf/ libsubcmd/ fixdep libtraceevent-dynamic-list diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index f8c712e26a693..57aec5a972704 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -294,11 +294,9 @@ strip-libs = $(filter-out -l%,$(1)) ifneq ($(OUTPUT),) TE_PATH=$(OUTPUT) PLUGINS_PATH=$(OUTPUT) - LIBPERF_PATH=$(OUTPUT) else TE_PATH=$(TRACE_EVENT_DIR) PLUGINS_PATH=$(TRACE_EVENT_DIR)plugins/ - LIBPERF_PATH=$(LIBPERF_DIR) endif LIBTRACEEVENT = $(TE_PATH)libtraceevent.a @@ -340,7 +338,14 @@ LIBSUBCMD_DESTDIR = $(LIBSUBCMD_OUTPUT) LIBSUBCMD_INCLUDE = $(LIBSUBCMD_DESTDIR)/include LIBSUBCMD = $(LIBSUBCMD_OUTPUT)/libsubcmd.a -LIBPERF = $(LIBPERF_PATH)libperf.a +ifneq ($(OUTPUT),) + LIBPERF_OUTPUT = $(abspath $(OUTPUT))/libperf +else + LIBPERF_OUTPUT = $(CURDIR)/libperf +endif +LIBPERF_DESTDIR = $(LIBPERF_OUTPUT) +LIBPERF_INCLUDE = $(LIBPERF_DESTDIR)/include +LIBPERF = $(LIBPERF_OUTPUT)/libperf.a export LIBPERF # python extension build directories @@ -850,12 +855,14 @@ $(LIBBPF)-clean: $(call QUIET_CLEAN, libbpf) $(Q)$(RM) -r -- $(LIBBPF_OUTPUT) -$(LIBPERF): FORCE - $(Q)$(MAKE) -C $(LIBPERF_DIR) EXTRA_CFLAGS="$(LIBPERF_CFLAGS)" O=$(OUTPUT) $(OUTPUT)libperf.a +$(LIBPERF): FORCE | $(LIBPERF_OUTPUT) + $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(LIBPERF_OUTPUT) \ + DESTDIR=$(LIBPERF_DESTDIR) prefix= \ + $@ install_headers $(LIBPERF)-clean: $(call QUIET_CLEAN, libperf) - $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) clean >/dev/null + $(Q)$(RM) -r -- $(LIBPERF_OUTPUT) $(LIBSUBCMD): FORCE | $(LIBSUBCMD_OUTPUT) $(Q)$(MAKE) -C $(LIBSUBCMD_DIR) O=$(LIBSUBCMD_OUTPUT) \ @@ -1050,7 +1057,7 @@ SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h -$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBSUBCMD_OUTPUT): +$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT): $(Q)$(MKDIR) -p $@ ifdef BUILD_BPF_SKEL -- GitLab From ef019df01e207971200ffcb06559f791980668a1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:06 -0800 Subject: [PATCH 0561/1480] perf build: Install libtraceevent locally when building The perf build currently has a '-Itools/lib' on the CC command line. This causes issues as the libapi, libsubcmd, libtraceevent, libbpf headers are all found via this path, making it impossible to override include behavior. Change the libtraceevent build mirroring the libbpf, libsubcmd, libapi and libperf build, so that it is installed in a directory along with its headers. A later change will modify the include behavior. Similarly, the plugins are now installed into libtraceevent_plugins except they have no header files. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 3 ++- tools/perf/Makefile.perf | 57 ++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index b5f10d5603f1d..bc165f4e48308 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -43,6 +43,7 @@ libapi/ libbpf/ libperf/ libsubcmd/ +libtraceevent/ +libtraceevent_plugins/ fixdep -libtraceevent-dynamic-list Documentation/doc.dep diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 57aec5a972704..6e5e3f7730b58 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -242,7 +242,8 @@ sub-make: fixdep else # force_fixdep LIBAPI_DIR = $(srctree)/tools/lib/api/ -TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ +LIBTRACEEVENT_DIR = $(srctree)/tools/lib/traceevent/ +LIBTRACEEVENT_PLUGINS_DIR = $(LIBTRACEEVENT_DIR)/plugins LIBBPF_DIR = $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ LIBPERF_DIR = $(srctree)/tools/lib/perf/ @@ -292,16 +293,17 @@ grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) ifneq ($(OUTPUT),) - TE_PATH=$(OUTPUT) - PLUGINS_PATH=$(OUTPUT) + LIBTRACEEVENT_OUTPUT = $(abspath $(OUTPUT))/libtraceevent else - TE_PATH=$(TRACE_EVENT_DIR) - PLUGINS_PATH=$(TRACE_EVENT_DIR)plugins/ + LIBTRACEEVENT_OUTPUT = $(CURDIR)/libtraceevent endif - -LIBTRACEEVENT = $(TE_PATH)libtraceevent.a +LIBTRACEEVENT_PLUGINS_OUTPUT = $(LIBTRACEEVENT_OUTPUT)_plugins +LIBTRACEEVENT_DESTDIR = $(LIBTRACEEVENT_OUTPUT) +LIBTRACEEVENT_PLUGINS_DESTDIR = $(LIBTRACEEVENT_PLUGINS_OUTPUT) +LIBTRACEEVENT_INCLUDE = $(LIBTRACEEVENT_DESTDIR)/include +LIBTRACEEVENT = $(LIBTRACEEVENT_OUTPUT)/libtraceevent.a export LIBTRACEEVENT -LIBTRACEEVENT_DYNAMIC_LIST = $(PLUGINS_PATH)libtraceevent-dynamic-list +LIBTRACEEVENT_DYNAMIC_LIST = $(LIBTRACEEVENT_PLUGINS_OUTPUT)/libtraceevent-dynamic-list # # The static build has no dynsym table, so this does not work for @@ -821,21 +823,33 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(filter-out -static,$(LDFLAGS))' -$(LIBTRACEEVENT): FORCE - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a - -libtraceevent_plugins: FORCE - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR)plugins $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins - -$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR)plugins $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent-dynamic-list +$(LIBTRACEEVENT): FORCE | $(LIBTRACEEVENT_OUTPUT) + $(Q)$(MAKE) -C $(LIBTRACEEVENT_DIR) O=$(LIBTRACEEVENT_OUTPUT) \ + DESTDIR=$(LIBTRACEEVENT_DESTDIR) prefix= \ + $@ install_headers $(LIBTRACEEVENT)-clean: $(call QUIET_CLEAN, libtraceevent) - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null + $(Q)$(RM) -r -- $(LIBTRACEEVENT_OUTPUT) + +libtraceevent_plugins: FORCE | $(LIBTRACEEVENT_PLUGINS_OUTPUT) + $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ + DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ + plugins + +libtraceevent_plugins-clean: + $(call QUIET_CLEAN, libtraceevent_plugins) + $(Q)$(RM) -r -- $(LIBTRACEEVENT_PLUGINS_OUTPUT) + +$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins + $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ + DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ + $(LIBTRACEEVENT_FLAGS) $@ install-traceevent-plugins: libtraceevent_plugins - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins + $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ + DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ + $(LIBTRACEEVENT_FLAGS) install $(LIBAPI): FORCE | $(LIBAPI_OUTPUT) $(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \ @@ -1060,6 +1074,11 @@ SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT): $(Q)$(MKDIR) -p $@ +ifndef LIBTRACEEVENT_DYNAMIC +$(LIBTRACEEVENT_OUTPUT) $(LIBTRACEEVENT_PLUGINS_OUTPUT): + $(Q)$(MKDIR) -p $@ +endif + ifdef BUILD_BPF_SKEL BPFTOOL := $(SKEL_TMP_OUT)/bootstrap/bpftool BPF_INCLUDE := -I$(SKEL_TMP_OUT)/.. -I$(LIBBPF_INCLUDE) @@ -1102,7 +1121,7 @@ endif # BUILD_BPF_SKEL bpf-skel-clean: $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean libtraceevent_plugins-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected -- GitLab From 8d1f68bd76a6517c132fd1dd223c85c5e1defa49 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:07 -0800 Subject: [PATCH 0562/1480] tools lib api: Add missing install headers Headers necessary for the perf build. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 6629d0fd01306..3e5ef1e0e8908 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -103,7 +103,10 @@ install_headers: $(call QUIET_INSTALL, headers) \ $(call do_install,cpu.h,$(prefix)/include/api,644); \ $(call do_install,debug.h,$(prefix)/include/api,644); \ - $(call do_install,io.h,$(prefix)/include/api,644); + $(call do_install,io.h,$(prefix)/include/api,644); \ + $(call do_install,fd/array.h,$(prefix)/include/api/fd,644); \ + $(call do_install,fs/fs.h,$(prefix)/include/api/fs,644); + $(call do_install,fs/tracing_path.h,$(prefix)/include/api/fs,644); install: install_lib install_headers -- GitLab From a6e8caf5db2e1db8e2ec51f87b9749bd28f6b969 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:08 -0800 Subject: [PATCH 0563/1480] tools lib perf: Add missing install headers Headers necessary for the perf build. Note, internal headers are also installed as these are necessary for the build. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index 21df023a2103e..1badc0a046768 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -189,13 +189,21 @@ install_lib: libs install_headers: $(call QUIET_INSTALL, headers) \ + $(call do_install,include/perf/bpf_perf.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/core.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/cpumap.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/event.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/mmap.h,$(prefix)/include/perf,644); + $(call do_install,include/perf/mmap.h,$(prefix)/include/perf,644); \ + $(call do_install,include/internal/cpumap.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/evlist.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/evsel.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/lib.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/mmap.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/threadmap.h,$(prefix)/include/internal,644); \ + $(call do_install,include/internal/xyarray.h,$(prefix)/include/internal,644); install_pkgconfig: $(LIBPERF_PC) $(call QUIET_INSTALL, $(LIBPERF_PC)) \ -- GitLab From 160be157eaba2a37233ff2d27093e5915b6b084e Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:09 -0800 Subject: [PATCH 0564/1480] tool lib symbol: Add Makefile/Build Add sufficient Makefile for libsymbol to be built as a dependency and header files installed. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-10-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/symbol/Build | 1 + tools/lib/symbol/Makefile | 115 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tools/lib/symbol/Build create mode 100644 tools/lib/symbol/Makefile diff --git a/tools/lib/symbol/Build b/tools/lib/symbol/Build new file mode 100644 index 0000000000000..9b9a9c78d3c98 --- /dev/null +++ b/tools/lib/symbol/Build @@ -0,0 +1 @@ +libsymbol-y += kallsyms.o diff --git a/tools/lib/symbol/Makefile b/tools/lib/symbol/Makefile new file mode 100644 index 0000000000000..4c1d6b53032d2 --- /dev/null +++ b/tools/lib/symbol/Makefile @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../../scripts/Makefile.include +include ../../scripts/utilities.mak # QUIET_CLEAN + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + +CC ?= $(CROSS_COMPILE)gcc +AR ?= $(CROSS_COMPILE)ar +LD ?= $(CROSS_COMPILE)ld + +MAKEFLAGS += --no-print-directory + +INSTALL = install + + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + +LIBFILE = $(OUTPUT)libsymbol.a + +CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu11 -U_FORTIFY_SOURCE -fPIC + +ifeq ($(DEBUG),0) +ifeq ($(CC_NO_CLANG), 0) + CFLAGS += -O3 +else + CFLAGS += -O6 +endif +endif + +ifeq ($(DEBUG),0) + CFLAGS += -D_FORTIFY_SOURCE +endif + +# Treat warnings as errors unless directed not to +ifneq ($(WERROR),0) + CFLAGS += -Werror +endif + +CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 + +CFLAGS += -I$(srctree)/tools/lib +CFLAGS += -I$(srctree)/tools/include + +RM = rm -f + +SYMBOL_IN := $(OUTPUT)libsymbol-in.o + +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif + +prefix ?= +libdir = $(prefix)/$(libdir_relative) + +# Shell quotes +libdir_SQ = $(subst ','\'',$(libdir)) + +all: + +export srctree OUTPUT CC LD CFLAGS V +include $(srctree)/tools/build/Makefile.include +include $(srctree)/tools/scripts/Makefile.include + +all: fixdep $(LIBFILE) + +$(SYMBOL_IN): FORCE + $(MAKE) $(build)=libsymbol V=1 + +$(LIBFILE): $(SYMBOL_IN) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SYMBOL_IN) + +define do_install_mkdir + if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ + fi +endef + +define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' +endef + +install_lib: $(LIBFILE) + $(call QUIET_INSTALL, $(LIBFILE)) \ + $(call do_install_mkdir,$(libdir_SQ)); \ + cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) + +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,kallsyms.h,$(prefix)/include/symbol,644); + +install: install_lib install_headers + +clean: + $(call QUIET_CLEAN, libsymbol) $(RM) $(LIBFILE); \ + find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) + +FORCE: + +.PHONY: clean FORCE -- GitLab From 84bec6f0b31fb2ac8c5e4b0ded7727e6ec1115db Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:10 -0800 Subject: [PATCH 0565/1480] perf build: Install libsymbol locally when building The perf build currently has a '-Itools/lib' on the CC command line. This causes issues as the libapi, libsubcmd, libtraceevent, libbpf and libsymbol headers are all found via this path, making it impossible to override include behavior. Change the libsymbol build mirroring the libbpf, libsubcmd, libapi, libperf and libtraceevent build, so that it is installed in a directory along with its headers. A later change will modify the include behavior. Don't build kallsyms.o as part of util as this will lead to duplicate definitions. Add kallsym's directory to the MANIFEST rather than individual files, so that the Build and Makefile are added to a source tar ball. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-11-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 1 + tools/perf/MANIFEST | 3 +-- tools/perf/Makefile.perf | 25 ++++++++++++++++++++++--- tools/perf/util/Build | 5 ----- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index bc165f4e48308..05806ecfc33c1 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -43,6 +43,7 @@ libapi/ libbpf/ libperf/ libsubcmd/ +libsymbol/ libtraceevent/ libtraceevent_plugins/ fixdep diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index f5d72f936a6ba..c8e8e05b4ff1f 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -13,8 +13,7 @@ tools/lib/ctype.c tools/lib/hweight.c tools/lib/rbtree.c tools/lib/string.c -tools/lib/symbol/kallsyms.c -tools/lib/symbol/kallsyms.h +tools/lib/symbol tools/lib/find_bit.c tools/lib/bitmap.c tools/lib/list_sort.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6e5e3f7730b58..6c1a2a3ccc381 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -246,6 +246,7 @@ LIBTRACEEVENT_DIR = $(srctree)/tools/lib/traceevent/ LIBTRACEEVENT_PLUGINS_DIR = $(LIBTRACEEVENT_DIR)/plugins LIBBPF_DIR = $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ +LIBSYMBOL_DIR = $(srctree)/tools/lib/symbol/ LIBPERF_DIR = $(srctree)/tools/lib/perf/ DOC_DIR = $(srctree)/tools/perf/Documentation/ @@ -340,6 +341,15 @@ LIBSUBCMD_DESTDIR = $(LIBSUBCMD_OUTPUT) LIBSUBCMD_INCLUDE = $(LIBSUBCMD_DESTDIR)/include LIBSUBCMD = $(LIBSUBCMD_OUTPUT)/libsubcmd.a +ifneq ($(OUTPUT),) + LIBSYMBOL_OUTPUT = $(abspath $(OUTPUT))/libsymbol +else + LIBSYMBOL_OUTPUT = $(CURDIR)/libsymbol +endif +LIBSYMBOL_DESTDIR = $(LIBSYMBOL_OUTPUT) +LIBSYMBOL_INCLUDE = $(LIBSYMBOL_DESTDIR)/include +LIBSYMBOL = $(LIBSYMBOL_OUTPUT)/libsymbol.a + ifneq ($(OUTPUT),) LIBPERF_OUTPUT = $(abspath $(OUTPUT))/libperf else @@ -398,7 +408,7 @@ endif export PERL_PATH -PERFLIBS = $(LIBAPI) $(LIBSUBCMD) $(LIBPERF) +PERFLIBS = $(LIBAPI) $(LIBPERF) $(LIBSUBCMD) $(LIBSYMBOL) ifndef NO_LIBBPF ifndef LIBBPF_DYNAMIC PERFLIBS += $(LIBBPF) @@ -887,6 +897,15 @@ $(LIBSUBCMD)-clean: $(call QUIET_CLEAN, libsubcmd) $(Q)$(RM) -r -- $(LIBSUBCMD_OUTPUT) +$(LIBSYMBOL): FORCE | $(LIBSYMBOL_OUTPUT) + $(Q)$(MAKE) -C $(LIBSYMBOL_DIR) O=$(LIBSYMBOL_OUTPUT) \ + DESTDIR=$(LIBSYMBOL_DESTDIR) prefix= \ + $@ install_headers + +$(LIBSYMBOL)-clean: + $(call QUIET_CLEAN, libsymbol) + $(Q)$(RM) -r -- $(LIBSYMBOL_OUTPUT) + help: @echo 'Perf make targets:' @echo ' doc - make *all* documentation (see below)' @@ -1071,7 +1090,7 @@ SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h -$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT): +$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT): $(Q)$(MKDIR) -p $@ ifndef LIBTRACEEVENT_DYNAMIC @@ -1121,7 +1140,7 @@ endif # BUILD_BPF_SKEL bpf-skel-clean: $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean libtraceevent_plugins-clean +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean libtraceevent_plugins-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 47a7db3ad0a1f..ab37f588ee8b3 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -19,7 +19,6 @@ perf-y += perf_event_attr_fprintf.o perf-y += evswitch.o perf-y += find_bit.o perf-y += get_current_dir_name.o -perf-y += kallsyms.o perf-y += levenshtein.o perf-y += llvm-utils.o perf-y += mmap.o @@ -294,10 +293,6 @@ CFLAGS_expr.o += -Wno-redundant-decls CFLAGS_header.o += -include $(OUTPUT)PERF-VERSION-FILE CFLAGS_arm-spe.o += -I$(srctree)/tools/arch/arm64/include/ -$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE - $(call rule_mkdir) - $(call if_changed_dep,cc_o_c) - $(OUTPUT)util/argv_split.o: ../lib/argv_split.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) -- GitLab From bd560973c5d3b2a37fb13d769b34385ed320d547 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:11 -0800 Subject: [PATCH 0566/1480] perf expr: Tidy hashmap dependency hashmap.h comes from libbpf but isn't installed with its headers. Always use the header file of the code in util. Change the hashmap.h dependency in expr.h to a forward declaration, add the necessary header file includes in the C files. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-12-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 1 + tools/perf/tests/pmu-events.c | 1 + tools/perf/util/bpf-loader.c | 4 ---- tools/perf/util/evsel.c | 4 ---- tools/perf/util/expr.c | 1 + tools/perf/util/expr.h | 7 +------ tools/perf/util/metricgroup.c | 1 + tools/perf/util/stat-shadow.c | 1 + tools/perf/util/stat.c | 4 ---- 9 files changed, 6 insertions(+), 18 deletions(-) diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 6512f5e22045a..b6667501ebb45 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -2,6 +2,7 @@ #include "util/cputopo.h" #include "util/debug.h" #include "util/expr.h" +#include "util/hashmap.h" #include "util/header.h" #include "util/smt.h" #include "tests.h" diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 5d0d3b239a68b..f7b9dbbad97f5 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -12,6 +12,7 @@ #include #include "util/evlist.h" #include "util/expr.h" +#include "util/hashmap.h" #include "util/parse-events.h" #include "metricgroup.h" #include "stat.h" diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index f4adeccdbbcb4..b3c8174360bf3 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -27,11 +27,7 @@ #include "util.h" #include "llvm-utils.h" #include "c++/clang-c.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include -#else #include "util/hashmap.h" -#endif #include "asm/bug.h" #include diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ca6abb64c91d2..ca554f8202f94 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -46,11 +46,7 @@ #include "string2.h" #include "memswap.h" #include "util.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include -#else #include "util/hashmap.h" -#endif #include "pmu-hybrid.h" #include "off_cpu.h" #include "../perf-sys.h" diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index aaacf514dc09c..140f2acdb3259 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -11,6 +11,7 @@ #include "expr.h" #include "expr-bison.h" #include "expr-flex.h" +#include "util/hashmap.h" #include "smt.h" #include "tsc.h" #include diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index d6c1668dc1a08..029271540fb0d 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -2,12 +2,7 @@ #ifndef PARSE_CTX_H #define PARSE_CTX_H 1 -#ifdef HAVE_LIBBPF_SUPPORT -#include -#else -#include "util/hashmap.h" -#endif - +struct hashmap; struct metric_ref; struct expr_scanner_ctx { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 1943fed9b6d92..cf9e2452d3229 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -28,6 +28,7 @@ #include "util.h" #include #include "cgroup.h" +#include "util/hashmap.h" struct metric_event *metricgroup__lookup(struct rblist *metric_events, struct evsel *evsel, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 07b29fe272c79..9bde9224a97ce 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -14,6 +14,7 @@ #include "units.h" #include #include "iostat.h" +#include "util/hashmap.h" /* * AGGR_GLOBAL: Use CPU 0 diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index acf0edf5fdd1a..673f017a211f6 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -14,11 +14,7 @@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include -#else #include "util/hashmap.h" -#endif #include void update_stats(struct stats *stats, u64 val) -- GitLab From fd3f518fc1140622e752ac51d0ff18bb74f1d180 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:12 -0800 Subject: [PATCH 0567/1480] perf thread_map: Reduce exposure of libperf internal API Remove unnecessary include of internal threadmap.h and refcount.h in thread_map.h. Switch to using public APIs when possible or including the internal header file in the C file. Fix a transitive dependency in openat-syscall.c broken by the clean up. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-13-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 1 + tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/openat-syscall.c | 1 + tools/perf/tests/thread-map.c | 1 + tools/perf/util/bpf_counter.c | 2 +- tools/perf/util/evsel.c | 1 + tools/perf/util/python.c | 6 +++--- tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/thread_map.c | 1 + tools/perf/util/thread_map.h | 2 -- 10 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1d79801f4e844..d040fbcdcc5a7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -93,6 +93,7 @@ #include #include +#include #define DEFAULT_SEPARATOR " " #define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c93b359abc312..3257da5cad231 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4095,8 +4095,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) } trace->multiple_threads = perf_thread_map__pid(evlist->core.threads, 0) == -1 || - evlist->core.threads->nr > 1 || - evlist__first(evlist)->core.attr.inherit; + perf_thread_map__nr(evlist->core.threads) > 1 || + evlist__first(evlist)->core.attr.inherit; /* * Now that we already used evsel->core.attr to ask the kernel to setup the diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 7e05b8b5cc95f..131b62271bfa2 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "thread_map.h" #include "evsel.h" #include "debug.h" diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index e413c1387fcba..74308c1368fe1 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -11,6 +11,7 @@ #include "util/synthetic-events.h" #include #include +#include struct perf_sample; struct perf_tool; diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c index ef1c15e4aeba5..eeee899fcf34f 100644 --- a/tools/perf/util/bpf_counter.c +++ b/tools/perf/util/bpf_counter.c @@ -561,7 +561,7 @@ static int bperf__load(struct evsel *evsel, struct target *target) if (filter_type == BPERF_FILTER_PID || filter_type == BPERF_FILTER_TGID) - key = evsel->core.threads->map[i].pid; + key = perf_thread_map__pid(evsel->core.threads, i); else if (filter_type == BPERF_FILTER_CPU) key = evsel->core.cpus->map[i].cpu; else diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ca554f8202f94..45f4f08399ae1 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -53,6 +53,7 @@ #include "util/parse-branch-options.h" #include #include +#include #include diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 5be5fa2391de2..b5941c74a0d64 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -718,17 +718,17 @@ static Py_ssize_t pyrf_thread_map__length(PyObject *obj) { struct pyrf_thread_map *pthreads = (void *)obj; - return pthreads->threads->nr; + return perf_thread_map__nr(pthreads->threads); } static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) { struct pyrf_thread_map *pthreads = (void *)obj; - if (i >= pthreads->threads->nr) + if (i >= perf_thread_map__nr(pthreads->threads)) return NULL; - return Py_BuildValue("i", pthreads->threads->map[i]); + return Py_BuildValue("i", perf_thread_map__pid(pthreads->threads, i)); } static PySequenceMethods pyrf_thread_map__sequence_methods = { diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 1985d1a42a224..1cf65db8f861d 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1654,7 +1654,7 @@ static void python_process_stat(struct perf_stat_config *config, struct perf_cpu_map *cpus = counter->core.cpus; int cpu, thread; - for (thread = 0; thread < threads->nr; thread++) { + for (thread = 0; thread < perf_thread_map__nr(threads); thread++) { for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) { process_stat(counter, perf_cpu_map__cpu(cpus, cpu), perf_thread_map__pid(threads, thread), tstamp, diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index c9bfe4696943b..e848579e61a86 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -18,6 +18,7 @@ #include "thread_map.h" #include "debug.h" #include "event.h" +#include /* Skip "." and ".." directories */ static int filter(const struct dirent *dir) diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 3bb860a32b8e9..00ec05fc1656d 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -4,8 +4,6 @@ #include #include -#include -#include #include struct perf_record_thread_map; -- GitLab From c4d9d95f84d7f4758db76f358b03a0d6809c929b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 9 Nov 2022 10:49:13 -0800 Subject: [PATCH 0568/1480] perf cpumap: Tidy libperf includes Use public API when possible, don't include internal API in header files in evsel.h. Fix any related breakages. Committer note: There was one missing case, when building for arm64: arch/arm64/util/pmu.c: In function 'pmu_events_table__find': arch/arm64/util/pmu.c:18:30: error: invalid use of undefined type 'struct perf_cpu_map' 18 | if (pmu->cpus->nr != cpu__max_cpu().cpu) | ^~ Fix it by adding one more exception, including Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-14-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/pmu.c | 1 + tools/perf/tests/cpumap.c | 2 +- tools/perf/util/auxtrace.h | 2 +- tools/perf/util/cpumap.c | 1 + tools/perf/util/cpumap.h | 2 +- tools/perf/util/evsel.h | 2 -- 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c index f849b1e88d433..477e513972a40 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include "../../../util/cpumap.h" #include "../../../util/pmu.h" diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 7c873c6ae3eb9..3150fc1fed6f5 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -6,7 +6,7 @@ #include "util/synthetic-events.h" #include #include -#include +#include #include "debug.h" struct machine; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 6a0f9b98f059b..2cf63d3778313 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 6e3fcf523de93..5e564974fba4f 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -12,6 +12,7 @@ #include #include +#include static struct perf_cpu max_cpu_num; static struct perf_cpu max_present_cpu_num; diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index da28b3146ef9f..c2f5824a3a22b 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -4,8 +4,8 @@ #include #include -#include #include +#include /** Identify where counts are aggregated, -1 implies not to aggregate. */ struct aggr_cpu_id { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 467bb0b32fef8..f3485799ddf9e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -10,8 +10,6 @@ #include #include #include "symbol_conf.h" -#include -#include struct bpf_object; struct cgroup; -- GitLab From 746bd29e348f99b44c14cb2b2a57f1d3efb66538 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 15 Nov 2022 23:22:11 -0800 Subject: [PATCH 0569/1480] perf build: Use tools/lib headers from install path Switch -I from tools/lib to the install path for the tools/lib libraries. Add the include_headers build targets to prepare target, as well as pmu-events.c compilation that dependes on libperf. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221109184914.1357295-15-irogers@google.com Link: http://lore.kernel.org/lkml/20221116072211.2837834-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 2 -- tools/perf/Makefile.perf | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index a7f6c0669fae4..9cc3c48f32881 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -349,7 +349,6 @@ ifeq ($(DEBUG),0) endif endif -INC_FLAGS += -I$(srctree)/tools/lib/perf/include INC_FLAGS += -I$(src-perf)/util/include INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include INC_FLAGS += -I$(srctree)/tools/include/ @@ -367,7 +366,6 @@ endif INC_FLAGS += -I$(src-perf)/util INC_FLAGS += -I$(src-perf) -INC_FLAGS += -I$(srctree)/tools/lib/ CORE_CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6c1a2a3ccc381..8c0df762fb02f 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -305,6 +305,7 @@ LIBTRACEEVENT_INCLUDE = $(LIBTRACEEVENT_DESTDIR)/include LIBTRACEEVENT = $(LIBTRACEEVENT_OUTPUT)/libtraceevent.a export LIBTRACEEVENT LIBTRACEEVENT_DYNAMIC_LIST = $(LIBTRACEEVENT_PLUGINS_OUTPUT)/libtraceevent-dynamic-list +CFLAGS += -I$(LIBTRACEEVENT_OUTPUT)/include # # The static build has no dynsym table, so this does not work for @@ -322,6 +323,7 @@ LIBAPI_DESTDIR = $(LIBAPI_OUTPUT) LIBAPI_INCLUDE = $(LIBAPI_DESTDIR)/include LIBAPI = $(LIBAPI_OUTPUT)/libapi.a export LIBAPI +CFLAGS += -I$(LIBAPI_OUTPUT)/include ifneq ($(OUTPUT),) LIBBPF_OUTPUT = $(abspath $(OUTPUT))/libbpf @@ -331,6 +333,7 @@ endif LIBBPF_DESTDIR = $(LIBBPF_OUTPUT) LIBBPF_INCLUDE = $(LIBBPF_DESTDIR)/include LIBBPF = $(LIBBPF_OUTPUT)/libbpf.a +CFLAGS += -I$(LIBBPF_OUTPUT)/include ifneq ($(OUTPUT),) LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd @@ -340,6 +343,7 @@ endif LIBSUBCMD_DESTDIR = $(LIBSUBCMD_OUTPUT) LIBSUBCMD_INCLUDE = $(LIBSUBCMD_DESTDIR)/include LIBSUBCMD = $(LIBSUBCMD_OUTPUT)/libsubcmd.a +CFLAGS += -I$(LIBSUBCMD_OUTPUT)/include ifneq ($(OUTPUT),) LIBSYMBOL_OUTPUT = $(abspath $(OUTPUT))/libsymbol @@ -349,6 +353,7 @@ endif LIBSYMBOL_DESTDIR = $(LIBSYMBOL_OUTPUT) LIBSYMBOL_INCLUDE = $(LIBSYMBOL_DESTDIR)/include LIBSYMBOL = $(LIBSYMBOL_OUTPUT)/libsymbol.a +CFLAGS += -I$(LIBSYMBOL_OUTPUT)/include ifneq ($(OUTPUT),) LIBPERF_OUTPUT = $(abspath $(OUTPUT))/libperf @@ -359,6 +364,7 @@ LIBPERF_DESTDIR = $(LIBPERF_OUTPUT) LIBPERF_INCLUDE = $(LIBPERF_DESTDIR)/include LIBPERF = $(LIBPERF_OUTPUT)/libperf.a export LIBPERF +CFLAGS += -I$(LIBPERF_OUTPUT)/include # python extension build directories PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ @@ -691,14 +697,14 @@ build := -f $(srctree)/tools/build/Makefile.build dir=. obj $(PERF_IN): prepare FORCE $(Q)$(MAKE) $(build)=perf -$(PMU_EVENTS_IN): FORCE +$(PMU_EVENTS_IN): FORCE prepare $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ -$(GTK_IN): FORCE +$(GTK_IN): FORCE prepare $(Q)$(MAKE) $(build)=gtk $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) @@ -774,6 +780,12 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(rename_flags_array) \ $(arch_errno_name_array) \ $(sync_file_range_arrays) \ + $(LIBAPI) \ + $(LIBBPF) \ + $(LIBPERF) \ + $(LIBSUBCMD) \ + $(LIBSYMBOL) \ + $(LIBTRACEEVENT) \ bpf-skel $(OUTPUT)%.o: %.c prepare FORCE -- GitLab From 35fef9b471c70413f8277984920129ddf601f5e9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 16 Nov 2022 15:40:46 -0300 Subject: [PATCH 0570/1480] libperf: Remove recursive perf/cpumap.h include from perf/cpumap.h It just hits the header guard, becoming a no-op, ditch it. Acked-by: Ian Rogers Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/include/perf/cpumap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index 03aceb72a783c..98e463ec15a7f 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -3,7 +3,6 @@ #define __LIBPERF_CPUMAP_H #include -#include #include #include -- GitLab From 63a3bf5e8d9e79ce456c8f73d4395a5a51d841b1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 16 Nov 2022 15:43:34 -0300 Subject: [PATCH 0571/1480] libperf: Add missing 'struct perf_cpu_map' forward declaration to perf/cpumap.h The perf/cpumap.h header is getting the 'struct perf_cpu_map' forward declaration by luck, add it. Acked-by: Ian Rogers Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/include/perf/cpumap.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index 98e463ec15a7f..3f43f770cdac5 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -11,6 +11,8 @@ struct perf_cpu { int cpu; }; +struct perf_cpu_map; + LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); LIBPERF_API struct perf_cpu_map *perf_cpu_map__default_new(void); LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); -- GitLab From 86fdd15e10e404e70ecb2a3bff24d70356d42b36 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Nov 2022 10:37:12 +0800 Subject: [PATCH 0572/1480] iio: fix memory leak in iio_device_register_eventset() When iio_device_register_sysfs_group() returns failed, iio_device_register_eventset() needs to free attrs array. Otherwise, kmemleak would scan & report memory leak as below: unreferenced object 0xffff88810a1cc3c0 (size 32): comm "100-i2c-vcnl302", pid 728, jiffies 4295052307 (age 156.027s) backtrace: __kmalloc+0x46/0x1b0 iio_device_register_eventset at drivers/iio/industrialio-event.c:541 __iio_device_register at drivers/iio/industrialio-core.c:1959 __devm_iio_device_register at drivers/iio/industrialio-core.c:2040 Fixes: 32f171724e5c ("iio: core: rework iio device group creation") Signed-off-by: Zeng Heng Link: https://lore.kernel.org/r/20221115023712.3726854-1-zengheng4@huawei.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 3d78da2531a9a..727e2ef66aa4b 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -556,7 +556,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) ret = iio_device_register_sysfs_group(indio_dev, &ev_int->group); if (ret) - goto error_free_setup_event_lines; + goto error_free_group_attrs; ev_int->ioctl_handler.ioctl = iio_event_ioctl; iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev, @@ -564,6 +564,8 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) return 0; +error_free_group_attrs: + kfree(ev_int->group.attrs); error_free_setup_event_lines: iio_free_chan_devattr_list(&ev_int->dev_attr_list); kfree(ev_int); -- GitLab From 5562c6a9657e1bffd4d66df841db142c596f411c Mon Sep 17 00:00:00 2001 From: Slark Xiao Date: Mon, 7 Nov 2022 19:27:00 +0800 Subject: [PATCH 0573/1480] bus: mhi: host: pci_generic: Add definition for some VIDs To make code neat and for convenience purpose, add definition for some VIDs. Adding it locally until these VIDs are used in multiple places. Signed-off-by: Slark Xiao Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20221107112700.773-1-slark_xiao@163.com Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/pci_generic.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index b58a303678964..f39657f71483c 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -24,6 +24,10 @@ #define HEALTH_CHECK_PERIOD (HZ * 2) +/* PCI VID definitions */ +#define PCI_VENDOR_ID_THALES 0x1269 +#define PCI_VENDOR_ID_QUECTEL 0x1eac + /** * struct mhi_pci_dev_info - MHI PCI device specific information * @config: MHI controller configuration @@ -559,11 +563,11 @@ static const struct pci_device_id mhi_pci_id_table[] = { .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, - { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */ + { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */ + { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(0x1eac, 0x2001), /* EM120R-GL for FCCL (sdx24) */ + { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, /* T99W175 (sdx55), Both for eSIM and Non-eSIM */ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab), @@ -587,16 +591,16 @@ static const struct pci_device_id mhi_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9), .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info }, /* MV31-W (Cinterion) */ - { PCI_DEVICE(0x1269, 0x00b3), + { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3), .driver_data = (kernel_ulong_t) &mhi_mv31_info }, /* MV31-W (Cinterion), based on new baseline */ - { PCI_DEVICE(0x1269, 0x00b4), + { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b4), .driver_data = (kernel_ulong_t) &mhi_mv31_info }, /* MV32-WA (Cinterion) */ - { PCI_DEVICE(0x1269, 0x00ba), + { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00ba), .driver_data = (kernel_ulong_t) &mhi_mv32_info }, /* MV32-WB (Cinterion) */ - { PCI_DEVICE(0x1269, 0x00bb), + { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00bb), .driver_data = (kernel_ulong_t) &mhi_mv32_info }, /* T99W175 (sdx55), HP variant */ { PCI_DEVICE(0x03f0, 0x0a6c), -- GitLab From c70edc06773976f4e6ccfe250030a73c2896e131 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:10 -0800 Subject: [PATCH 0574/1480] dt-bindings: interconnect: Add sm8350, sc8280xp and generic OSM L3 compatibles Add EPSS L3 compatibles for sm8350 and sc8280xp, but while at it also introduce generic compatible for both qcom,osm-l3 and qcom,epss-l3. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Krzysztof Kozlowski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-6-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,osm-l3.yaml | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml index bf538c0c5a811..aadae4424ba95 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml @@ -16,13 +16,21 @@ description: properties: compatible: - enum: - - qcom,sc7180-osm-l3 - - qcom,sc7280-epss-l3 - - qcom,sc8180x-osm-l3 - - qcom,sdm845-osm-l3 - - qcom,sm8150-osm-l3 - - qcom,sm8250-epss-l3 + oneOf: + - items: + - enum: + - qcom,sc7180-osm-l3 + - qcom,sc8180x-osm-l3 + - qcom,sdm845-osm-l3 + - qcom,sm8150-osm-l3 + - const: qcom,osm-l3 + - items: + - enum: + - qcom,sc7280-epss-l3 + - qcom,sc8280xp-epss-l3 + - qcom,sm8250-epss-l3 + - qcom,sm8350-epss-l3 + - const: qcom,epss-l3 reg: maxItems: 1 @@ -56,7 +64,7 @@ examples: #define RPMH_CXO_CLK 0 osm_l3: interconnect@17d41000 { - compatible = "qcom,sdm845-osm-l3"; + compatible = "qcom,sdm845-osm-l3", "qcom,osm-l3"; reg = <0x17d41000 0x1400>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; -- GitLab From 2d710b00f22f3fcbc4e0189524bbf36731d9baf4 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 10 Nov 2022 19:25:14 -0800 Subject: [PATCH 0575/1480] dt-bindings: interconnect: qcom,msm8998-bwmon: Add sc8280xp bwmon instances The sc8280xp platform has two BWMON instances, one v4 and one v5. Extend the existing qcom,msm8998-bwmon and qcom,sc7280-llcc-bwmon to describe these. Signed-off-by: Bjorn Andersson Tested-by: Steev Klimaszewski Reviewed-by: Krzysztof Kozlowski Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20221111032515.3460-10-quic_bjorande@quicinc.com Signed-off-by: Georgi Djakov --- .../devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index be29e0b80995e..0c720dbde36e1 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -25,9 +25,14 @@ properties: - items: - enum: - qcom,sc7280-cpu-bwmon + - qcom,sc8280xp-cpu-bwmon - qcom,sdm845-bwmon - const: qcom,msm8998-bwmon - const: qcom,msm8998-bwmon # BWMON v4 + - items: + - enum: + - qcom,sc8280xp-llcc-bwmon + - const: qcom,sc7280-llcc-bwmon - const: qcom,sc7280-llcc-bwmon # BWMON v5 - const: qcom,sdm845-llcc-bwmon # BWMON v5 -- GitLab From c423f01633eb948ba6f8c98872b4119685e007fb Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Sat, 24 Sep 2022 09:50:43 +0800 Subject: [PATCH 0576/1480] interconnect: qcom: icc-rpm: Remove redundant dev_err call devm_ioremap_resource() prints error message in itself. Remove the dev_err call to avoid redundant error message. Signed-off-by: Shang XiaoJing Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220924015043.25130-1-shangxiaojing@huawei.com Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/icc-rpm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index 39e43b9575998..ba6781f54ab73 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -477,11 +477,8 @@ int qnoc_probe(struct platform_device *pdev) } mmio = devm_ioremap_resource(dev, res); - - if (IS_ERR(mmio)) { - dev_err(dev, "Cannot ioremap interconnect bus resource\n"); + if (IS_ERR(mmio)) return PTR_ERR(mmio); - } qp->regmap = devm_regmap_init_mmio(dev, mmio, desc->regmap_cfg); if (IS_ERR(qp->regmap)) { -- GitLab From f24227a640344f894522045f74bb2decbdc4f55e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Oct 2022 11:48:46 -0400 Subject: [PATCH 0577/1480] interconnect: qcom: sc7180: fix dropped const of qcom_icc_bcm Pointers to struct qcom_icc_bcm are const, but the change was dropped during merge. Fixes: 016fca59f95f ("Merge branch 'icc-const' into icc-next") Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221027154848.293523-1-krzysztof.kozlowski@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sc7180.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c index 35cd448efdfbe..82d5e8a8c19ea 100644 --- a/drivers/interconnect/qcom/sc7180.c +++ b/drivers/interconnect/qcom/sc7180.c @@ -369,7 +369,7 @@ static const struct qcom_icc_desc sc7180_gem_noc = { .num_bcms = ARRAY_SIZE(gem_noc_bcms), }; -static struct qcom_icc_bcm *mc_virt_bcms[] = { +static struct qcom_icc_bcm * const mc_virt_bcms[] = { &bcm_acv, &bcm_mc0, }; -- GitLab From 7870c7076aa07d9caaf53652d6b5a3cd74b1d157 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Oct 2022 11:48:47 -0400 Subject: [PATCH 0578/1480] interconnect: qcom: sc7180: drop double space Drop double white-space. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221027154848.293523-2-krzysztof.kozlowski@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sc7180.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c index 82d5e8a8c19ea..ef4e13fb49831 100644 --- a/drivers/interconnect/qcom/sc7180.c +++ b/drivers/interconnect/qcom/sc7180.c @@ -443,7 +443,7 @@ static struct qcom_icc_node * const qup_virt_nodes[] = { [SLAVE_QUP_CORE_1] = &qup_core_slave_2, }; -static const struct qcom_icc_desc sc7180_qup_virt = { +static const struct qcom_icc_desc sc7180_qup_virt = { .nodes = qup_virt_nodes, .num_nodes = ARRAY_SIZE(qup_virt_nodes), .bcms = qup_virt_bcms, -- GitLab From c1c537cf30bc539d8f6fa4ac315a8def23fd4ae8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Oct 2022 11:48:48 -0400 Subject: [PATCH 0579/1480] interconnect: qcom: sc8180x: constify pointer to qcom_icc_node Pointers to struct qcom_icc_node are const. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221027154848.293523-3-krzysztof.kozlowski@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/sc8180x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c index 8e32ca958824c..0f515bf10bd71 100644 --- a/drivers/interconnect/qcom/sc8180x.c +++ b/drivers/interconnect/qcom/sc8180x.c @@ -1889,7 +1889,7 @@ static struct qcom_icc_bcm * const qup_virt_bcms[] = { &bcm_qup0, }; -static struct qcom_icc_node *qup_virt_nodes[] = { +static struct qcom_icc_node * const qup_virt_nodes[] = { [MASTER_QUP_CORE_0] = &mas_qup_core_0, [MASTER_QUP_CORE_1] = &mas_qup_core_1, [MASTER_QUP_CORE_2] = &mas_qup_core_2, -- GitLab From 435d6b6564568b82ec74ee7d4d0bcb1f24ccb5f5 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Thu, 17 Nov 2022 10:16:32 -0700 Subject: [PATCH 0580/1480] vmlinux.lds.h: fix BOUNDED_SECTION_(PRE|POST)_LABEL macros Commit 2f465b921bb8 ("vmlinux.lds.h: place optional header space in BOUNDED_SECTION") added BOUNDED_SECTION_(PRE|POST)_LABEL macros, encapsulating the basic boilerplate to KEEP/pack records into a section, and to mark the begin and end of the section with linker-symbols. But it tried to do extra, adding KEEP(*(.gnu.linkonce.##_sec_)) to optionally reserve a header record in front of the data. It wrongly placed the KEEP after the linker-symbol starting the section, so if a header was added, it would wind up in the data. Moving the KEEP to the "correct" place proved brittle, and too clever by half. The obvious safe fix is to remove the KEEP and restore the plain old boilerplate. The header can be added later, with separate macros. Also, the macro var-names: _s_, _e_ are nearly invisible, change them to more obvious names: _BEGIN_, _END_ Fixes: 2f465b921bb8 ("vmlinux.lds.h: place optional header space in BOUNDED_SECTION") Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20221117171633.923628-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index b3ca56ac163f7..c17f947852530 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -193,17 +193,15 @@ # endif #endif -#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _s_, _e_) \ - _s_##_label_ = .; \ - KEEP(*(.gnu.linkonce.##_sec_)) \ +#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_) \ + _BEGIN_##_label_ = .; \ KEEP(*(_sec_)) \ - _e_##_label_ = .; + _END_##_label_ = .; -#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _s_, _e_) \ - _label_##_s_ = .; \ - KEEP(*(.gnu.linkonce.##_sec_)) \ +#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) \ + _label_##_BEGIN_ = .; \ KEEP(*(_sec_)) \ - _label_##_e_ = .; + _label_##_END_ = .; #define BOUNDED_SECTION_BY(_sec_, _label_) \ BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop) -- GitLab From 1d926e259d8f8195fdfaeea7951149001894b473 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Thu, 17 Nov 2022 10:16:33 -0700 Subject: [PATCH 0581/1480] vmlinux.lds.h: add HEADERED_SECTION_* macros These macros elaborate on BOUNDED_SECTION_(PRE|POST)_LABEL macros, prepending an optional KEEP(.gnu.linkonce##_sec_) reservation, and a linker-symbol to address it. This allows a developer to define a header struct (which must fit with the section's base struct-type), and could contain: 1- fields whose value is common to the entire set of data-records. This allows the header & data structs to specialize, complement each other, and shrink. 2- an uplink pointer to an organizing struct which refs other related/sub data-tables header record is addressable via the extern'd header linker-symbol Once the linker-symbols created by the macro are ref'd extern in code, that code can compute a record's index (ptr - start) in the "primary" table, then use it to index into the related/sub tables. Adding a primary.map_* field foreach sub-table would then allow deduplication and remapping of that sub-table. This is aimed at dyndbg's struct _ddebug __dyndbg[] section, whose 3 columns: function, file, module are 50%, 90%, 100% redundant. The module column is fully recoverable after dynamic_debug_init() saves it to each ddebug_table.module as the builtin __dyndbg[] table is parsed. Given that those 3 columns use 24/56 of a _ddebug record, a dyndbg=y kernel with ~5k callsites could reduce kernel memory substantially. Returning that memory to the kernel buddy-allocator? is then possible. Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20221117171633.923628-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index c17f947852530..c9a475a30803e 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -208,6 +208,21 @@ #define BOUNDED_SECTION(_sec) BOUNDED_SECTION_BY(_sec, _sec) +#define HEADERED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \ + _HDR_##_label_ = .; \ + KEEP(*(.gnu.linkonce.##_sec_)) \ + BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_) + +#define HEADERED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \ + _label_##_HDR_ = .; \ + KEEP(*(.gnu.linkonce.##_sec_)) \ + BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) + +#define HEADERED_SECTION_BY(_sec_, _label_) \ + HEADERED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop) + +#define HEADERED_SECTION(_sec) HEADERED_SECTION_BY(_sec, _sec) + #ifdef CONFIG_TRACE_BRANCH_PROFILING #define LIKELY_PROFILE() \ BOUNDED_SECTION_BY(_ftrace_annotated_branch, _annotated_branch_profile) -- GitLab From a3f3e97a039cab5b7efc754dc2907ab5044c7c88 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Thu, 10 Nov 2022 10:09:27 +0100 Subject: [PATCH 0582/1480] staging: r8188eu: rename three functions Prefix the names of the following functions with the driver name. The original names are bad for the global namespace. While at it, convert is_IBSS_empty() to all lower case to follow kernel coding style. is_client_associated_to_ap() is_client_associated_to_ibss() is_IBSS_empty() Suggested-by: Greg Kroah-Hartman Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221110090927.17274-1-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 14 +++++++------- drivers/staging/r8188eu/core/rtw_wlan_util.c | 8 ++++---- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index be33489d3dfdd..161cb67f78828 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -5831,7 +5831,7 @@ void rtw_mlme_site_survey_done(struct adapter *adapter) int res; u8 reg; - if ((is_client_associated_to_ap(adapter)) || + if ((r8188eu_is_client_associated_to_ap(adapter)) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) { /* enable to rx data frame */ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF); @@ -5982,7 +5982,7 @@ void site_survey(struct adapter *padapter) Restore_DM_Func_Flag(padapter); /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ - if (is_client_associated_to_ap(padapter)) + if (r8188eu_is_client_associated_to_ap(padapter)) issue_nulldata(padapter, NULL, 0, 3, 500); rtw_mlme_site_survey_done(padapter); @@ -6952,7 +6952,7 @@ void mlmeext_sta_del_event_callback(struct adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) { + if (r8188eu_is_client_associated_to_ap(padapter) || r8188eu_is_ibss_empty(padapter)) { mlme_disconnect(padapter); rtw_set_bssid(padapter, null_addr); @@ -7025,7 +7025,7 @@ void linked_status_chk(struct adapter *padapter) rtl8188e_sreset_linked_status_check(padapter); - if (is_client_associated_to_ap(padapter)) { + if (r8188eu_is_client_associated_to_ap(padapter)) { /* linked infrastructure client mode */ int tx_chk = _SUCCESS, rx_chk = _SUCCESS; @@ -7097,7 +7097,7 @@ void linked_status_chk(struct adapter *padapter) pmlmeinfo->link_count = 0; } } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */ - } else if (is_client_associated_to_ibss(padapter)) { + } else if (r8188eu_is_client_associated_to_ibss(padapter)) { /* linked IBSS mode */ /* for each assoc list entry to check the rx pkt counter */ for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { @@ -7415,7 +7415,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) u8 val8; int res; - if (is_client_associated_to_ap(padapter)) + if (r8188eu_is_client_associated_to_ap(padapter)) issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100); mlme_disconnect(padapter); @@ -7527,7 +7527,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; /* issue null data if associating to the AP */ - if (is_client_associated_to_ap(padapter)) { + if (r8188eu_is_client_associated_to_ap(padapter)) { pmlmeext->sitesurvey_res.state = SCAN_TXNULL; issue_nulldata(padapter, NULL, 1, 3, 500); diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c index c95438a12b598..965bb7da4cce3 100644 --- a/drivers/staging/r8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c @@ -331,7 +331,7 @@ u16 get_beacon_interval(struct wlan_bssid_ex *bss) return le16_to_cpu(val); } -bool is_client_associated_to_ap(struct adapter *padapter) +bool r8188eu_is_client_associated_to_ap(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; @@ -348,7 +348,7 @@ bool is_client_associated_to_ap(struct adapter *padapter) return false; } -bool is_client_associated_to_ibss(struct adapter *padapter) +bool r8188eu_is_client_associated_to_ibss(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; @@ -359,7 +359,7 @@ bool is_client_associated_to_ibss(struct adapter *padapter) return false; } -bool is_IBSS_empty(struct adapter *padapter) +bool r8188eu_is_ibss_empty(struct adapter *padapter) { unsigned int i; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -893,7 +893,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) unsigned short ht_cap_info; unsigned char ht_info_infos_0; - if (!is_client_associated_to_ap(Adapter)) + if (!r8188eu_is_client_associated_to_ap(Adapter)) return true; len = packet_len - sizeof(struct ieee80211_hdr_3addr); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 9c0af4704607b..c46fc1a530859 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -431,9 +431,9 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork); u16 get_beacon_interval(struct wlan_bssid_ex *bss); -bool is_client_associated_to_ap(struct adapter *padapter); -bool is_client_associated_to_ibss(struct adapter *padapter); -bool is_IBSS_empty(struct adapter *padapter); +bool r8188eu_is_client_associated_to_ap(struct adapter *padapter); +bool r8188eu_is_client_associated_to_ibss(struct adapter *padapter); +bool r8188eu_is_ibss_empty(struct adapter *padapter); unsigned char check_assoc_AP(u8 *pframe, uint len); -- GitLab From 9b35a6926c613457e0dce179871028a0aa6efb06 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Fri, 11 Nov 2022 09:37:30 +0100 Subject: [PATCH 0583/1480] staging: r8188eu: convert aes_cipher() to void The function aes_cipher() returns always _SUCCESS and its callers do not use the return value. So we can convert the return type to void and get rid of another use of _SUCCESS. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221111083733.3144-2-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_security.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_security.c b/drivers/staging/r8188eu/core/rtw_security.c index 5bba57d18b5fc..780019ce1b983 100644 --- a/drivers/staging/r8188eu/core/rtw_security.c +++ b/drivers/staging/r8188eu/core/rtw_security.c @@ -954,7 +954,7 @@ static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) } -static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) +static void aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) { uint qc_exists, a4_exists, i, j, payload_remainder, num_blocks, payload_index; @@ -1083,8 +1083,6 @@ static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) bitwise_xor(aes_out, padded_buffer, chain_buffer); for (j = 0; j < 8; j++) pframe[payload_index++] = chain_buffer[j]; - - return _SUCCESS; } u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) -- GitLab From 8985814bb3732aaf7ce5bf892d2827bd4d854fc7 Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Fri, 11 Nov 2022 09:37:31 +0100 Subject: [PATCH 0584/1480] staging: r8188eu: convert rtw_xmit_resource_alloc() to common error logic Convert the function rtw_xmit_resource_alloc() away from returning _FAIL or _SUCCESS which uses inverted error logic. Use the common error logic instead. Return 0 for success and negative values for failure. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221111083733.3144-3-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_xmit.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c index bd6c1a401c590..c0fda6ce7c56c 100644 --- a/drivers/staging/r8188eu/core/rtw_xmit.c +++ b/drivers/staging/r8188eu/core/rtw_xmit.c @@ -38,7 +38,7 @@ static int rtw_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *px { pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL); if (!pxmitbuf->pallocated_buf) - return _FAIL; + return -ENOMEM; pxmitbuf->pbuf = (u8 *)ALIGN((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); pxmitbuf->dma_transfer_addr = 0; @@ -46,10 +46,10 @@ static int rtw_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *px pxmitbuf->pxmit_urb = usb_alloc_urb(0, GFP_KERNEL); if (!pxmitbuf->pxmit_urb) { kfree(pxmitbuf->pallocated_buf); - return _FAIL; + return -ENOMEM; } - return _SUCCESS; + return 0; } static void rtw_xmit_resource_free(struct adapter *padapter, struct xmit_buf *pxmitbuf, @@ -151,12 +151,12 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitbuf->ext_tag = false; /* Tx buf allocation may fail sometimes, so sleep and retry. */ - res = rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); - if (res == _FAIL) { + if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) { msleep(10); - res = rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); - if (res == _FAIL) + if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) { + res = _FAIL; goto free_xmitbuf; + } } pxmitbuf->flags = XMIT_VO_QUEUE; @@ -188,8 +188,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitbuf->padapter = padapter; pxmitbuf->ext_tag = true; - res = rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); - if (res == _FAIL) { + if (rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) { res = _FAIL; goto free_xmit_extbuf; } -- GitLab From 64ce3acd0a50b3ad7ff345fe11bbb3d39cab216b Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Fri, 11 Nov 2022 09:37:32 +0100 Subject: [PATCH 0585/1480] staging: r8188eu: convert _rtw_init_xmit_priv() to common error logic Convert the function _rtw_init_xmit_priv() away from returning _FAIL or _SUCCESS which uses inverted error logic. Use the common error logic instead. Return 0 for success and negative values for failure. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221111083733.3144-4-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_xmit.c | 28 +++++++--------------- drivers/staging/r8188eu/include/rtw_xmit.h | 2 +- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c index c0fda6ce7c56c..34494f08c0cdf 100644 --- a/drivers/staging/r8188eu/core/rtw_xmit.c +++ b/drivers/staging/r8188eu/core/rtw_xmit.c @@ -59,12 +59,11 @@ static void rtw_xmit_resource_free(struct adapter *padapter, struct xmit_buf *px kfree(pxmitbuf->pallocated_buf); } -s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) +int _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) { int i; struct xmit_buf *pxmitbuf; struct xmit_frame *pxframe; - int res = _SUCCESS; u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; @@ -97,7 +96,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) if (!pxmitpriv->pallocated_frame_buf) { pxmitpriv->pxmit_frame_buf = NULL; - res = _FAIL; goto exit; } pxmitpriv->pxmit_frame_buf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_frame_buf), 4); @@ -132,10 +130,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4); - if (!pxmitpriv->pallocated_xmitbuf) { - res = _FAIL; + if (!pxmitpriv->pallocated_xmitbuf) goto free_frame_buf; - } pxmitpriv->pxmitbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmitbuf), 4); /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */ @@ -153,10 +149,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) /* Tx buf allocation may fail sometimes, so sleep and retry. */ if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) { msleep(10); - if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) { - res = _FAIL; + if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) goto free_xmitbuf; - } } pxmitbuf->flags = XMIT_VO_QUEUE; @@ -172,10 +166,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); - if (!pxmitpriv->pallocated_xmit_extbuf) { - res = _FAIL; + if (!pxmitpriv->pallocated_xmit_extbuf) goto free_xmitbuf; - } pxmitpriv->pxmit_extbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4); @@ -188,10 +180,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitbuf->padapter = padapter; pxmitbuf->ext_tag = true; - if (rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) { - res = _FAIL; + if (rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) goto free_xmit_extbuf; - } list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); pxmitbuf++; @@ -199,10 +189,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; - if (rtw_alloc_hwxmits(padapter)) { - res = _FAIL; + if (rtw_alloc_hwxmits(padapter)) goto free_xmit_extbuf; - } rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); @@ -225,7 +213,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) rtl8188eu_init_xmit_priv(padapter); - return _SUCCESS; + return 0; free_xmit_extbuf: pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; @@ -245,7 +233,7 @@ free_xmitbuf: free_frame_buf: vfree(pxmitpriv->pallocated_frame_buf); exit: - return res; + return -ENOMEM; } static void rtw_pkt_complete(struct adapter *padapter, struct sk_buff *pkt) diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h index cff065554608d..6e7ebea5362d8 100644 --- a/drivers/staging/r8188eu/include/rtw_xmit.h +++ b/drivers/staging/r8188eu/include/rtw_xmit.h @@ -351,7 +351,7 @@ s32 rtw_txframes_pending(struct adapter *padapter); s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib); void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry); -s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); +int _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv); int rtw_alloc_hwxmits(struct adapter *padapter); void rtw_free_hwxmits(struct adapter *padapter); diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 66556e07ed93d..44eb95a7682c8 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -480,7 +480,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) init_mlme_ext_priv(padapter); - if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { + if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter)) { dev_err(dvobj_to_dev(padapter->dvobj), "_rtw_init_xmit_priv failed\n"); goto free_mlme_ext; } -- GitLab From 7209757311d6eec4c531feba31b170c33122491e Mon Sep 17 00:00:00 2001 From: Michael Straube Date: Fri, 11 Nov 2022 09:37:33 +0100 Subject: [PATCH 0586/1480] staging: r8188eu: binstallGrpkey is set to _FAIL The variable binstallGrpkey is set to _FAIL which is defined as 0. Use false to set the variable to get rid of another use of _FAIL. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Michael Straube Link: https://lore.kernel.org/r/20221111083733.3144-5-straube.linux@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/os_dep/os_intfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c index 44eb95a7682c8..2f59bb9947960 100644 --- a/drivers/staging/r8188eu/os_dep/os_intfs.c +++ b/drivers/staging/r8188eu/os_dep/os_intfs.c @@ -405,7 +405,7 @@ static void rtw_init_default_value(struct adapter *padapter) pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ /* security_priv */ - psecuritypriv->binstallGrpkey = _FAIL; + psecuritypriv->binstallGrpkey = false; psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ -- GitLab From b397fc48c5d9b70ad17ffeaf8607a4f49055c0d9 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:34:54 +0100 Subject: [PATCH 0587/1480] staging: rtl8192e: Rename bTxDisableRate.., RegMaxLPSAwa.. and bTxUseD.. Rename variable bTxDisableRateFallBack to tx_dis_rate_fallback, RegMaxLPSAwakeIntvl to reg_max_lps_awake_intvl and bTxUseDriverAssingedRate to tx_use_drv_assinged_rate to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/092eb2dc73d37daf851ea9ef9cb7e4df6f766845.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 4 ++-- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 10 ++++---- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 2 +- drivers/staging/rtl8192e/rtl819x_HTProc.c | 4 ++-- drivers/staging/rtl8192e/rtllib.h | 10 ++++---- drivers/staging/rtl8192e/rtllib_softmac.c | 14 +++++------ drivers/staging/rtl8192e/rtllib_tx.c | 24 +++++++++---------- 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 210b7ecc273ab..39aac83d89604 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1136,8 +1136,8 @@ void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, cb_desc->priority); pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci); - pdesc->DISFB = cb_desc->bTxDisableRateFallBack; - pdesc->USERATE = cb_desc->bTxUseDriverAssingedRate; + pdesc->DISFB = cb_desc->tx_dis_rate_fallback; + pdesc->USERATE = cb_desc->tx_use_drv_assinged_rate; pdesc->FirstSeg = 1; pdesc->LastSeg = 1; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 213aac943ef76..952fe8d7a7be4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -494,8 +494,8 @@ static void _rtl92e_prepare_beacon(struct tasklet_struct *t) tcb_desc->queue_index = BEACON_QUEUE; tcb_desc->data_rate = 2; tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_dis_rate_fallback = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; skb_push(pnewskb, priv->rtllib->tx_headroom); pdesc = &ring->desc[0]; @@ -822,7 +822,7 @@ static void _rtl92e_init_priv_constant(struct net_device *dev) struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) &priv->rtllib->PowerSaveControl; - pPSC->RegMaxLPSAwakeIntvl = 5; + pPSC->reg_max_lps_awake_intvl = 5; } static void _rtl92e_init_priv_variable(struct net_device *dev) @@ -1538,8 +1538,8 @@ static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_dis_rate_fallback = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; tcb_desc->bTxEnableFwCalcDur = 1; skb_push(skb, priv->rtllib->tx_headroom); ret = _rtl92e_tx(dev, skb); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 12eea4fcb9dde..ffef63e8dcaee 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -196,7 +196,7 @@ static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev, netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n", __func__, *extra); - pPSC->RegMaxLPSAwakeIntvl = *extra; + pPSC->reg_max_lps_awake_intvl = *extra; mutex_unlock(&priv->wx_mutex); return 0; } diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 2c0a8d5c8f279..7fad983ad4be1 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -91,8 +91,8 @@ void HTUpdateDefaultSetting(struct rtllib_device *ieee) pHTInfo->self_mimo_ps = 3; if (pHTInfo->self_mimo_ps == 2) pHTInfo->self_mimo_ps = 3; - ieee->bTxDisableRateFallBack = 0; - ieee->bTxUseDriverAssingedRate = 0; + ieee->tx_dis_rate_fallback = 0; + ieee->tx_use_drv_assinged_rate = 0; ieee->bTxEnableFwCalcDur = 1; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index e0fa87b12cebb..ca9e016ffa9fe 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -126,8 +126,8 @@ struct cb_desc { u8 bFirstSeg:1; u8 bLastSeg:1; u8 bEncrypt:1; - u8 bTxDisableRateFallBack:1; - u8 bTxUseDriverAssingedRate:1; + u8 tx_dis_rate_fallback:1; + u8 tx_use_drv_assinged_rate:1; u8 bHwSec:1; u8 nStuckCount; @@ -1256,7 +1256,7 @@ struct rt_pwr_save_ctrl { bool bLeisurePs; u8 LpsIdleCount; - u8 RegMaxLPSAwakeIntvl; + u8 reg_max_lps_awake_intvl; u8 LPSAwakeIntvl; u32 CurPsLevel; @@ -1441,8 +1441,8 @@ struct rtllib_device { u8 RegHTSuppRateSet[16]; u8 HTCurrentOperaRate; u8 HTHighestOperaRate; - u8 bTxDisableRateFallBack; - u8 bTxUseDriverAssingedRate; + u8 tx_dis_rate_fallback; + u8 tx_use_drv_assinged_rate; u8 bTxEnableFwCalcDur; atomic_t atm_swbw; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 1253de4818053..604d4fd7e2cde 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -220,8 +220,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_dis_rate_fallback = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; if (single) { if (ieee->queue_stop) { enqueue_mgmt(ieee, skb); @@ -298,8 +298,8 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb, tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_dis_rate_fallback = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; if (single) { if (type != RTLLIB_FTYPE_CTL) { header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); @@ -1996,12 +1996,12 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) if (pPSC->LPSAwakeIntvl == 0) pPSC->LPSAwakeIntvl = 1; - if (pPSC->RegMaxLPSAwakeIntvl == 0) + if (pPSC->reg_max_lps_awake_intvl == 0) MaxPeriod = 1; - else if (pPSC->RegMaxLPSAwakeIntvl == 0xFF) + else if (pPSC->reg_max_lps_awake_intvl == 0xFF) MaxPeriod = ieee->current_network.dtim_period; else - MaxPeriod = pPSC->RegMaxLPSAwakeIntvl; + MaxPeriod = pPSC->reg_max_lps_awake_intvl; pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1); diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 101f441291451..be3779efcd233 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -477,13 +477,13 @@ NO_PROTECTION: static void rtllib_txrate_selectmode(struct rtllib_device *ieee, struct cb_desc *tcb_desc) { - if (ieee->bTxDisableRateFallBack) - tcb_desc->bTxDisableRateFallBack = true; + if (ieee->tx_dis_rate_fallback) + tcb_desc->tx_dis_rate_fallback = true; - if (ieee->bTxUseDriverAssingedRate) - tcb_desc->bTxUseDriverAssingedRate = true; - if (!tcb_desc->bTxDisableRateFallBack || - !tcb_desc->bTxUseDriverAssingedRate) { + if (ieee->tx_use_drv_assinged_rate) + tcb_desc->tx_use_drv_assinged_rate = true; + if (!tcb_desc->tx_dis_rate_fallback || + !tcb_desc->tx_use_drv_assinged_rate) { if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) tcb_desc->RATRIndex = 0; @@ -886,14 +886,14 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); - tcb_desc->bTxDisableRateFallBack = false; + tcb_desc->tx_dis_rate_fallback = false; } else { tcb_desc->data_rate = ieee->basic_rate; - tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->tx_dis_rate_fallback = 1; } tcb_desc->RATRIndex = 7; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; } else { if (is_multicast_ether_addr(header.addr1)) tcb_desc->bMulticast = 1; @@ -910,14 +910,14 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); - tcb_desc->bTxDisableRateFallBack = false; + tcb_desc->tx_dis_rate_fallback = false; } else { tcb_desc->data_rate = MGN_1M; - tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->tx_dis_rate_fallback = 1; } tcb_desc->RATRIndex = 7; - tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->tx_use_drv_assinged_rate = 1; tcb_desc->bdhcp = 1; } -- GitLab From c7bf6d33d095637fb78ba484a181d17bc1a73a68 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:12 +0100 Subject: [PATCH 0588/1480] staging: rtl8192e: Rename Regdot11HTOper.., bSupportM.. and PowerSaveCo.. Rename variable Regdot11HTOperationalRateSet to reg_dot11ht_oper_rate_set, bSupportMode to support_mode and PowerSaveControl to pwr_save_ctrl to avoid CamelCase which is not accepted by checkpatch. Fix unnecessary parentheses warning from checkpatch when used with this variables. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/1ef7fd22b4a037c4d1f8685065ce7916b6f0930b.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_phy.c | 2 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 30 +++++++++---------- drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 10 +++---- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 4 +-- drivers/staging/rtl8192e/rtl819x_HTProc.c | 2 +- drivers/staging/rtl8192e/rtllib.h | 4 +-- drivers/staging/rtl8192e/rtllib_softmac.c | 10 +++---- 7 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 58da2dab55bd6..b14497423cbf7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -1304,7 +1304,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&(priv->rtllib->PowerSaveControl)); + (&priv->rtllib->pwr_save_ctrl); bool bResult = true; u8 i = 0, QueueID = 0; struct rtl8192_tx_ring *ring = NULL; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 952fe8d7a7be4..16e15b8e1b7a6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -607,13 +607,13 @@ static void _rtl92e_refresh_support_rate(struct r8192_priv *priv) if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) { - memcpy(ieee->Regdot11HTOperationalRateSet, + memcpy(ieee->reg_dot11ht_oper_rate_set, ieee->RegHTSuppRateSet, 16); memcpy(ieee->Regdot11TxHTOperationalRateSet, ieee->RegHTSuppRateSet, 16); } else { - memset(ieee->Regdot11HTOperationalRateSet, 0, 16); + memset(ieee->reg_dot11ht_oper_rate_set, 0, 16); } } @@ -642,19 +642,19 @@ static u8 _rtl92e_get_supported_wireless_mode(struct net_device *dev) void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) { struct r8192_priv *priv = rtllib_priv(dev); - u8 bSupportMode = _rtl92e_get_supported_wireless_mode(dev); + u8 support_mode = _rtl92e_get_supported_wireless_mode(dev); if ((wireless_mode == WIRELESS_MODE_AUTO) || - ((wireless_mode & bSupportMode) == 0)) { - if (bSupportMode & WIRELESS_MODE_N_24G) { + ((wireless_mode & support_mode) == 0)) { + if (support_mode & WIRELESS_MODE_N_24G) { wireless_mode = WIRELESS_MODE_N_24G; - } else if (bSupportMode & WIRELESS_MODE_N_5G) { + } else if (support_mode & WIRELESS_MODE_N_5G) { wireless_mode = WIRELESS_MODE_N_5G; - } else if ((bSupportMode & WIRELESS_MODE_A)) { + } else if ((support_mode & WIRELESS_MODE_A)) { wireless_mode = WIRELESS_MODE_A; - } else if ((bSupportMode & WIRELESS_MODE_G)) { + } else if ((support_mode & WIRELESS_MODE_G)) { wireless_mode = WIRELESS_MODE_G; - } else if ((bSupportMode & WIRELESS_MODE_B)) { + } else if ((support_mode & WIRELESS_MODE_B)) { wireless_mode = WIRELESS_MODE_B; } else { netdev_info(dev, @@ -683,7 +683,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->PowerSaveControl); + (&priv->rtllib->pwr_save_ctrl); bool init_status; priv->bdisable_nic = false; @@ -820,7 +820,7 @@ static void _rtl92e_init_priv_constant(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &priv->rtllib->PowerSaveControl; + &priv->rtllib->pwr_save_ctrl; pPSC->reg_max_lps_awake_intvl = 5; } @@ -877,7 +877,7 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rf_change_in_progress = false; priv->bHwRfOffAction = 0; priv->SetRFPowerStateInProgress = false; - priv->rtllib->PowerSaveControl.bLeisurePs = true; + priv->rtllib->pwr_save_ctrl.bLeisurePs = true; priv->rtllib->LPSDelayCnt = 0; priv->rtllib->sta_sleep = LPS_IS_WAKE; priv->rtllib->rf_power_state = rf_on; @@ -1272,7 +1272,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) static u8 check_reset_cnt; unsigned long flags; struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->PowerSaveControl); + (&priv->rtllib->pwr_save_ctrl); bool bBusyTraffic = false; bool bHigherBusyTraffic = false; bool bHigherBusyRxTraffic = false; @@ -1295,7 +1295,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) RTLLIB_NOLINK) && (ieee->rf_power_state == rf_on) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc) { - if ((ieee->PowerSaveControl.ReturnPoint == + if ((ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE) && (!ieee->bNetPromiscuousMode)) { rtl92e_ips_enter(dev); @@ -2422,7 +2422,7 @@ bool rtl92e_enable_nic(struct net_device *dev) bool init_status = true; struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->PowerSaveControl); + (&priv->rtllib->pwr_save_ctrl); if (!priv->up) { netdev_warn(dev, "%s(): Driver is already down!\n", __func__); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 1501f7be8eee9..8a6b7f58ebfdd 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -101,7 +101,7 @@ static void _rtl92e_ps_update_rf_state(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &(priv->rtllib->PowerSaveControl); + &priv->rtllib->pwr_save_ctrl; pPSC->bSwRfProcessing = true; rtl92e_set_rf_state(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); @@ -113,7 +113,7 @@ void rtl92e_ips_enter(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &(priv->rtllib->PowerSaveControl); + &priv->rtllib->pwr_save_ctrl; enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; @@ -129,7 +129,7 @@ void rtl92e_ips_leave(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &(priv->rtllib->PowerSaveControl); + &priv->rtllib->pwr_save_ctrl; enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; @@ -207,7 +207,7 @@ void rtl92e_leisure_ps_enter(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &(priv->rtllib->PowerSaveControl); + &priv->rtllib->pwr_save_ctrl; if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && (priv->rtllib->state == RTLLIB_LINKED)) @@ -233,7 +233,7 @@ void rtl92e_leisure_ps_leave(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - &(priv->rtllib->PowerSaveControl); + &priv->rtllib->pwr_save_ctrl; if (pPSC->bLeisurePs) { if (priv->rtllib->ps != RTLLIB_PS_DISABLED) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index ffef63e8dcaee..d68f8f5902c8d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -160,7 +160,7 @@ static int _rtl92e_wx_adapter_power_status(struct net_device *dev, { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->PowerSaveControl); + (&priv->rtllib->pwr_save_ctrl); struct rtllib_device *ieee = priv->rtllib; mutex_lock(&priv->wx_mutex); @@ -189,7 +189,7 @@ static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev, { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->PowerSaveControl); + (&priv->rtllib->pwr_save_ctrl); mutex_lock(&priv->wx_mutex); diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 7fad983ad4be1..52f41562dd824 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -323,7 +323,7 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, pCapELE->MPDUDensity = 0; } - memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); + memcpy(pCapELE->MCS, ieee->reg_dot11ht_oper_rate_set, 16); memset(&pCapELE->ExtHTCapInfo, 0, 2); memset(pCapELE->TxBFCap, 0, 4); diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index ca9e016ffa9fe..d80883b211cea 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1435,7 +1435,7 @@ struct rtllib_device { struct rt_hi_throughput *pHTInfo; spinlock_t reorder_spinlock; - u8 Regdot11HTOperationalRateSet[16]; + u8 reg_dot11ht_oper_rate_set[16]; u8 Regdot11TxHTOperationalRateSet[16]; u8 dot11HTOperationalRateSet[16]; u8 RegHTSuppRateSet[16]; @@ -1645,7 +1645,7 @@ struct rtllib_device { struct rt_link_detect LinkDetectInfo; bool bIsAggregateFrame; - struct rt_pwr_save_ctrl PowerSaveControl; + struct rt_pwr_save_ctrl pwr_save_ctrl; /* used if IEEE_SOFTMAC_TX_QUEUE is set */ struct tx_pending tx_pending; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 604d4fd7e2cde..498febc88b15e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1504,7 +1504,7 @@ static void rtllib_associate_complete_wq(void *data) container_of_work_rsl(data, struct rtllib_device, associate_complete_wq); - struct rt_pwr_save_ctrl *pPSC = &(ieee->PowerSaveControl); + struct rt_pwr_save_ctrl *pPSC = &ieee->pwr_save_ctrl; netdev_info(ieee->dev, "Associated successfully with %pM\n", ieee->current_network.bssid); @@ -1960,7 +1960,7 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) { int timeout; u8 dtim; - struct rt_pwr_save_ctrl *pPSC = &(ieee->PowerSaveControl); + struct rt_pwr_save_ctrl *pPSC = &ieee->pwr_save_ctrl; if (ieee->LPSDelayCnt) { ieee->LPSDelayCnt--; @@ -2984,9 +2984,9 @@ int rtllib_softmac_init(struct rtllib_device *ieee) ieee->ps = RTLLIB_PS_DISABLED; ieee->sta_sleep = LPS_IS_WAKE; - ieee->Regdot11HTOperationalRateSet[0] = 0xff; - ieee->Regdot11HTOperationalRateSet[1] = 0xff; - ieee->Regdot11HTOperationalRateSet[4] = 0x01; + ieee->reg_dot11ht_oper_rate_set[0] = 0xff; + ieee->reg_dot11ht_oper_rate_set[1] = 0xff; + ieee->reg_dot11ht_oper_rate_set[4] = 0x01; ieee->Regdot11TxHTOperationalRateSet[0] = 0xff; ieee->Regdot11TxHTOperationalRateSet[1] = 0xff; -- GitLab From ca25401e21ab40539a5ed4b86aecc3698f89b86f Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:27 +0100 Subject: [PATCH 0589/1480] staging: rtl8192e: Rename Regdot11TxHT.., dot11HTOpera.. and RegHTSuppRa.. Rename variable Regdot11TxHTOperationalRateSet to reg_dot11tx_ht_oper_rate_set, dot11HTOperationalRateSet to dot11ht_oper_rate_set and RegHTSuppRateSet to reg_ht_supp_rate_set to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/0c87e7ffc94be1c26f6400f5e12419f2df0418a3.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 2 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 6 +++--- drivers/staging/rtl8192e/rtl819x_HTProc.c | 14 +++++++------- drivers/staging/rtl8192e/rtllib.h | 6 +++--- drivers/staging/rtl8192e/rtllib_softmac.c | 10 +++++----- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 39aac83d89604..bbaf20fbfde05 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1958,7 +1958,7 @@ void rtl92e_update_ratr_table(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rtllib_device *ieee = priv->rtllib; - u8 *pMcsRate = ieee->dot11HTOperationalRateSet; + u8 *pMcsRate = ieee->dot11ht_oper_rate_set; u32 ratr_value = 0; u16 rate_config = 0; u8 rate_index = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 16e15b8e1b7a6..d5eec6d6b644f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -608,9 +608,9 @@ static void _rtl92e_refresh_support_rate(struct r8192_priv *priv) if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) { memcpy(ieee->reg_dot11ht_oper_rate_set, - ieee->RegHTSuppRateSet, 16); - memcpy(ieee->Regdot11TxHTOperationalRateSet, - ieee->RegHTSuppRateSet, 16); + ieee->reg_ht_supp_rate_set, 16); + memcpy(ieee->reg_dot11tx_ht_oper_rate_set, + ieee->reg_ht_supp_rate_set, 16); } else { memset(ieee->reg_dot11ht_oper_rate_set, 0, 16); diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 52f41562dd824..2092ebf717a1f 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -489,7 +489,7 @@ static u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, u8 i; for (i = 0; i <= 15; i++) - pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & + pOperateMCS[i] = ieee->reg_dot11tx_ht_oper_rate_set[i] & pSupportMCS[i]; HT_PickMCSRate(ieee, pOperateMCS); @@ -604,7 +604,7 @@ void HTOnAssocRsp(struct rtllib_device *ieee) HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); - HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); + HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11ht_oper_rate_set); pHTInfo->peer_mimo_ps = pPeerHTCap->MimoPwrSave; if (pHTInfo->peer_mimo_ps == MIMO_PS_STATIC) @@ -612,7 +612,7 @@ void HTOnAssocRsp(struct rtllib_device *ieee) else pMcsFilter = MCS_FILTER_ALL; ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, - ieee->dot11HTOperationalRateSet, + ieee->dot11ht_oper_rate_set, pMcsFilter); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; @@ -661,7 +661,7 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) pHTInfo->iot_ra_func = 0; { - u8 *RegHTSuppRateSets = &ieee->RegHTSuppRateSet[0]; + u8 *RegHTSuppRateSets = &ieee->reg_ht_supp_rate_set[0]; RegHTSuppRateSets[0] = 0xFF; RegHTSuppRateSets[1] = 0xFF; @@ -796,10 +796,10 @@ void HTUseDefaultSetting(struct rtllib_device *ieee) pHTInfo->current_mpdu_density = pHTInfo->current_mpdu_density; - HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, - ieee->dot11HTOperationalRateSet); + HTFilterMCSRate(ieee, ieee->reg_dot11tx_ht_oper_rate_set, + ieee->dot11ht_oper_rate_set); ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, - ieee->dot11HTOperationalRateSet, + ieee->dot11ht_oper_rate_set, MCS_FILTER_ALL); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index d80883b211cea..487aa337eafa4 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1436,9 +1436,9 @@ struct rtllib_device { spinlock_t reorder_spinlock; u8 reg_dot11ht_oper_rate_set[16]; - u8 Regdot11TxHTOperationalRateSet[16]; - u8 dot11HTOperationalRateSet[16]; - u8 RegHTSuppRateSet[16]; + u8 reg_dot11tx_ht_oper_rate_set[16]; + u8 dot11ht_oper_rate_set[16]; + u8 reg_ht_supp_rate_set[16]; u8 HTCurrentOperaRate; u8 HTHighestOperaRate; u8 tx_dis_rate_fallback; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 498febc88b15e..09cc3b3068cc8 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1532,7 +1532,7 @@ static void rtllib_associate_complete_wq(void *data) "Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); - memset(ieee->dot11HTOperationalRateSet, 0, 16); + memset(ieee->dot11ht_oper_rate_set, 0, 16); } ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / @@ -1728,7 +1728,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, netdev_info(ieee->dev, "Using B rates\n"); } - memset(ieee->dot11HTOperationalRateSet, 0, 16); + memset(ieee->dot11ht_oper_rate_set, 0, 16); ieee->state = RTLLIB_LINKED; } } @@ -2988,9 +2988,9 @@ int rtllib_softmac_init(struct rtllib_device *ieee) ieee->reg_dot11ht_oper_rate_set[1] = 0xff; ieee->reg_dot11ht_oper_rate_set[4] = 0x01; - ieee->Regdot11TxHTOperationalRateSet[0] = 0xff; - ieee->Regdot11TxHTOperationalRateSet[1] = 0xff; - ieee->Regdot11TxHTOperationalRateSet[4] = 0x01; + ieee->reg_dot11tx_ht_oper_rate_set[0] = 0xff; + ieee->reg_dot11tx_ht_oper_rate_set[1] = 0xff; + ieee->reg_dot11tx_ht_oper_rate_set[4] = 0x01; ieee->FirstIe_InScan = false; ieee->actscanning = false; -- GitLab From ca0298c09a5ec55954c0c0c1585e6a5643b8d3ca Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:34 +0100 Subject: [PATCH 0590/1480] staging: rtl8192e: Rename pPSC Rename variable pPSC to psc to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/47ded8a906e55d6f09b51cd8f2dfb78b7b92c1cc.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_phy.c | 14 +++---- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 16 ++++---- drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 32 ++++++++-------- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 10 ++--- drivers/staging/rtl8192e/rtllib.h | 10 ++--- drivers/staging/rtl8192e/rtllib_softmac.c | 38 +++++++++---------- 6 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index b14497423cbf7..c357adf95a3d0 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -1303,7 +1303,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, enum rt_rf_power_state rf_power_state) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); bool bResult = true; u8 i = 0, QueueID = 0; @@ -1318,7 +1318,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, switch (rf_power_state) { case rf_on: if ((priv->rtllib->rf_power_state == rf_off) && - RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { + RT_IN_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC)) { bool rtstatus; u32 InitilizeCount = 3; @@ -1335,7 +1335,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, return false; } - RT_CLEAR_PS_LEVEL(pPSC, + RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); } else { rtl92e_writeb(dev, ANAPAR, 0x37); @@ -1399,11 +1399,11 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, break; } - if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && - !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { + if (psc->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && + !RT_IN_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC)) { rtl92e_disable_nic(dev); - RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - } else if (!(pPSC->RegRfPsLevel & + RT_SET_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); + } else if (!(psc->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) { rtl92e_set_rf_off(dev); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index d5eec6d6b644f..144bc7c9abd52 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -682,7 +682,7 @@ void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); bool init_status; @@ -700,7 +700,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) return -1; } - RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); priv->bfirst_init = false; if (priv->polling_timer_on == 0) @@ -819,10 +819,10 @@ static void _rtl92e_init_priv_handler(struct net_device *dev) static void _rtl92e_init_priv_constant(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; - pPSC->reg_max_lps_awake_intvl = 5; + psc->reg_max_lps_awake_intvl = 5; } static void _rtl92e_init_priv_variable(struct net_device *dev) @@ -1271,7 +1271,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) enum reset_type ResetType = RESET_TYPE_NORESET; static u8 check_reset_cnt; unsigned long flags; - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); bool bBusyTraffic = false; bool bHigherBusyTraffic = false; @@ -1389,7 +1389,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) spin_lock_irqsave(&priv->tx_lock, flags); if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) && - (!priv->rf_change_in_progress) && (!pPSC->bSwRfProcessing)) { + (!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) { ResetType = _rtl92e_if_check_reset(dev); check_reset_cnt = 3; } @@ -2421,7 +2421,7 @@ bool rtl92e_enable_nic(struct net_device *dev) { bool init_status = true; struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); if (!priv->up) { @@ -2437,7 +2437,7 @@ bool rtl92e_enable_nic(struct net_device *dev) priv->bdisable_nic = false; return false; } - RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); priv->bfirst_init = false; rtl92e_irq_enable(dev); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 8a6b7f58ebfdd..ef4f736ce3255 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -100,27 +100,27 @@ void rtl92e_enter_sleep(struct net_device *dev, u64 time) static void _rtl92e_ps_update_rf_state(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; - pPSC->bSwRfProcessing = true; - rtl92e_set_rf_state(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); + psc->bSwRfProcessing = true; + rtl92e_set_rf_state(dev, psc->eInactivePowerState, RF_CHANGE_BY_IPS); - pPSC->bSwRfProcessing = false; + psc->bSwRfProcessing = false; } void rtl92e_ips_enter(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; - if (rt_state == rf_on && !pPSC->bSwRfProcessing && + if (rt_state == rf_on && !psc->bSwRfProcessing && (priv->rtllib->state != RTLLIB_LINKED) && (priv->rtllib->iw_mode != IW_MODE_MASTER)) { - pPSC->eInactivePowerState = rf_off; + psc->eInactivePowerState = rf_off; _rtl92e_ps_update_rf_state(dev); } } @@ -128,14 +128,14 @@ void rtl92e_ips_enter(struct net_device *dev) void rtl92e_ips_leave(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; enum rt_rf_power_state rt_state; rt_state = priv->rtllib->rf_power_state; - if (rt_state != rf_on && !pPSC->bSwRfProcessing && + if (rt_state != rf_on && !psc->bSwRfProcessing && priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { - pPSC->eInactivePowerState = rf_on; + psc->eInactivePowerState = rf_on; _rtl92e_ps_update_rf_state(dev); } } @@ -206,7 +206,7 @@ static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode) void rtl92e_leisure_ps_enter(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && @@ -215,8 +215,8 @@ void rtl92e_leisure_ps_enter(struct net_device *dev) (priv->rtllib->iw_mode == IW_MODE_MASTER)) return; - if (pPSC->bLeisurePs) { - if (pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) { + if (psc->bLeisurePs) { + if (psc->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) { if (priv->rtllib->ps == RTLLIB_PS_DISABLED) { if (priv->rtllib->SetFwCmdHandler) @@ -225,17 +225,17 @@ void rtl92e_leisure_ps_enter(struct net_device *dev) RTLLIB_PS_UNICAST); } } else - pPSC->LpsIdleCount++; + psc->LpsIdleCount++; } } void rtl92e_leisure_ps_leave(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) &priv->rtllib->pwr_save_ctrl; - if (pPSC->bLeisurePs) { + if (psc->bLeisurePs) { if (priv->rtllib->ps != RTLLIB_PS_DISABLED) { _rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED); if (priv->rtllib->SetFwCmdHandler) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index d68f8f5902c8d..b200d53c8e3d2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -159,7 +159,7 @@ static int _rtl92e_wx_adapter_power_status(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); struct rtllib_device *ieee = priv->rtllib; @@ -167,13 +167,13 @@ static int _rtl92e_wx_adapter_power_status(struct net_device *dev, if (*extra || priv->force_lps) { priv->ps_force = false; - pPSC->bLeisurePs = true; + psc->bLeisurePs = true; } else { if (priv->rtllib->state == RTLLIB_LINKED) rtl92e_leisure_ps_leave(dev); priv->ps_force = true; - pPSC->bLeisurePs = false; + psc->bLeisurePs = false; ieee->ps = *extra; } @@ -188,7 +188,7 @@ static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev, char *extra) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) (&priv->rtllib->pwr_save_ctrl); mutex_lock(&priv->wx_mutex); @@ -196,7 +196,7 @@ static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev, netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n", __func__, *extra); - pPSC->reg_max_lps_awake_intvl = *extra; + psc->reg_max_lps_awake_intvl = *extra; mutex_unlock(&priv->wx_mutex); return 0; } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 487aa337eafa4..6b7b2c887c347 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -111,11 +111,11 @@ static inline void *netdev_priv_rsl(struct net_device *dev) #define SUPPORT_CKIP_MIC 0x08 #define SUPPORT_CKIP_PK 0x10 #define RT_RF_OFF_LEVL_HALT_NIC BIT3 -#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) \ - ((pPSC->CurPsLevel & _PS_FLAG) ? true : false) -#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) \ - (pPSC->CurPsLevel &= (~(_PS_FLAG))) -#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG) +#define RT_IN_PS_LEVEL(psc, _PS_FLAG) \ + ((psc->CurPsLevel & _PS_FLAG) ? true : false) +#define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \ + (psc->CurPsLevel &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(psc, _PS_FLAG) (psc->CurPsLevel |= _PS_FLAG) /* defined for skb cb field */ /* At most 28 byte */ diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 09cc3b3068cc8..ee4173a6ade02 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1504,7 +1504,7 @@ static void rtllib_associate_complete_wq(void *data) container_of_work_rsl(data, struct rtllib_device, associate_complete_wq); - struct rt_pwr_save_ctrl *pPSC = &ieee->pwr_save_ctrl; + struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl; netdev_info(ieee->dev, "Associated successfully with %pM\n", ieee->current_network.bssid); @@ -1542,7 +1542,7 @@ static void rtllib_associate_complete_wq(void *data) ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; } - pPSC->LpsIdleCount = 0; + psc->LpsIdleCount = 0; ieee->link_change(ieee->dev); if (ieee->is_silent_reset) { @@ -1960,7 +1960,7 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) { int timeout; u8 dtim; - struct rt_pwr_save_ctrl *pPSC = &ieee->pwr_save_ctrl; + struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl; if (ieee->LPSDelayCnt) { ieee->LPSDelayCnt--; @@ -1990,21 +1990,21 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) if (time) { if (ieee->bAwakePktSent) { - pPSC->LPSAwakeIntvl = 1; + psc->LPSAwakeIntvl = 1; } else { u8 MaxPeriod = 1; - if (pPSC->LPSAwakeIntvl == 0) - pPSC->LPSAwakeIntvl = 1; - if (pPSC->reg_max_lps_awake_intvl == 0) + if (psc->LPSAwakeIntvl == 0) + psc->LPSAwakeIntvl = 1; + if (psc->reg_max_lps_awake_intvl == 0) MaxPeriod = 1; - else if (pPSC->reg_max_lps_awake_intvl == 0xFF) + else if (psc->reg_max_lps_awake_intvl == 0xFF) MaxPeriod = ieee->current_network.dtim_period; else - MaxPeriod = pPSC->reg_max_lps_awake_intvl; - pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= + MaxPeriod = psc->reg_max_lps_awake_intvl; + psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : - (pPSC->LPSAwakeIntvl + 1); + (psc->LPSAwakeIntvl + 1); } { u8 LPSAwakeIntvl_tmp = 0; @@ -2012,23 +2012,23 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) u8 count = ieee->current_network.tim.tim_count; if (count == 0) { - if (pPSC->LPSAwakeIntvl > period) + if (psc->LPSAwakeIntvl > period) LPSAwakeIntvl_tmp = period + - (pPSC->LPSAwakeIntvl - + (psc->LPSAwakeIntvl - period) - - ((pPSC->LPSAwakeIntvl-period) % + ((psc->LPSAwakeIntvl-period) % period); else - LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl; } else { - if (pPSC->LPSAwakeIntvl > + if (psc->LPSAwakeIntvl > ieee->current_network.tim.tim_count) LPSAwakeIntvl_tmp = count + - (pPSC->LPSAwakeIntvl - count) - - ((pPSC->LPSAwakeIntvl-count)%period); + (psc->LPSAwakeIntvl - count) - + ((psc->LPSAwakeIntvl-count)%period); else - LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl; } *time = ieee->current_network.last_dtim_sta_time -- GitLab From ab4bcf795e46de03772c583e5180dfaa67eb0293 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:43 +0100 Subject: [PATCH 0591/1480] staging: rtl8192e: Rename RFInProgres.., bEnableHT and RegChannelPlan Rename variable RFInProgressTimeOut to rf_in_progress_timeout, bEnableHT to enable_ht and RegChannelPlan to reg_chnl_plan to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/aa3b8fd4a51fc9b1c32566cd079590bf11a9190d.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 4 ++-- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 12 ++++++------ drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 +- drivers/staging/rtl8192e/rtl819x_HT.h | 2 +- drivers/staging/rtl8192e/rtl819x_HTProc.c | 4 ++-- drivers/staging/rtl8192e/rtllib_softmac.c | 14 +++++++------- drivers/staging/rtl8192e/rtllib_softmac_wx.c | 2 +- drivers/staging/rtl8192e/rtllib_tx.c | 8 ++++---- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index bbaf20fbfde05..d0ce898370737 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -474,10 +474,10 @@ static void _rtl92e_read_eeprom_info(struct net_device *dev) priv->rf_chip = RF_8256; - if (priv->RegChannelPlan == 0xf) + if (priv->reg_chnl_plan == 0xf) priv->ChannelPlan = priv->eeprom_ChannelPlan; else - priv->ChannelPlan = priv->RegChannelPlan; + priv->ChannelPlan = priv->reg_chnl_plan; if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) priv->CustomerID = RT_CID_DLINK; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 144bc7c9abd52..1bf5e760d87ae 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -672,9 +672,9 @@ void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G)) { - priv->rtllib->pHTInfo->bEnableHT = 1; + priv->rtllib->pHTInfo->enable_ht = 1; } else { - priv->rtllib->pHTInfo->bEnableHT = 0; + priv->rtllib->pHTInfo->enable_ht = 0; } _rtl92e_refresh_support_rate(priv); } @@ -723,7 +723,7 @@ static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) { struct r8192_priv *priv = rtllib_priv(dev); unsigned long flags = 0; - u8 RFInProgressTimeOut = 0; + u8 rf_in_progress_timeout = 0; if (priv->up == 0) return -1; @@ -755,12 +755,12 @@ static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) spin_lock_irqsave(&priv->rf_ps_lock, flags); while (priv->rf_change_in_progress) { spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - if (RFInProgressTimeOut > 100) { + if (rf_in_progress_timeout > 100) { spin_lock_irqsave(&priv->rf_ps_lock, flags); break; } mdelay(1); - RFInProgressTimeOut++; + rf_in_progress_timeout++; spin_lock_irqsave(&priv->rf_ps_lock, flags); } priv->rf_change_in_progress = true; @@ -845,7 +845,7 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rxringcount = MAX_RX_COUNT; priv->irq_enabled = 0; priv->chan = 1; - priv->RegChannelPlan = 0xf; + priv->reg_chnl_plan = 0xf; priv->rtllib->mode = WIRELESS_MODE_AUTO; priv->rtllib->iw_mode = IW_MODE_INFRA; priv->rtllib->bNetPromiscuousMode = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 1ae3c77e2fefc..98c750730f871 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -467,7 +467,7 @@ struct r8192_priv { bool bTXPowerDataReadFromEEPORM; - u16 RegChannelPlan; + u16 reg_chnl_plan; u16 ChannelPlan; u8 bHwRfOffAction; diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h index 76bc9c5a6d83d..22e4f126ed565 100644 --- a/drivers/staging/rtl8192e/rtl819x_HT.h +++ b/drivers/staging/rtl8192e/rtl819x_HT.h @@ -96,7 +96,7 @@ enum ht_aggre_mode { struct rt_hi_throughput { - u8 bEnableHT; + u8 enable_ht; u8 bCurrentHTSupport; u8 bRegBW40MHz; diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 2092ebf717a1f..2c4c1cb4cbed2 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -690,7 +690,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; u8 bIOTAction = 0; - /* unmark bEnableHT flag here is the same reason why unmarked in + /* unmark enable_ht flag here is the same reason why unmarked in * function rtllib_softmac_new_net. WB 2008.09.10 */ if (pNetwork->bssht.bd_support_ht) { @@ -776,7 +776,7 @@ void HTUseDefaultSetting(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; - if (pHTInfo->bEnableHT) { + if (pHTInfo->enable_ht) { pHTInfo->bCurrentHTSupport = true; pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index ee4173a6ade02..ac8132d8c45ac 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1179,11 +1179,11 @@ rtllib_association_req(struct rtllib_network *beacon, if ((ieee->rtllib_ap_sec_type && (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) || ieee->bForcedBgMode) { - ieee->pHTInfo->bEnableHT = 0; + ieee->pHTInfo->enable_ht = 0; ieee->mode = WIRELESS_MODE_G; } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap); ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, @@ -1324,7 +1324,7 @@ rtllib_association_req(struct rtllib_network *beacon, memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length); tag += osCcxVerNum.Length; } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_HT_CAP; @@ -1358,7 +1358,7 @@ rtllib_association_req(struct rtllib_network *beacon, rtllib_TURBO_Info(ieee, &tag); } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_GENERIC; @@ -1524,14 +1524,14 @@ static void rtllib_associate_complete_wq(void *data) ieee->SetWirelessMode(ieee->dev, IEEE_B); netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate); } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { netdev_info(ieee->dev, "Successfully associated, ht enabled\n"); HTOnAssocRsp(ieee); } else { netdev_info(ieee->dev, "Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, - ieee->pHTInfo->bEnableHT); + ieee->pHTInfo->enable_ht); memset(ieee->dot11ht_oper_rate_set, 0, 16); } ieee->LinkDetectInfo.SlotNum = 2 * (1 + @@ -1684,7 +1684,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, ieee->current_network.ssid, ieee->current_network.channel, ieee->current_network.qos_data.supported, - ieee->pHTInfo->bEnableHT, + ieee->pHTInfo->enable_ht, ieee->current_network.bssht.bd_support_ht, ieee->current_network.mode, ieee->current_network.flags); diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index fdf867a5dd7a2..7bac30b87c93d 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -359,7 +359,7 @@ void rtllib_wx_sync_scan_wq(void *data) if (ieee->ScanOperationBackupHandler) ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht && ieee->pHTInfo->bCurBW40MHz) { b40M = 1; chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index be3779efcd233..8b01cfe033813 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -273,7 +273,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, if (rtllib_act_scanning(ieee, false)) return; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) return; if (!IsQoSDataFrame(skb->data)) return; @@ -354,7 +354,7 @@ static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee, tcb_desc->bUseShortGI = false; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) return; if (pHTInfo->forced_short_gi) { @@ -375,7 +375,7 @@ static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, tcb_desc->bPacketBW = false; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) return; if (tcb_desc->bMulticast || tcb_desc->bBroadcast) @@ -438,7 +438,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, tcb_desc->rts_rate = MGN_24M; break; } - if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { + if (pHTInfo->bCurrentHTSupport && pHTInfo->enable_ht) { u8 HTOpMode = pHTInfo->current_op_mode; if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || -- GitLab From 7e5cfa3c77d324fa235e94cc4363b14624ff2c45 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:49 +0100 Subject: [PATCH 0592/1480] staging: rtl8192e: Rename LinkDetectInfo Rename variable LinkDetectInfo to link_detect_info to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/48d043893fa755490e810af204e5b7ad2ba606de.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 58 ++++++++++---------- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 2 +- drivers/staging/rtl8192e/rtllib.h | 2 +- drivers/staging/rtl8192e/rtllib_rx.c | 14 ++--- drivers/staging/rtl8192e/rtllib_softmac.c | 26 ++++----- drivers/staging/rtl8192e/rtllib_softmac_wx.c | 8 +-- 6 files changed, 55 insertions(+), 55 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 1bf5e760d87ae..3379b4229a85f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1250,15 +1250,15 @@ static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, *TotalRxBcnNum = 0; *TotalRxDataNum = 0; - SlotIndex = (priv->rtllib->LinkDetectInfo.SlotIndex++) % - (priv->rtllib->LinkDetectInfo.SlotNum); - priv->rtllib->LinkDetectInfo.RxBcnNum[SlotIndex] = - priv->rtllib->LinkDetectInfo.NumRecvBcnInPeriod; - priv->rtllib->LinkDetectInfo.RxDataNum[SlotIndex] = - priv->rtllib->LinkDetectInfo.NumRecvDataInPeriod; - for (i = 0; i < priv->rtllib->LinkDetectInfo.SlotNum; i++) { - *TotalRxBcnNum += priv->rtllib->LinkDetectInfo.RxBcnNum[i]; - *TotalRxDataNum += priv->rtllib->LinkDetectInfo.RxDataNum[i]; + SlotIndex = (priv->rtllib->link_detect_info.SlotIndex++) % + (priv->rtllib->link_detect_info.SlotNum); + priv->rtllib->link_detect_info.RxBcnNum[SlotIndex] = + priv->rtllib->link_detect_info.NumRecvBcnInPeriod; + priv->rtllib->link_detect_info.RxDataNum[SlotIndex] = + priv->rtllib->link_detect_info.NumRecvDataInPeriod; + for (i = 0; i < priv->rtllib->link_detect_info.SlotNum; i++) { + *TotalRxBcnNum += priv->rtllib->link_detect_info.RxBcnNum[i]; + *TotalRxDataNum += priv->rtllib->link_detect_info.RxDataNum[i]; } } @@ -1304,22 +1304,22 @@ static void _rtl92e_watchdog_wq_cb(void *data) } if ((ieee->state == RTLLIB_LINKED) && (ieee->iw_mode == IW_MODE_INFRA) && (!ieee->bNetPromiscuousMode)) { - if (ieee->LinkDetectInfo.NumRxOkInPeriod > 100 || - ieee->LinkDetectInfo.NumTxOkInPeriod > 100) + if (ieee->link_detect_info.NumRxOkInPeriod > 100 || + ieee->link_detect_info.NumTxOkInPeriod > 100) bBusyTraffic = true; - if (ieee->LinkDetectInfo.NumRxOkInPeriod > 4000 || - ieee->LinkDetectInfo.NumTxOkInPeriod > 4000) { + if (ieee->link_detect_info.NumRxOkInPeriod > 4000 || + ieee->link_detect_info.NumTxOkInPeriod > 4000) { bHigherBusyTraffic = true; - if (ieee->LinkDetectInfo.NumRxOkInPeriod > 5000) + if (ieee->link_detect_info.NumRxOkInPeriod > 5000) bHigherBusyRxTraffic = true; else bHigherBusyRxTraffic = false; } - if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + - ieee->LinkDetectInfo.NumTxOkInPeriod) > 8) || - (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) + if (((ieee->link_detect_info.NumRxUnicastOkInPeriod + + ieee->link_detect_info.NumTxOkInPeriod) > 8) || + (ieee->link_detect_info.NumRxUnicastOkInPeriod > 2)) bEnterPS = false; else bEnterPS = true; @@ -1336,13 +1336,13 @@ static void _rtl92e_watchdog_wq_cb(void *data) rtl92e_leisure_ps_leave(dev); } - ieee->LinkDetectInfo.NumRxOkInPeriod = 0; - ieee->LinkDetectInfo.NumTxOkInPeriod = 0; - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; - ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + ieee->link_detect_info.NumRxOkInPeriod = 0; + ieee->link_detect_info.NumTxOkInPeriod = 0; + ieee->link_detect_info.NumRxUnicastOkInPeriod = 0; + ieee->link_detect_info.bBusyTraffic = bBusyTraffic; - ieee->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; - ieee->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; + ieee->link_detect_info.bHigherBusyTraffic = bHigherBusyTraffic; + ieee->link_detect_info.bHigherBusyRxTraffic = bHigherBusyRxTraffic; if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == IW_MODE_INFRA) { u32 TotalRxBcnNum = 0; @@ -1383,8 +1383,8 @@ static void _rtl92e_watchdog_wq_cb(void *data) priv->check_roaming_cnt = 0; } - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; + ieee->link_detect_info.NumRecvBcnInPeriod = 0; + ieee->link_detect_info.NumRecvDataInPeriod = 0; } spin_lock_irqsave(&priv->tx_lock, flags); @@ -2213,25 +2213,25 @@ static irqreturn_t _rtl92e_irq(int irq, void *netdev) if (inta & IMR_BKDOK) { priv->stats.txbkokint++; - priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + priv->rtllib->link_detect_info.NumTxOkInPeriod++; _rtl92e_tx_isr(dev, BK_QUEUE); } if (inta & IMR_BEDOK) { priv->stats.txbeokint++; - priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + priv->rtllib->link_detect_info.NumTxOkInPeriod++; _rtl92e_tx_isr(dev, BE_QUEUE); } if (inta & IMR_VIDOK) { priv->stats.txviokint++; - priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + priv->rtllib->link_detect_info.NumTxOkInPeriod++; _rtl92e_tx_isr(dev, VI_QUEUE); } if (inta & IMR_VODOK) { priv->stats.txvookint++; - priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + priv->rtllib->link_detect_info.NumTxOkInPeriod++; _rtl92e_tx_isr(dev, VO_QUEUE); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index b200d53c8e3d2..4f16c3d079cc0 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -393,7 +393,7 @@ static int _rtl92e_wx_set_scan(struct net_device *dev, rt_state = priv->rtllib->rf_power_state; if (!priv->up) return -ENETDOWN; - if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true) + if (priv->rtllib->link_detect_info.bBusyTraffic == true) return -EAGAIN; if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 6b7b2c887c347..b5313c1ea32d9 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1643,7 +1643,7 @@ struct rtllib_device { struct bandwidth_autoswitch bandwidth_auto_switch; bool FwRWRF; - struct rt_link_detect LinkDetectInfo; + struct rt_link_detect link_detect_info; bool bIsAggregateFrame; struct rt_pwr_save_ctrl pwr_save_ctrl; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 46d75e925ee9b..f9a35fcb1d1b2 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1211,9 +1211,9 @@ static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, if (unicast) { if (ieee->state == RTLLIB_LINKED) { - if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + - ieee->LinkDetectInfo.NumTxOkInPeriod) > 8) || - (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { + if (((ieee->link_detect_info.NumRxUnicastOkInPeriod + + ieee->link_detect_info.NumTxOkInPeriod) > 8) || + (ieee->link_detect_info.NumRxUnicastOkInPeriod > 2)) { if (ieee->LeisurePSLeave) ieee->LeisurePSLeave(ieee->dev); } @@ -1355,8 +1355,8 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Update statstics for AP roaming */ if (!bToOtherSTA) { - ieee->LinkDetectInfo.NumRecvDataInPeriod++; - ieee->LinkDetectInfo.NumRxOkInPeriod++; + ieee->link_detect_info.NumRecvDataInPeriod++; + ieee->link_detect_info.NumRxOkInPeriod++; } /* Data frame - extract src/dst addresses */ @@ -1437,7 +1437,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, else nr_subframes = 1; if (unicast) - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod += nr_subframes; + ieee->link_detect_info.NumRxUnicastOkInPeriod += nr_subframes; rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes); } @@ -2620,7 +2620,7 @@ static inline void rtllib_process_probe_response( } if (is_beacon(frame_ctl)) { if (ieee->state >= RTLLIB_LINKED) - ieee->LinkDetectInfo.NumRecvBcnInPeriod++; + ieee->link_detect_info.NumRecvBcnInPeriod++; } } list_for_each_entry(target, &ieee->network_list, list) { diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index ac8132d8c45ac..1d583e73d7533 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1534,13 +1534,13 @@ static void rtllib_associate_complete_wq(void *data) ieee->pHTInfo->enable_ht); memset(ieee->dot11ht_oper_rate_set, 0, 16); } - ieee->LinkDetectInfo.SlotNum = 2 * (1 + + ieee->link_detect_info.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500); - if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || - ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; + if (ieee->link_detect_info.NumRecvBcnInPeriod == 0 || + ieee->link_detect_info.NumRecvDataInPeriod == 0) { + ieee->link_detect_info.NumRecvBcnInPeriod = 1; + ieee->link_detect_info.NumRecvDataInPeriod = 1; } psc->LpsIdleCount = 0; ieee->link_change(ieee->dev); @@ -2369,7 +2369,7 @@ rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb) ieee->state = RTLLIB_ASSOCIATING; ieee->softmac_stats.reassoc++; ieee->is_roaming = true; - ieee->LinkDetectInfo.bBusyTraffic = false; + ieee->link_detect_info.bBusyTraffic = false; rtllib_disassociate(ieee); RemovePeerTS(ieee, header->addr2); if (ieee->LedControlHandler != NULL) @@ -2963,13 +2963,13 @@ int rtllib_softmac_init(struct rtllib_device *ieee) if (!ieee->dot11d_info) return -ENOMEM; - ieee->LinkDetectInfo.SlotIndex = 0; - ieee->LinkDetectInfo.SlotNum = 2; - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; - ieee->LinkDetectInfo.NumTxOkInPeriod = 0; - ieee->LinkDetectInfo.NumRxOkInPeriod = 0; - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; + ieee->link_detect_info.SlotIndex = 0; + ieee->link_detect_info.SlotNum = 2; + ieee->link_detect_info.NumRecvBcnInPeriod = 0; + ieee->link_detect_info.NumRecvDataInPeriod = 0; + ieee->link_detect_info.NumTxOkInPeriod = 0; + ieee->link_detect_info.NumRxOkInPeriod = 0; + ieee->link_detect_info.NumRxUnicastOkInPeriod = 0; ieee->bIsAggregateFrame = false; ieee->assoc_id = 0; ieee->queue_stop = 0; diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 7bac30b87c93d..e02e7d9566b24 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -391,10 +391,10 @@ void rtllib_wx_sync_scan_wq(void *data) /* Notify AP that I wake up again */ rtllib_sta_ps_send_null_frame(ieee, 0); - if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || - ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; + if (ieee->link_detect_info.NumRecvBcnInPeriod == 0 || + ieee->link_detect_info.NumRecvDataInPeriod == 0) { + ieee->link_detect_info.NumRecvBcnInPeriod = 1; + ieee->link_detect_info.NumRecvDataInPeriod = 1; } if (ieee->data_hard_resume) -- GitLab From 8e5d08ceb8db933bdb1f60772984ffc166d2eb55 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:35:55 +0100 Subject: [PATCH 0593/1480] staging: rtl8192e: Rename bNetPromisc.., IntelPromiscu.. and bPromiscu.. Rename variable bNetPromiscuousMode to net_promiscuous_md, IntelPromiscuousModeInfo to intel_promiscuous_md_info and bPromiscuousOn to promiscuous_on to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/69d9998a30ce2286c3ae6cb4510174e1255b3f9e.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 2 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 10 +++++----- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 20 +++++++++---------- drivers/staging/rtl8192e/rtllib.h | 6 +++--- drivers/staging/rtl8192e/rtllib_rx.c | 8 ++++---- drivers/staging/rtl8192e/rtllib_softmac.c | 4 ++-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index d0ce898370737..2ccd1e0542c24 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -859,7 +859,7 @@ void rtl92e_link_change(struct net_device *dev) reg = rtl92e_readl(dev, RCR); if (priv->rtllib->state == RTLLIB_LINKED) { - if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn) + if (ieee->intel_promiscuous_md_info.promiscuous_on) ; else priv->ReceiveConfig = reg |= RCR_CBSSID; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 3379b4229a85f..94b8ed2e3489d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -848,9 +848,9 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->reg_chnl_plan = 0xf; priv->rtllib->mode = WIRELESS_MODE_AUTO; priv->rtllib->iw_mode = IW_MODE_INFRA; - priv->rtllib->bNetPromiscuousMode = false; - priv->rtllib->IntelPromiscuousModeInfo.bPromiscuousOn = false; - priv->rtllib->IntelPromiscuousModeInfo.bFilterSourceStationFrame = + priv->rtllib->net_promiscuous_md = false; + priv->rtllib->intel_promiscuous_md_info.promiscuous_on = false; + priv->rtllib->intel_promiscuous_md_info.bFilterSourceStationFrame = false; priv->rtllib->ieee_up = 0; priv->retry_rts = DEFAULT_RETRY_RTS; @@ -1297,13 +1297,13 @@ static void _rtl92e_watchdog_wq_cb(void *data) (!ieee->proto_stoppping) && !ieee->wx_set_enc) { if ((ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE) && - (!ieee->bNetPromiscuousMode)) { + (!ieee->net_promiscuous_md)) { rtl92e_ips_enter(dev); } } } if ((ieee->state == RTLLIB_LINKED) && (ieee->iw_mode == - IW_MODE_INFRA) && (!ieee->bNetPromiscuousMode)) { + IW_MODE_INFRA) && (!ieee->net_promiscuous_md)) { if (ieee->link_detect_info.NumRxOkInPeriod > 100 || ieee->link_detect_info.NumTxOkInPeriod > 100) bBusyTraffic = true; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 4f16c3d079cc0..c31e5b572e9e2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -251,7 +251,7 @@ static int _rtl92e_wx_set_mode(struct net_device *dev, rt_state = priv->rtllib->rf_power_state; mutex_lock(&priv->wx_mutex); if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR || - ieee->bNetPromiscuousMode) { + ieee->net_promiscuous_md) { if (rt_state == rf_off) { if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { @@ -1014,28 +1014,28 @@ static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, u32 info_buf[3]; u32 oid; - u32 bPromiscuousOn; + u32 promiscuous_on; u32 bFilterSourceStationFrame; if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf))) return -EFAULT; oid = info_buf[0]; - bPromiscuousOn = info_buf[1]; + promiscuous_on = info_buf[1]; bFilterSourceStationFrame = info_buf[2]; if (oid == OID_RT_INTEL_PROMISCUOUS_MODE) { - ieee->IntelPromiscuousModeInfo.bPromiscuousOn = - (bPromiscuousOn) ? (true) : (false); - ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame = + ieee->intel_promiscuous_md_info.promiscuous_on = + (promiscuous_on) ? (true) : (false); + ieee->intel_promiscuous_md_info.bFilterSourceStationFrame = (bFilterSourceStationFrame) ? (true) : (false); - (bPromiscuousOn) ? + (promiscuous_on) ? (rtllib_EnableIntelPromiscuousMode(dev, false)) : (rtllib_DisableIntelPromiscuousMode(dev, false)); netdev_info(dev, "=======>%s(), on = %d, filter src sta = %d\n", - __func__, bPromiscuousOn, + __func__, promiscuous_on, bFilterSourceStationFrame); } else { return -1; @@ -1054,8 +1054,8 @@ static int _rtl92e_wx_get_promisc_mode(struct net_device *dev, mutex_lock(&priv->wx_mutex); snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d", - ieee->IntelPromiscuousModeInfo.bPromiscuousOn, - ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame); + ieee->intel_promiscuous_md_info.promiscuous_on, + ieee->intel_promiscuous_md_info.bFilterSourceStationFrame); wrqu->data.length = strlen(extra) + 1; mutex_unlock(&priv->wx_mutex); diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index b5313c1ea32d9..493759cc6ccf1 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1384,7 +1384,7 @@ struct rt_pmkid_list { }; struct rt_intel_promisc_mode { - bool bPromiscuousOn; + bool promiscuous_on; bool bFilterSourceStationFrame; }; @@ -1470,8 +1470,8 @@ struct rtllib_device { int scan_age; int iw_mode; /* operating mode (IW_MODE_*) */ - bool bNetPromiscuousMode; - struct rt_intel_promisc_mode IntelPromiscuousModeInfo; + bool net_promiscuous_md; + struct rt_intel_promisc_mode intel_promiscuous_md_info; spinlock_t lock; spinlock_t wpax_suitlist_lock; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index f9a35fcb1d1b2..ccb61d8decd3c 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -999,8 +999,8 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, } /* Filter packets sent by an STA that will be forwarded by AP */ - if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn && - ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame) { + if (ieee->intel_promiscuous_md_info.promiscuous_on && + ieee->intel_promiscuous_md_info.bFilterSourceStationFrame) { if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) && !ether_addr_equal(dst, ieee->current_network.bssid) && ether_addr_equal(bssid, ieee->current_network.bssid)) { @@ -1011,7 +1011,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, /* Nullfunc frames may have PS-bit set, so they must be passed to * hostap_handle_sta_rx() before being dropped here. */ - if (!ieee->IntelPromiscuousModeInfo.bPromiscuousOn) { + if (!ieee->intel_promiscuous_md_info.promiscuous_on) { if (stype != RTLLIB_STYPE_DATA && stype != RTLLIB_STYPE_DATA_CFACK && stype != RTLLIB_STYPE_DATA_CFPOLL && @@ -1317,7 +1317,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, multicast = is_multicast_ether_addr(hdr->addr1); unicast = !multicast; if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) { - if (ieee->bNetPromiscuousMode) + if (ieee->net_promiscuous_md) bToOtherSTA = true; else goto rx_dropped; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 1d583e73d7533..8b1d88061125a 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -445,7 +445,7 @@ void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, (u8 *)&bFilterOutNonAssociatedBSSID); - ieee->bNetPromiscuousMode = true; + ieee->net_promiscuous_md = true; } EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode); @@ -466,7 +466,7 @@ void rtllib_DisableIntelPromiscuousMode(struct net_device *dev, ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, (u8 *)&bFilterOutNonAssociatedBSSID); - ieee->bNetPromiscuousMode = false; + ieee->net_promiscuous_md = false; } EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode); -- GitLab From 62310f889a73ea2089f31209a426307887435e86 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:36:02 +0100 Subject: [PATCH 0594/1480] staging: rtl8192e: Rename bFilterSour.., CCKPresentAt.. and ResetProg.. Rename variable bFilterSourceStationFrame to fltr_src_sta_frame, CCKPresentAttentuation to cck_present_attn and ResetProgress to rst_progress to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/25ab52350a4a3249a1f76b28eea10c44e2f9552d.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 12 +++++------ .../staging/rtl8192e/rtl8192e/r8192E_phy.c | 20 +++++++++---------- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 14 ++++++------- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 4 ++-- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 20 +++++++++---------- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 12 +++++------ drivers/staging/rtl8192e/rtllib.h | 2 +- drivers/staging/rtl8192e/rtllib_rx.c | 2 +- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 2ccd1e0542c24..0eeb9b2daefce 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -617,7 +617,7 @@ bool rtl92e_start_adapter(struct net_device *dev) start: rtl92e_reset_desc_ring(dev); priv->Rf_Mode = RF_OP_By_SW_3wire; - if (priv->ResetProgress == RESET_TYPE_NORESET) { + if (priv->rst_progress == RESET_TYPE_NORESET) { rtl92e_writeb(dev, ANAPAR, 0x37); mdelay(500); } @@ -650,7 +650,7 @@ start: } priv->LoopbackMode = RTL819X_NO_LOOPBACK; - if (priv->ResetProgress == RESET_TYPE_NORESET) { + if (priv->rst_progress == RESET_TYPE_NORESET) { ulRegRead = rtl92e_readl(dev, CPU_GEN); if (priv->LoopbackMode == RTL819X_NO_LOOPBACK) ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | @@ -699,7 +699,7 @@ start: rtl92e_writeb(dev, ACK_TIMEOUT, 0x30); - if (priv->ResetProgress == RESET_TYPE_NORESET) + if (priv->rst_progress == RESET_TYPE_NORESET) rtl92e_set_wireless_mode(dev, priv->rtllib->mode); rtl92e_cam_reset(dev); { @@ -739,7 +739,7 @@ start: } } - if (priv->ResetProgress == RESET_TYPE_NORESET) { + if (priv->rst_progress == RESET_TYPE_NORESET) { rtStatus = rtl92e_config_phy(dev); if (!rtStatus) { netdev_info(dev, "RF Config failed\n"); @@ -766,7 +766,7 @@ start: else priv->Rf_Mode = RF_OP_By_SW_3wire; - if (priv->ResetProgress == RESET_TYPE_NORESET) { + if (priv->rst_progress == RESET_TYPE_NORESET) { rtl92e_dm_init_txpower_tracking(dev); if (priv->IC_Cut >= IC_VersionCut_D) { @@ -795,7 +795,7 @@ start: } priv->CCKPresentAttentuation_40Mdefault = 0; priv->CCKPresentAttentuation_difference = 0; - priv->CCKPresentAttentuation = + priv->cck_present_attn = priv->CCKPresentAttentuation_20Mdefault; priv->btxpower_tracking = false; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index c357adf95a3d0..ac3c7f047ca2d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -1008,16 +1008,16 @@ static void _rtl92e_cck_tx_power_track_bw_switch_tssi(struct net_device *dev) switch (priv->CurrentChannelBW) { case HT_CHANNEL_WIDTH_20: - priv->CCKPresentAttentuation = + priv->cck_present_attn = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; - if (priv->CCKPresentAttentuation > + if (priv->cck_present_attn > (CCKTxBBGainTableLength-1)) - priv->CCKPresentAttentuation = + priv->cck_present_attn = CCKTxBBGainTableLength-1; - if (priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; + if (priv->cck_present_attn < 0) + priv->cck_present_attn = 0; if (priv->rtllib->current_network.channel == 14 && !priv->bcck_in_ch14) { @@ -1033,16 +1033,16 @@ static void _rtl92e_cck_tx_power_track_bw_switch_tssi(struct net_device *dev) break; case HT_CHANNEL_WIDTH_20_40: - priv->CCKPresentAttentuation = + priv->cck_present_attn = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; - if (priv->CCKPresentAttentuation > + if (priv->cck_present_attn > (CCKTxBBGainTableLength - 1)) - priv->CCKPresentAttentuation = + priv->cck_present_attn = CCKTxBBGainTableLength-1; - if (priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; + if (priv->cck_present_attn < 0) + priv->cck_present_attn = 0; if (priv->rtllib->current_network.channel == 14 && !priv->bcck_in_ch14) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 94b8ed2e3489d..1c4985dcc5eb1 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -850,7 +850,7 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rtllib->iw_mode = IW_MODE_INFRA; priv->rtllib->net_promiscuous_md = false; priv->rtllib->intel_promiscuous_md_info.promiscuous_on = false; - priv->rtllib->intel_promiscuous_md_info.bFilterSourceStationFrame = + priv->rtllib->intel_promiscuous_md_info.fltr_src_sta_frame = false; priv->rtllib->ieee_up = 0; priv->retry_rts = DEFAULT_RETRY_RTS; @@ -861,11 +861,11 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; priv->bcck_in_ch14 = false; priv->bfsync_processing = false; - priv->CCKPresentAttentuation = 0; + priv->cck_present_attn = 0; priv->rfa_txpowertrackingindex = 0; priv->rfc_txpowertrackingindex = 0; priv->CckPwEnl = 6; - priv->ResetProgress = RESET_TYPE_NORESET; + priv->rst_progress = RESET_TYPE_NORESET; priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); @@ -1135,8 +1135,8 @@ static void _rtl92e_if_silent_reset(struct net_device *dev) struct rtllib_device *ieee = priv->rtllib; unsigned long flag; - if (priv->ResetProgress == RESET_TYPE_NORESET) { - priv->ResetProgress = RESET_TYPE_SILENT; + if (priv->rst_progress == RESET_TYPE_NORESET) { + priv->rst_progress = RESET_TYPE_SILENT; spin_lock_irqsave(&priv->rf_ps_lock, flag); if (priv->rf_change_in_progress) { @@ -1233,7 +1233,7 @@ RESET_START: rtl92e_cam_restore(dev); rtl92e_dm_restore_state(dev); END: - priv->ResetProgress = RESET_TYPE_NORESET; + priv->rst_progress = RESET_TYPE_NORESET; priv->reset_count++; priv->bResetInProgress = false; @@ -1396,7 +1396,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) spin_unlock_irqrestore(&priv->tx_lock, flags); if (ResetType == RESET_TYPE_NORMAL) { - priv->ResetProgress = RESET_TYPE_NORMAL; + priv->rst_progress = RESET_TYPE_NORMAL; return; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 98c750730f871..dfbc9fbcc1297 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -483,7 +483,7 @@ struct r8192_priv { u8 CCKPresentAttentuation_20Mdefault; u8 CCKPresentAttentuation_40Mdefault; s8 CCKPresentAttentuation_difference; - s8 CCKPresentAttentuation; + s8 cck_present_attn; long undecorated_smoothed_pwdb; u32 MCSTxPowerLevelOriginalOffset[6]; @@ -536,7 +536,7 @@ struct r8192_priv { u32 reset_count; - enum reset_type ResetProgress; + enum reset_type rst_progress; u16 TxCounter; u16 RxCounter; bool bResetInProgress; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 767c746fc73d9..234e85a25d459 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -267,7 +267,7 @@ static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev) "PATH=/usr/bin:/bin", NULL}; - if (priv->ResetProgress == RESET_TYPE_SILENT) + if (priv->rst_progress == RESET_TYPE_SILENT) return; if (priv->rtllib->state != RTLLIB_LINKED) return; @@ -716,21 +716,21 @@ static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) } if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) - priv->CCKPresentAttentuation = + priv->cck_present_attn = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; else - priv->CCKPresentAttentuation = + priv->cck_present_attn = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; - if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) - priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; - if (priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; + if (priv->cck_present_attn > (CCKTxBBGainTableLength-1)) + priv->cck_present_attn = CCKTxBBGainTableLength-1; + if (priv->cck_present_attn < 0) + priv->cck_present_attn = 0; - if (priv->CCKPresentAttentuation > -1 && - priv->CCKPresentAttentuation < CCKTxBBGainTableLength) { + if (priv->cck_present_attn > -1 && + priv->cck_present_attn < CCKTxBBGainTableLength) { if (priv->rtllib->current_network.channel == 14 && !priv->bcck_in_ch14) { priv->bcck_in_ch14 = true; @@ -963,7 +963,7 @@ static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev, { u32 TempVal; struct r8192_priv *priv = rtllib_priv(dev); - u8 attenuation = priv->CCKPresentAttentuation; + u8 attenuation = priv->cck_present_attn; TempVal = 0; if (!bInCH14) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index c31e5b572e9e2..7ff14aa9f4762 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -1015,20 +1015,20 @@ static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, u32 oid; u32 promiscuous_on; - u32 bFilterSourceStationFrame; + u32 fltr_src_sta_frame; if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf))) return -EFAULT; oid = info_buf[0]; promiscuous_on = info_buf[1]; - bFilterSourceStationFrame = info_buf[2]; + fltr_src_sta_frame = info_buf[2]; if (oid == OID_RT_INTEL_PROMISCUOUS_MODE) { ieee->intel_promiscuous_md_info.promiscuous_on = (promiscuous_on) ? (true) : (false); - ieee->intel_promiscuous_md_info.bFilterSourceStationFrame = - (bFilterSourceStationFrame) ? (true) : (false); + ieee->intel_promiscuous_md_info.fltr_src_sta_frame = + (fltr_src_sta_frame) ? (true) : (false); (promiscuous_on) ? (rtllib_EnableIntelPromiscuousMode(dev, false)) : (rtllib_DisableIntelPromiscuousMode(dev, false)); @@ -1036,7 +1036,7 @@ static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, netdev_info(dev, "=======>%s(), on = %d, filter src sta = %d\n", __func__, promiscuous_on, - bFilterSourceStationFrame); + fltr_src_sta_frame); } else { return -1; } @@ -1055,7 +1055,7 @@ static int _rtl92e_wx_get_promisc_mode(struct net_device *dev, snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d", ieee->intel_promiscuous_md_info.promiscuous_on, - ieee->intel_promiscuous_md_info.bFilterSourceStationFrame); + ieee->intel_promiscuous_md_info.fltr_src_sta_frame); wrqu->data.length = strlen(extra) + 1; mutex_unlock(&priv->wx_mutex); diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 493759cc6ccf1..9c81ca38f4b1d 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1385,7 +1385,7 @@ struct rt_pmkid_list { struct rt_intel_promisc_mode { bool promiscuous_on; - bool bFilterSourceStationFrame; + bool fltr_src_sta_frame; }; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index ccb61d8decd3c..75190c389ccf1 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1000,7 +1000,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, /* Filter packets sent by an STA that will be forwarded by AP */ if (ieee->intel_promiscuous_md_info.promiscuous_on && - ieee->intel_promiscuous_md_info.bFilterSourceStationFrame) { + ieee->intel_promiscuous_md_info.fltr_src_sta_frame) { if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) && !ether_addr_equal(dst, ieee->current_network.bssid) && ether_addr_equal(bssid, ieee->current_network.bssid)) { -- GitLab From 41fa3d42a3210f09771a10d4e30896c6e3062a82 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:36:09 +0100 Subject: [PATCH 0595/1480] staging: rtl8192e: Rename InterruptLog, RxCounter and bHwRfOffAction Rename variable InterruptLog to int_log, RxCounter to rx_ctr and bHwRfOffAction to hw_rf_off_action to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/82ea07ddd894ac9b863ce90ddb9ba78065bd1f4e.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 6 +++--- drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c | 4 ++-- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 8 ++++---- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 6 +++--- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 0eeb9b2daefce..e530f917fd231 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1928,7 +1928,7 @@ void rtl92e_stop_adapter(struct net_device *dev, bool reset) if (!reset) { mdelay(150); - priv->bHwRfOffAction = 2; + priv->hw_rf_off_action = 2; if (!priv->rtllib->bSupportRemoteWakeUp) { rtl92e_set_rf_off(dev); @@ -2129,7 +2129,7 @@ bool rtl92e_is_rx_stuck(struct net_device *dev) SlotIndex = (priv->SilentResetRxSlotIndex++)%SilentResetRxSoltNum; - if (priv->RxCounter == RegRxCounter) { + if (priv->rx_ctr == RegRxCounter) { priv->SilentResetRxStuckEvent[SlotIndex] = 1; for (i = 0; i < SilentResetRxSoltNum; i++) @@ -2147,7 +2147,7 @@ bool rtl92e_is_rx_stuck(struct net_device *dev) priv->SilentResetRxStuckEvent[SlotIndex] = 0; } - priv->RxCounter = RegRxCounter; + priv->rx_ctr = RegRxCounter; return bStuck; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index ac3c7f047ca2d..a813eded4cb3f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -1342,7 +1342,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, mdelay(1); rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); - priv->bHwRfOffAction = 0; + priv->hw_rf_off_action = 0; rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); @@ -1450,7 +1450,7 @@ bool rtl92e_set_rf_power_state(struct net_device *dev, bool bResult = false; if (rf_power_state == priv->rtllib->rf_power_state && - priv->bHwRfOffAction == 0) { + priv->hw_rf_off_action == 0) { return bResult; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 1c4985dcc5eb1..43601ec8d9032 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -869,13 +869,13 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); - memset(&priv->InterruptLog, 0, sizeof(struct log_int_8190)); - priv->RxCounter = 0; + memset(&priv->int_log, 0, sizeof(struct log_int_8190)); + priv->rx_ctr = 0; priv->rtllib->wx_set_enc = 0; priv->hw_radio_off = false; priv->rtllib->rf_off_reason = 0; priv->rf_change_in_progress = false; - priv->bHwRfOffAction = 0; + priv->hw_rf_off_action = 0; priv->SetRFPowerStateInProgress = false; priv->rtllib->pwr_save_ctrl.bLeisurePs = true; priv->rtllib->LPSDelayCnt = 0; @@ -2189,7 +2189,7 @@ static irqreturn_t _rtl92e_irq(int irq, void *netdev) if (inta & IMR_ROK) { priv->stats.rxint++; - priv->InterruptLog.nIMR_ROK++; + priv->int_log.nIMR_ROK++; tasklet_schedule(&priv->irq_rx_tasklet); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index dfbc9fbcc1297..b1656d4ecbad6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -330,7 +330,7 @@ struct r8192_priv { struct work_struct reset_wq; - struct log_int_8190 InterruptLog; + struct log_int_8190 int_log; enum rt_customer_id CustomerID; @@ -469,7 +469,7 @@ struct r8192_priv { u16 reg_chnl_plan; u16 ChannelPlan; - u8 bHwRfOffAction; + u8 hw_rf_off_action; bool rf_change_in_progress; bool SetRFPowerStateInProgress; @@ -538,7 +538,7 @@ struct r8192_priv { enum reset_type rst_progress; u16 TxCounter; - u16 RxCounter; + u16 rx_ctr; bool bResetInProgress; bool force_reset; bool force_lps; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 234e85a25d459..e0f6f1405c17e 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -1693,7 +1693,7 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) if (bActuallySet) { mdelay(1000); - priv->bHwRfOffAction = 1; + priv->hw_rf_off_action = 1; rtl92e_set_rf_state(dev, rf_power_state_to_set, RF_CHANGE_BY_HW); if (priv->hw_radio_off) argv[1] = "RFOFF"; -- GitLab From ccdbe14b77a5e39496baf632e157f9daf322dd27 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Sun, 13 Nov 2022 05:36:15 +0100 Subject: [PATCH 0596/1480] staging: rtl8192e: Rename pHTInfo Rename variable pHTInfo to ht_info to avoid CamelCase which is not accepted by checkpatch. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/88cdc0ef393c92cb2102a66893c5320e8c8606df.1668313325.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 10 +- drivers/staging/rtl8192e/rtl8192e/rtl_cam.c | 2 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 12 +- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 50 +-- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 2 +- drivers/staging/rtl8192e/rtl819x_BAProc.c | 20 +- drivers/staging/rtl8192e/rtl819x_HTProc.c | 354 +++++++++--------- drivers/staging/rtl8192e/rtl819x_TSProc.c | 2 +- drivers/staging/rtl8192e/rtllib.h | 4 +- drivers/staging/rtl8192e/rtllib_module.c | 6 +- drivers/staging/rtl8192e/rtllib_rx.c | 12 +- drivers/staging/rtl8192e/rtllib_softmac.c | 78 ++-- drivers/staging/rtl8192e/rtllib_softmac_wx.c | 8 +- drivers/staging/rtl8192e/rtllib_tx.c | 54 +-- 14 files changed, 307 insertions(+), 307 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index e530f917fd231..b9c846015d286 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1978,7 +1978,7 @@ void rtl92e_update_ratr_table(struct net_device *dev) break; case IEEE_N_24G: case IEEE_N_5G: - if (ieee->pHTInfo->peer_mimo_ps == 0) { + if (ieee->ht_info->peer_mimo_ps == 0) { ratr_value &= 0x0007F007; } else { if (priv->rf_type == RF_1T2R) @@ -1991,11 +1991,11 @@ void rtl92e_update_ratr_table(struct net_device *dev) break; } ratr_value &= 0x0FFFFFFF; - if (ieee->pHTInfo->cur_tx_bw40mhz && - ieee->pHTInfo->bCurShortGI40MHz) + if (ieee->ht_info->cur_tx_bw40mhz && + ieee->ht_info->bCurShortGI40MHz) ratr_value |= 0x80000000; - else if (!ieee->pHTInfo->cur_tx_bw40mhz && - ieee->pHTInfo->bCurShortGI20MHz) + else if (!ieee->ht_info->cur_tx_bw40mhz && + ieee->ht_info->bCurShortGI20MHz) ratr_value |= 0x80000000; rtl92e_writel(dev, RATR0+rate_index*4, ratr_value); rtl92e_writeb(dev, UFWP, 1); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index 9d8d4837e6b20..a4d65b4d99c28 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -41,7 +41,7 @@ void rtl92e_enable_hw_security_config(struct net_device *dev) } ieee->hwsec_active = 1; - if ((ieee->pHTInfo->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { + if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { ieee->hwsec_active = 0; SECR_value &= ~SCR_RxDecEnable; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 43601ec8d9032..399ee9783f994 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -307,7 +307,7 @@ static void _rtl92e_update_cap(struct net_device *dev, u16 cap) u8 cur_slot_time = priv->slot_time; if ((cap & WLAN_CAPABILITY_SHORT_SLOT_TIME) && - (!priv->rtllib->pHTInfo->current_rt2rt_long_slot_time)) { + (!priv->rtllib->ht_info->current_rt2rt_long_slot_time)) { if (cur_slot_time != SHORT_SLOT_TIME) { slot_time_val = SHORT_SLOT_TIME; priv->rtllib->SetHwRegHandler(dev, @@ -339,10 +339,10 @@ static void _rtl92e_update_beacon(void *data) struct rtllib_device *ieee = priv->rtllib; struct rtllib_network *net = &ieee->current_network; - if (ieee->pHTInfo->bCurrentHTSupport) + if (ieee->ht_info->bCurrentHTSupport) HT_update_self_and_peer_setting(ieee, net); - ieee->pHTInfo->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time; - ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.rt2rt_ht_mode; + ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time; + ieee->ht_info->RT2RT_HT_Mode = net->bssht.rt2rt_ht_mode; _rtl92e_update_cap(dev, net->capability); } @@ -672,9 +672,9 @@ void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G)) { - priv->rtllib->pHTInfo->enable_ht = 1; + priv->rtllib->ht_info->enable_ht = 1; } else { - priv->rtllib->pHTInfo->enable_ht = 0; + priv->rtllib->ht_info->enable_ht = 0; } _rtl92e_refresh_support_rate(priv); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index e0f6f1405c17e..a18393c8a8339 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -321,7 +321,7 @@ void rtl92e_init_adaptive_rate(struct net_device *dev) static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; struct rate_adaptive *pra = &priv->rate_adaptive; u32 currentRATR, targetRATR = 0; u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; @@ -340,10 +340,10 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) if (priv->rtllib->state == RTLLIB_LINKED) { - bshort_gi_enabled = (pHTInfo->cur_tx_bw40mhz && - pHTInfo->bCurShortGI40MHz) || - (!pHTInfo->cur_tx_bw40mhz && - pHTInfo->bCurShortGI20MHz); + bshort_gi_enabled = (ht_info->cur_tx_bw40mhz && + ht_info->bCurShortGI40MHz) || + (!ht_info->cur_tx_bw40mhz && + ht_info->bCurShortGI20MHz); pra->upper_rssi_threshold_ratr = (pra->upper_rssi_threshold_ratr & (~BIT31)) | @@ -1532,7 +1532,7 @@ void rtl92e_dm_init_edca_turbo(struct net_device *dev) static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; static unsigned long lastTxOkCnt; static unsigned long lastRxOkCnt; @@ -1543,18 +1543,18 @@ static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) goto dm_CheckEdcaTurbo_EXIT; if (priv->rtllib->state != RTLLIB_LINKED) goto dm_CheckEdcaTurbo_EXIT; - if (priv->rtllib->pHTInfo->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO) + if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO) goto dm_CheckEdcaTurbo_EXIT; if (!priv->rtllib->bis_any_nonbepkts) { curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - if (pHTInfo->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) { + if (ht_info->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) { if (curTxOkCnt > 4*curRxOkCnt) { if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_UL[pHTInfo->IOTPeer]); + edca_setting_UL[ht_info->IOTPeer]); priv->bis_cur_rdlstate = false; } } else { @@ -1562,10 +1562,10 @@ static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) !priv->bcurrent_turbo_EDCA) { if (priv->rtllib->mode == WIRELESS_MODE_G) rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL_GMode[pHTInfo->IOTPeer]); + edca_setting_DL_GMode[ht_info->IOTPeer]); else rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL[pHTInfo->IOTPeer]); + edca_setting_DL[ht_info->IOTPeer]); priv->bis_cur_rdlstate = true; } } @@ -1576,17 +1576,17 @@ static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) !priv->bcurrent_turbo_EDCA) { if (priv->rtllib->mode == WIRELESS_MODE_G) rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL_GMode[pHTInfo->IOTPeer]); + edca_setting_DL_GMode[ht_info->IOTPeer]); else rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL[pHTInfo->IOTPeer]); + edca_setting_DL[ht_info->IOTPeer]); priv->bis_cur_rdlstate = true; } } else { if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_UL[pHTInfo->IOTPeer]); + edca_setting_UL[ht_info->IOTPeer]); priv->bis_cur_rdlstate = false; } @@ -1621,23 +1621,23 @@ static void _rtl92e_dm_init_cts_to_self(struct net_device *dev) static void _rtl92e_dm_cts_to_self(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); - struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; static unsigned long lastTxOkCnt; static unsigned long lastRxOkCnt; unsigned long curTxOkCnt = 0; unsigned long curRxOkCnt = 0; if (!priv->rtllib->bCTSToSelfEnable) { - pHTInfo->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; + ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; return; } - if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { + if (ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) { curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; if (curRxOkCnt > 4*curTxOkCnt) - pHTInfo->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; + ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; else - pHTInfo->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF; + ht_info->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF; lastTxOkCnt = priv->stats.txbytesunicast; lastRxOkCnt = priv->stats.rxbytesunicast; @@ -1648,10 +1648,10 @@ static void _rtl92e_dm_cts_to_self(struct net_device *dev) static void _rtl92e_dm_init_wa_broadcom_iot(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); - struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; - pHTInfo->bWAIotBroadcom = false; - pHTInfo->WAIotTH = WAIotTHVal; + ht_info->bWAIotBroadcom = false; + ht_info->WAIotTH = WAIotTHVal; } static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) @@ -1992,7 +1992,7 @@ static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t) if (priv->rtllib->state == RTLLIB_LINKED && priv->rtllib->bfsync_enable && - (priv->rtllib->pHTInfo->iot_action & HT_IOT_ACT_CDD_FSYNC)) { + (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_CDD_FSYNC)) { u32 rate_bitmap; for (rate_index = 0; rate_index <= 27; rate_index++) { @@ -2163,7 +2163,7 @@ static void _rtl92e_dm_check_fsync(struct net_device *dev) static u32 reset_cnt; if (priv->rtllib->state == RTLLIB_LINKED && - priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { + priv->rtllib->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) { if (priv->rtllib->bfsync_enable == 0) { switch (priv->rtllib->fsync_state) { case Default_Fsync: @@ -2288,7 +2288,7 @@ static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev) priv->bDynamicTxLowPower = false; return; } - if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) && + if ((priv->rtllib->ht_info->IOTPeer == HT_IOT_PEER_ATHEROS) && (priv->rtllib->mode == IEEE_G)) { txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH; txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 7ff14aa9f4762..bf0030144e5d8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -915,7 +915,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev, key, 0); } else { if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && - ieee->pHTInfo->bCurrentHTSupport) + ieee->ht_info->bCurrentHTSupport) rtl92e_writeb(dev, 0x173, 1); rtl92e_set_key(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, 0, key); diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 7c0369319f97f..acc19514bca60 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -244,13 +244,13 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) pBaStartSeqCtrl = (union sequence_control *)(req + 7); if (!ieee->current_network.qos_data.active || - !ieee->pHTInfo->bCurrentHTSupport || - (ieee->pHTInfo->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) { + !ieee->ht_info->bCurrentHTSupport || + (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, - ieee->pHTInfo->bCurrentHTSupport); + ieee->ht_info->bCurrentHTSupport); goto OnADDBAReq_Fail; } if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, @@ -277,7 +277,7 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) pBA->ba_start_seq_ctrl = *pBaStartSeqCtrl; if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || - (ieee->pHTInfo->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) + (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) pBA->ba_param_set.field.buffer_size = 1; else pBA->ba_param_set.field.buffer_size = 32; @@ -326,13 +326,13 @@ int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) pBaTimeoutVal = (u16 *)(tag + 7); if (!ieee->current_network.qos_data.active || - !ieee->pHTInfo->bCurrentHTSupport || - !ieee->pHTInfo->bCurrentAMPDUEnable) { + !ieee->ht_info->bCurrentHTSupport || + !ieee->ht_info->bCurrentAMPDUEnable) { netdev_warn(ieee->dev, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", ieee->current_network.qos_data.active, - ieee->pHTInfo->bCurrentHTSupport, - ieee->pHTInfo->bCurrentAMPDUEnable); + ieee->ht_info->bCurrentHTSupport, + ieee->ht_info->bCurrentAMPDUEnable); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } @@ -413,11 +413,11 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) } if (!ieee->current_network.qos_data.active || - !ieee->pHTInfo->bCurrentHTSupport) { + !ieee->ht_info->bCurrentHTSupport) { netdev_warn(ieee->dev, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network. qos_data.active, - ieee->pHTInfo->bCurrentHTSupport); + ieee->ht_info->bCurrentHTSupport); return -1; } diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index 2c4c1cb4cbed2..fe30a291e64c9 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -69,48 +69,48 @@ static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; void HTUpdateDefaultSetting(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - pHTInfo->bRegShortGI20MHz = 1; - pHTInfo->bRegShortGI40MHz = 1; + ht_info->bRegShortGI20MHz = 1; + ht_info->bRegShortGI40MHz = 1; - pHTInfo->bRegBW40MHz = 1; + ht_info->bRegBW40MHz = 1; - if (pHTInfo->bRegBW40MHz) - pHTInfo->bRegSuppCCK = 1; + if (ht_info->bRegBW40MHz) + ht_info->bRegSuppCCK = 1; else - pHTInfo->bRegSuppCCK = true; + ht_info->bRegSuppCCK = true; - pHTInfo->nAMSDU_MaxSize = 7935UL; - pHTInfo->bAMSDU_Support = 0; + ht_info->nAMSDU_MaxSize = 7935UL; + ht_info->bAMSDU_Support = 0; - pHTInfo->bAMPDUEnable = 1; - pHTInfo->AMPDU_Factor = 2; - pHTInfo->MPDU_Density = 0; + ht_info->bAMPDUEnable = 1; + ht_info->AMPDU_Factor = 2; + ht_info->MPDU_Density = 0; - pHTInfo->self_mimo_ps = 3; - if (pHTInfo->self_mimo_ps == 2) - pHTInfo->self_mimo_ps = 3; + ht_info->self_mimo_ps = 3; + if (ht_info->self_mimo_ps == 2) + ht_info->self_mimo_ps = 3; ieee->tx_dis_rate_fallback = 0; ieee->tx_use_drv_assinged_rate = 0; ieee->bTxEnableFwCalcDur = 1; - pHTInfo->reg_rt2rt_aggregation = 1; + ht_info->reg_rt2rt_aggregation = 1; - pHTInfo->reg_rx_reorder_enable = 1; - pHTInfo->rx_reorder_win_size = 64; - pHTInfo->rx_reorder_pending_time = 30; + ht_info->reg_rx_reorder_enable = 1; + ht_info->rx_reorder_win_size = 64; + ht_info->rx_reorder_pending_time = 30; } static u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - u8 is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0; - u8 isShortGI = (pHTInfo->bCurBW40MHz) ? - ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) : - ((pHTInfo->bCurShortGI20MHz) ? 1 : 0); + u8 is40MHz = (ht_info->bCurBW40MHz) ? 1 : 0; + u8 isShortGI = (ht_info->bCurBW40MHz) ? + ((ht_info->bCurShortGI40MHz) ? 1 : 0) : + ((ht_info->bCurShortGI20MHz) ? 1 : 0); return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; } @@ -166,45 +166,45 @@ bool IsHTHalfNmodeAPs(struct rtllib_device *ieee) static void HTIOTPeerDetermine(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; struct rtllib_network *net = &ieee->current_network; if (net->bssht.bd_rt2rt_aggregation) { - pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; + ht_info->IOTPeer = HT_IOT_PEER_REALTEK; if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE) - pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE; + ht_info->IOTPeer = HT_IOT_PEER_REALTEK_92SE; if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_SOFTAP) - pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP; + ht_info->IOTPeer = HT_IOT_PEER_92U_SOFTAP; } else if (net->broadcom_cap_exist) { - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + ht_info->IOTPeer = HT_IOT_PEER_BROADCOM; } else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) { - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + ht_info->IOTPeer = HT_IOT_PEER_BROADCOM; } else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || (memcmp(net->bssid, PCI_RALINK, 3) == 0) || (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || net->ralink_cap_exist) { - pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; + ht_info->IOTPeer = HT_IOT_PEER_RALINK; } else if ((net->atheros_cap_exist) || (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) || (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) { - pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; + ht_info->IOTPeer = HT_IOT_PEER_ATHEROS; } else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) || net->cisco_cap_exist) { - pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; + ht_info->IOTPeer = HT_IOT_PEER_CISCO; } else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || net->marvell_cap_exist) { - pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; + ht_info->IOTPeer = HT_IOT_PEER_MARVELL; } else if (net->airgo_cap_exist) { - pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO; + ht_info->IOTPeer = HT_IOT_PEER_AIRGO; } else { - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; + ht_info->IOTPeer = HT_IOT_PEER_UNKNOWN; } - netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer); + netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->IOTPeer); } static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) @@ -233,7 +233,7 @@ static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, { u8 retValue = 0; - if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) + if (ieee->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) retValue = 1; return retValue; @@ -243,40 +243,40 @@ static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) { u8 retValue = 0; - if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) + if (ieee->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) retValue = 1; return retValue; } static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - pHTInfo->iot_ra_func &= HT_IOT_RAFUNC_DISABLE_ALL; + ht_info->iot_ra_func &= HT_IOT_RAFUNC_DISABLE_ALL; - if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) - pHTInfo->iot_ra_func |= HT_IOT_RAFUNC_PEER_1R; + if (ht_info->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) + ht_info->iot_ra_func |= HT_IOT_RAFUNC_PEER_1R; - if (pHTInfo->iot_action & HT_IOT_ACT_AMSDU_ENABLE) - pHTInfo->iot_ra_func |= HT_IOT_RAFUNC_TX_AMSDU; + if (ht_info->iot_action & HT_IOT_ACT_AMSDU_ENABLE) + ht_info->iot_ra_func |= HT_IOT_RAFUNC_TX_AMSDU; } -void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) +void HTResetIOTSetting(struct rt_hi_throughput *ht_info) { - pHTInfo->iot_action = 0; - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; - pHTInfo->iot_ra_func = 0; + ht_info->iot_action = 0; + ht_info->IOTPeer = HT_IOT_PEER_UNKNOWN; + ht_info->iot_ra_func = 0; } void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, u8 *len, u8 IsEncrypt, bool bAssoc) { - struct rt_hi_throughput *pHT = ieee->pHTInfo; + struct rt_hi_throughput *pHT = ieee->ht_info; struct ht_capab_ele *pCapELE = NULL; if (!posHTCap || !pHT) { netdev_warn(ieee->dev, - "%s(): posHTCap and pHTInfo are null\n", __func__); + "%s(): posHTCap and ht_info are null\n", __func__); return; } memset(posHTCap, 0, *len); @@ -352,7 +352,7 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, u8 *len, u8 IsEncrypt) { - struct rt_hi_throughput *pHT = ieee->pHTInfo; + struct rt_hi_throughput *pHT = ieee->ht_info; struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; if (!posHTInfo || !pHTInfoEle) { @@ -509,7 +509,7 @@ void HTSetConnectBwMode(struct rtllib_device *ieee, void HTOnAssocRsp(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; struct ht_capab_ele *pPeerHTCap = NULL; struct ht_info_ele *pPeerHTInfo = NULL; u16 nMaxAMSDUSize = 0; @@ -518,22 +518,22 @@ void HTOnAssocRsp(struct rtllib_device *ieee) static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 }; - if (!pHTInfo->bCurrentHTSupport) { + if (!ht_info->bCurrentHTSupport) { netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); return; } netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); - if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) - pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); + if (!memcmp(ht_info->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) + pPeerHTCap = (struct ht_capab_ele *)(&ht_info->PeerHTCapBuf[4]); else - pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); + pPeerHTCap = (struct ht_capab_ele *)(ht_info->PeerHTCapBuf); - if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + if (!memcmp(ht_info->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) pPeerHTInfo = (struct ht_info_ele *) - (&pHTInfo->PeerHTInfoBuf[4]); + (&ht_info->PeerHTInfoBuf[4]); else - pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); + pPeerHTInfo = (struct ht_info_ele *)(ht_info->PeerHTInfoBuf); #ifdef VERBOSE_DEBUG print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, @@ -541,63 +541,63 @@ void HTOnAssocRsp(struct rtllib_device *ieee) #endif HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); - pHTInfo->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? + ht_info->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? true : false); - pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? + ht_info->bCurShortGI20MHz = ((ht_info->bRegShortGI20MHz) ? ((pPeerHTCap->ShortGI20Mhz == 1) ? true : false) : false); - pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? + ht_info->bCurShortGI40MHz = ((ht_info->bRegShortGI40MHz) ? ((pPeerHTCap->ShortGI40Mhz == 1) ? true : false) : false); - pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? + ht_info->bCurSuppCCK = ((ht_info->bRegSuppCCK) ? ((pPeerHTCap->DssCCk == 1) ? true : false) : false); - pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + ht_info->bCurrent_AMSDU_Support = ht_info->bAMSDU_Support; nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; - if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) - pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; + if (ht_info->nAMSDU_MaxSize > nMaxAMSDUSize) + ht_info->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; else - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + ht_info->nCurrent_AMSDU_MaxSize = ht_info->nAMSDU_MaxSize; - pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + ht_info->bCurrentAMPDUEnable = ht_info->bAMPDUEnable; if (ieee->rtllib_ap_sec_type && (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) { - if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || - (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) - pHTInfo->bCurrentAMPDUEnable = false; + if ((ht_info->IOTPeer == HT_IOT_PEER_ATHEROS) || + (ht_info->IOTPeer == HT_IOT_PEER_UNKNOWN)) + ht_info->bCurrentAMPDUEnable = false; } - if (!pHTInfo->reg_rt2rt_aggregation) { - if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) - pHTInfo->CurrentAMPDUFactor = + if (!ht_info->reg_rt2rt_aggregation) { + if (ht_info->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) + ht_info->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; else - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + ht_info->CurrentAMPDUFactor = ht_info->AMPDU_Factor; } else { if (ieee->current_network.bssht.bd_rt2rt_aggregation) { if (ieee->pairwise_key_type != KEY_TYPE_NA) - pHTInfo->CurrentAMPDUFactor = + ht_info->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; else - pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; + ht_info->CurrentAMPDUFactor = HT_AGG_SIZE_64K; } else { - pHTInfo->CurrentAMPDUFactor = min_t(u32, pPeerHTCap->MaxRxAMPDUFactor, + ht_info->CurrentAMPDUFactor = min_t(u32, pPeerHTCap->MaxRxAMPDUFactor, HT_AGG_SIZE_32K); } } - pHTInfo->current_mpdu_density = max_t(u8, pHTInfo->MPDU_Density, + ht_info->current_mpdu_density = max_t(u8, ht_info->MPDU_Density, pPeerHTCap->MPDUDensity); - if (pHTInfo->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K) { - pHTInfo->bCurrentAMPDUEnable = false; - pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; + if (ht_info->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K) { + ht_info->bCurrentAMPDUEnable = false; + ht_info->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; } - pHTInfo->cur_rx_reorder_enable = pHTInfo->reg_rx_reorder_enable; + ht_info->cur_rx_reorder_enable = ht_info->reg_rx_reorder_enable; if (pPeerHTCap->MCS[0] == 0) pPeerHTCap->MCS[0] = 0xff; @@ -606,8 +606,8 @@ void HTOnAssocRsp(struct rtllib_device *ieee) HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11ht_oper_rate_set); - pHTInfo->peer_mimo_ps = pPeerHTCap->MimoPwrSave; - if (pHTInfo->peer_mimo_ps == MIMO_PS_STATIC) + ht_info->peer_mimo_ps = pPeerHTCap->MimoPwrSave; + if (ht_info->peer_mimo_ps == MIMO_PS_STATIC) pMcsFilter = MCS_FILTER_1SS; else pMcsFilter = MCS_FILTER_ALL; @@ -616,49 +616,49 @@ void HTOnAssocRsp(struct rtllib_device *ieee) pMcsFilter); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - pHTInfo->current_op_mode = pPeerHTInfo->OptMode; + ht_info->current_op_mode = pPeerHTInfo->OptMode; } void HTInitializeHTInfo(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - pHTInfo->bCurrentHTSupport = false; + ht_info->bCurrentHTSupport = false; - pHTInfo->bCurBW40MHz = false; - pHTInfo->cur_tx_bw40mhz = false; + ht_info->bCurBW40MHz = false; + ht_info->cur_tx_bw40mhz = false; - pHTInfo->bCurShortGI20MHz = false; - pHTInfo->bCurShortGI40MHz = false; - pHTInfo->forced_short_gi = false; + ht_info->bCurShortGI20MHz = false; + ht_info->bCurShortGI40MHz = false; + ht_info->forced_short_gi = false; - pHTInfo->bCurSuppCCK = true; + ht_info->bCurSuppCCK = true; - pHTInfo->bCurrent_AMSDU_Support = false; - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - pHTInfo->current_mpdu_density = pHTInfo->MPDU_Density; - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + ht_info->bCurrent_AMSDU_Support = false; + ht_info->nCurrent_AMSDU_MaxSize = ht_info->nAMSDU_MaxSize; + ht_info->current_mpdu_density = ht_info->MPDU_Density; + ht_info->CurrentAMPDUFactor = ht_info->AMPDU_Factor; - memset((void *)(&pHTInfo->SelfHTCap), 0, - sizeof(pHTInfo->SelfHTCap)); - memset((void *)(&pHTInfo->SelfHTInfo), 0, - sizeof(pHTInfo->SelfHTInfo)); - memset((void *)(&pHTInfo->PeerHTCapBuf), 0, - sizeof(pHTInfo->PeerHTCapBuf)); - memset((void *)(&pHTInfo->PeerHTInfoBuf), 0, - sizeof(pHTInfo->PeerHTInfoBuf)); + memset((void *)(&ht_info->SelfHTCap), 0, + sizeof(ht_info->SelfHTCap)); + memset((void *)(&ht_info->SelfHTInfo), 0, + sizeof(ht_info->SelfHTInfo)); + memset((void *)(&ht_info->PeerHTCapBuf), 0, + sizeof(ht_info->PeerHTCapBuf)); + memset((void *)(&ht_info->PeerHTInfoBuf), 0, + sizeof(ht_info->PeerHTInfoBuf)); - pHTInfo->sw_bw_in_progress = false; + ht_info->sw_bw_in_progress = false; - pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; + ht_info->ePeerHTSpecVer = HT_SPEC_VER_IEEE; - pHTInfo->current_rt2rt_aggregation = false; - pHTInfo->current_rt2rt_long_slot_time = false; - pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + ht_info->current_rt2rt_aggregation = false; + ht_info->current_rt2rt_long_slot_time = false; + ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0; - pHTInfo->IOTPeer = 0; - pHTInfo->iot_action = 0; - pHTInfo->iot_ra_func = 0; + ht_info->IOTPeer = 0; + ht_info->iot_action = 0; + ht_info->iot_ra_func = 0; { u8 *RegHTSuppRateSets = &ieee->reg_ht_supp_rate_set[0]; @@ -687,114 +687,114 @@ void HTInitializeBssDesc(struct bss_ht *pBssHT) void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, struct rtllib_network *pNetwork) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; u8 bIOTAction = 0; /* unmark enable_ht flag here is the same reason why unmarked in * function rtllib_softmac_new_net. WB 2008.09.10 */ if (pNetwork->bssht.bd_support_ht) { - pHTInfo->bCurrentHTSupport = true; - pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver; + ht_info->bCurrentHTSupport = true; + ht_info->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver; if (pNetwork->bssht.bd_ht_cap_len > 0 && - pNetwork->bssht.bd_ht_cap_len <= sizeof(pHTInfo->PeerHTCapBuf)) - memcpy(pHTInfo->PeerHTCapBuf, + pNetwork->bssht.bd_ht_cap_len <= sizeof(ht_info->PeerHTCapBuf)) + memcpy(ht_info->PeerHTCapBuf, pNetwork->bssht.bd_ht_cap_buf, pNetwork->bssht.bd_ht_cap_len); if (pNetwork->bssht.bd_ht_info_len > 0 && pNetwork->bssht.bd_ht_info_len <= - sizeof(pHTInfo->PeerHTInfoBuf)) - memcpy(pHTInfo->PeerHTInfoBuf, + sizeof(ht_info->PeerHTInfoBuf)) + memcpy(ht_info->PeerHTInfoBuf, pNetwork->bssht.bd_ht_info_buf, pNetwork->bssht.bd_ht_info_len); - if (pHTInfo->reg_rt2rt_aggregation) { - pHTInfo->current_rt2rt_aggregation = + if (ht_info->reg_rt2rt_aggregation) { + ht_info->current_rt2rt_aggregation = pNetwork->bssht.bd_rt2rt_aggregation; - pHTInfo->current_rt2rt_long_slot_time = + ht_info->current_rt2rt_long_slot_time = pNetwork->bssht.bd_rt2rt_long_slot_time; - pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.rt2rt_ht_mode; + ht_info->RT2RT_HT_Mode = pNetwork->bssht.rt2rt_ht_mode; } else { - pHTInfo->current_rt2rt_aggregation = false; - pHTInfo->current_rt2rt_long_slot_time = false; - pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + ht_info->current_rt2rt_aggregation = false; + ht_info->current_rt2rt_long_slot_time = false; + ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0; } HTIOTPeerDetermine(ieee); - pHTInfo->iot_action = 0; + ht_info->iot_action = 0; bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_DISABLE_MCS14; + ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS14; bIOTAction = HTIOTActIsDisableMCS15(ieee); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_DISABLE_MCS15; + ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS15; bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_DISABLE_ALL_2SS; + ht_info->iot_action |= HT_IOT_ACT_DISABLE_ALL_2SS; bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_DISABLE_EDCA_TURBO; + ht_info->iot_action |= HT_IOT_ACT_DISABLE_EDCA_TURBO; bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M; + ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M; bIOTAction = HTIOTActIsCCDFsync(ieee); if (bIOTAction) - pHTInfo->iot_action |= HT_IOT_ACT_CDD_FSYNC; + ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC; } else { - pHTInfo->bCurrentHTSupport = false; - pHTInfo->current_rt2rt_aggregation = false; - pHTInfo->current_rt2rt_long_slot_time = false; - pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + ht_info->bCurrentHTSupport = false; + ht_info->current_rt2rt_aggregation = false; + ht_info->current_rt2rt_long_slot_time = false; + ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0; - pHTInfo->iot_action = 0; - pHTInfo->iot_ra_func = 0; + ht_info->iot_action = 0; + ht_info->iot_ra_func = 0; } } void HT_update_self_and_peer_setting(struct rtllib_device *ieee, struct rtllib_network *pNetwork) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; struct ht_info_ele *pPeerHTInfo = (struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf; - if (pHTInfo->bCurrentHTSupport) { + if (ht_info->bCurrentHTSupport) { if (pNetwork->bssht.bd_ht_info_len != 0) - pHTInfo->current_op_mode = pPeerHTInfo->OptMode; + ht_info->current_op_mode = pPeerHTInfo->OptMode; } } EXPORT_SYMBOL(HT_update_self_and_peer_setting); void HTUseDefaultSetting(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - if (pHTInfo->enable_ht) { - pHTInfo->bCurrentHTSupport = true; - pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; + if (ht_info->enable_ht) { + ht_info->bCurrentHTSupport = true; + ht_info->bCurSuppCCK = ht_info->bRegSuppCCK; - pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; - pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; + ht_info->bCurBW40MHz = ht_info->bRegBW40MHz; + ht_info->bCurShortGI20MHz = ht_info->bRegShortGI20MHz; - pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; + ht_info->bCurShortGI40MHz = ht_info->bRegShortGI40MHz; if (ieee->iw_mode == IW_MODE_ADHOC) ieee->current_network.qos_data.active = ieee->current_network.qos_data.supported; - pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + ht_info->bCurrent_AMSDU_Support = ht_info->bAMSDU_Support; + ht_info->nCurrent_AMSDU_MaxSize = ht_info->nAMSDU_MaxSize; - pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + ht_info->bCurrentAMPDUEnable = ht_info->bAMPDUEnable; + ht_info->CurrentAMPDUFactor = ht_info->AMPDU_Factor; - pHTInfo->current_mpdu_density = pHTInfo->current_mpdu_density; + ht_info->current_mpdu_density = ht_info->current_mpdu_density; HTFilterMCSRate(ieee, ieee->reg_dot11tx_ht_oper_rate_set, ieee->dot11ht_oper_rate_set); @@ -804,13 +804,13 @@ void HTUseDefaultSetting(struct rtllib_device *ieee) ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; } else { - pHTInfo->bCurrentHTSupport = false; + ht_info->bCurrentHTSupport = false; } } u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) { - if (ieee->pHTInfo->bCurrentHTSupport) { + if (ieee->ht_info->bCurrentHTSupport) { if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); return true; @@ -821,13 +821,13 @@ u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - if (pHTInfo->bCurBW40MHz) { - if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) + if (ht_info->bCurBW40MHz) { + if (ht_info->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) ieee->set_chan(ieee->dev, ieee->current_network.channel + 2); - else if (pHTInfo->CurSTAExtChnlOffset == + else if (ht_info->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_LOWER) ieee->set_chan(ieee->dev, ieee->current_network.channel - 2); @@ -836,29 +836,29 @@ static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) ieee->current_network.channel); ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, - pHTInfo->CurSTAExtChnlOffset); + ht_info->CurSTAExtChnlOffset); } else { ieee->set_chan(ieee->dev, ieee->current_network.channel); ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } - pHTInfo->sw_bw_in_progress = false; + ht_info->sw_bw_in_progress = false; } void HTSetConnectBwMode(struct rtllib_device *ieee, enum ht_channel_width bandwidth, enum ht_extchnl_offset Offset) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; - if (!pHTInfo->bRegBW40MHz) + if (!ht_info->bRegBW40MHz) return; if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) bandwidth = HT_CHANNEL_WIDTH_20; - if (pHTInfo->sw_bw_in_progress) { + if (ht_info->sw_bw_in_progress) { pr_info("%s: sw_bw_in_progress!!\n", __func__); return; } @@ -868,21 +868,21 @@ void HTSetConnectBwMode(struct rtllib_device *ieee, Offset = HT_EXTCHNL_OFFSET_NO_EXT; if (Offset == HT_EXTCHNL_OFFSET_UPPER || Offset == HT_EXTCHNL_OFFSET_LOWER) { - pHTInfo->bCurBW40MHz = true; - pHTInfo->CurSTAExtChnlOffset = Offset; + ht_info->bCurBW40MHz = true; + ht_info->CurSTAExtChnlOffset = Offset; } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + ht_info->bCurBW40MHz = false; + ht_info->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; } } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + ht_info->bCurBW40MHz = false; + ht_info->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; } - netdev_dbg(ieee->dev, "%s():pHTInfo->bCurBW40MHz:%x\n", __func__, - pHTInfo->bCurBW40MHz); + netdev_dbg(ieee->dev, "%s():ht_info->bCurBW40MHz:%x\n", __func__, + ht_info->bCurBW40MHz); - pHTInfo->sw_bw_in_progress = true; + ht_info->sw_bw_in_progress = true; HTSetConnectBwModeCallback(ieee); } diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c index 05c7e822f3727..68c131afc2ba4 100644 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -83,7 +83,7 @@ static void RxPktPendingTimeout(struct timer_list *t) if (bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) { pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq; mod_timer(&pRxTs->rx_pkt_pending_timer, jiffies + - msecs_to_jiffies(ieee->pHTInfo->rx_reorder_pending_time) + msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time) ); } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 9c81ca38f4b1d..7119c9c5e1fef 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1432,7 +1432,7 @@ struct rtllib_device { RT_RF_CHANGE_SOURCE rf_off_reason; bool is_set_key; bool wx_set_enc; - struct rt_hi_throughput *pHTInfo; + struct rt_hi_throughput *ht_info; spinlock_t reorder_spinlock; u8 reg_dot11ht_oper_rate_set[16]; @@ -2089,7 +2089,7 @@ u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, extern u8 MCS_FILTER_ALL[]; extern u16 MCS_DATA_RATE[2][2][77]; u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame); -void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo); +void HTResetIOTSetting(struct rt_hi_throughput *ht_info); bool IsHTHalfNmodeAPs(struct rtllib_device *ieee); u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate); int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb); diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index ce8b73f437a3d..d6a4d6b4ec578 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -125,8 +125,8 @@ struct net_device *alloc_rtllib(int sizeof_priv) if (err) goto free_crypt_info; - ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); - if (!ieee->pHTInfo) + ieee->ht_info = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); + if (!ieee->ht_info) goto free_softmac; HTUpdateDefaultSetting(ieee); @@ -160,7 +160,7 @@ void free_rtllib(struct net_device *dev) struct rtllib_device *ieee = (struct rtllib_device *) netdev_priv_rsl(dev); - kfree(ieee->pHTInfo); + kfree(ieee->ht_info); rtllib_softmac_free(ieee); lib80211_crypt_info_free(&ieee->crypt_info); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 75190c389ccf1..6a0f5bbb99ef4 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -567,9 +567,9 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, struct rtllib_rxb *prxb, struct rx_ts_record *pTS, u16 SeqNum) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; struct rx_reorder_entry *pReorderEntry = NULL; - u8 WinSize = pHTInfo->rx_reorder_win_size; + u8 WinSize = ht_info->rx_reorder_win_size; u16 WinEnd = 0; u8 index = 0; bool bMatchWinStart = false, bPktInBuf = false; @@ -591,7 +591,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, netdev_dbg(ieee->dev, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); - pHTInfo->rx_reorder_drop_counter++; + ht_info->rx_reorder_drop_counter++; { int i; @@ -755,7 +755,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, netdev_dbg(ieee->dev, "%s(): SET rx timeout timer\n", __func__); pTS->rx_timeout_indicate_seq = pTS->rx_indicate_seq; mod_timer(&pTS->rx_pkt_pending_timer, jiffies + - msecs_to_jiffies(pHTInfo->rx_reorder_pending_time)); + msecs_to_jiffies(ht_info->rx_reorder_pending_time)); } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); } @@ -924,7 +924,7 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, sc = le16_to_cpu(hdr->seq_ctl); frag = WLAN_GET_SEQ_FRAG(sc); - if (!ieee->pHTInfo->cur_rx_reorder_enable || + if (!ieee->ht_info->cur_rx_reorder_enable || !ieee->current_network.qos_data.active || !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { @@ -1442,7 +1442,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, } /* Indicate packets to upper layer or Rx Reorder */ - if (!ieee->pHTInfo->cur_rx_reorder_enable || pTS == NULL || bToOtherSTA) + if (!ieee->ht_info->cur_rx_reorder_enable || pTS == NULL || bToOtherSTA) rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src); else RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 8b1d88061125a..2552aa089700f 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -176,10 +176,10 @@ u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; u8 rate; - if (pHTInfo->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M) + if (ht_info->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M) rate = 0x0c; else rate = ieee->basic_rate & 0x7f; @@ -187,7 +187,7 @@ static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) if (rate == 0) { if (ieee->mode == IEEE_A || ieee->mode == IEEE_N_5G || - (ieee->mode == IEEE_N_24G && !pHTInfo->bCurSuppCCK)) + (ieee->mode == IEEE_N_24G && !ht_info->bCurSuppCCK)) rate = 0x0c; else rate = 0x02; @@ -829,7 +829,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 tmp_ht_cap_len = 0; u8 *tmp_ht_info_buf = NULL; u8 tmp_ht_info_len = 0; - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; u8 *tmp_generic_ie_buf = NULL; u8 tmp_generic_ie_len = 0; @@ -843,7 +843,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, if ((ieee->current_network.mode == IEEE_G) || (ieee->current_network.mode == IEEE_N_24G && - ieee->pHTInfo->bCurSuppCCK)) { + ieee->ht_info->bCurSuppCCK)) { erp_len = 3; erpinfo_content = 0; if (ieee->current_network.buseprotection) @@ -854,20 +854,20 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; encrypt = ieee->host_encrypt && crypt && crypt->ops && ((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len)); - if (ieee->pHTInfo->bCurrentHTSupport) { - tmp_ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap); - tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); - tmp_ht_info_buf = (u8 *)&(ieee->pHTInfo->SelfHTInfo); - tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); + if (ieee->ht_info->bCurrentHTSupport) { + tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap); + tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap); + tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo); + tmp_ht_info_len = sizeof(ieee->ht_info->SelfHTInfo); HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len, encrypt, false); HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len, encrypt); - if (pHTInfo->reg_rt2rt_aggregation) { - tmp_generic_ie_buf = ieee->pHTInfo->sz_rt2rt_agg_buf; + if (ht_info->reg_rt2rt_aggregation) { + tmp_generic_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf; tmp_generic_ie_len = - sizeof(ieee->pHTInfo->sz_rt2rt_agg_buf); + sizeof(ieee->ht_info->sz_rt2rt_agg_buf); HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); } @@ -1179,19 +1179,19 @@ rtllib_association_req(struct rtllib_network *beacon, if ((ieee->rtllib_ap_sec_type && (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) || ieee->bForcedBgMode) { - ieee->pHTInfo->enable_ht = 0; + ieee->ht_info->enable_ht = 0; ieee->mode = WIRELESS_MODE_G; } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { - ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap); - ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); + if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap); + ht_cap_len = sizeof(ieee->ht_info->SelfHTCap); HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt, true); - if (ieee->pHTInfo->current_rt2rt_aggregation) { - realtek_ie_buf = ieee->pHTInfo->sz_rt2rt_agg_buf; + if (ieee->ht_info->current_rt2rt_aggregation) { + realtek_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf; realtek_ie_len = - sizeof(ieee->pHTInfo->sz_rt2rt_agg_buf); + sizeof(ieee->ht_info->sz_rt2rt_agg_buf); HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len); } @@ -1324,8 +1324,8 @@ rtllib_association_req(struct rtllib_network *beacon, memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length); tag += osCcxVerNum.Length; } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { - if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) { + if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_HT_CAP; *tag++ = ht_cap_len - 2; @@ -1358,8 +1358,8 @@ rtllib_association_req(struct rtllib_network *beacon, rtllib_TURBO_Info(ieee, &tag); } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { - if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) { + if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_GENERIC; *tag++ = ht_cap_len - 2; @@ -1367,7 +1367,7 @@ rtllib_association_req(struct rtllib_network *beacon, tag += ht_cap_len - 2; } - if (ieee->pHTInfo->current_rt2rt_aggregation) { + if (ieee->ht_info->current_rt2rt_aggregation) { tag = skb_put(skb, realtek_ie_len); *tag++ = MFIE_TYPE_GENERIC; *tag++ = realtek_ie_len - 2; @@ -1524,14 +1524,14 @@ static void rtllib_associate_complete_wq(void *data) ieee->SetWirelessMode(ieee->dev, IEEE_B); netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate); } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht) { + if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { netdev_info(ieee->dev, "Successfully associated, ht enabled\n"); HTOnAssocRsp(ieee); } else { netdev_info(ieee->dev, "Successfully associated, ht not enabled(%d, %d)\n", - ieee->pHTInfo->bCurrentHTSupport, - ieee->pHTInfo->enable_ht); + ieee->ht_info->bCurrentHTSupport, + ieee->ht_info->enable_ht); memset(ieee->dot11ht_oper_rate_set, 0, 16); } ieee->link_detect_info.SlotNum = 2 * (1 + @@ -1684,7 +1684,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, ieee->current_network.ssid, ieee->current_network.channel, ieee->current_network.qos_data.supported, - ieee->pHTInfo->enable_ht, + ieee->ht_info->enable_ht, ieee->current_network.bssht.bd_support_ht, ieee->current_network.mode, ieee->current_network.flags); @@ -1693,7 +1693,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, !(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) rtllib_stop_scan_syncro(ieee); - HTResetIOTSetting(ieee->pHTInfo); + HTResetIOTSetting(ieee->ht_info); ieee->wmm_acm = 0; if (ieee->iw_mode == IW_MODE_INFRA) { /* Join the network for the first time */ @@ -1703,7 +1703,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); else - ieee->pHTInfo->bCurrentHTSupport = + ieee->ht_info->bCurrentHTSupport = false; ieee->state = RTLLIB_ASSOCIATING; @@ -1893,7 +1893,7 @@ static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, ((ieee->mode == IEEE_G) && (ieee->current_network.mode == IEEE_N_24G) && (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) { - ieee->pHTInfo->iot_action |= HT_IOT_ACT_PURE_N_MODE; + ieee->ht_info->iot_action |= HT_IOT_ACT_PURE_N_MODE; } else { ieee->AsocRetryCount = 0; } @@ -2100,7 +2100,7 @@ static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl) { if (ieee->sta_sleep == LPS_IS_WAKE) { if (nl) { - if (ieee->pHTInfo->iot_action & + if (ieee->ht_info->iot_action & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { ieee->ack_tx_to_ieee = 1; rtllib_sta_ps_send_null_frame(ieee, 0); @@ -2116,7 +2116,7 @@ static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl) if (ieee->sta_sleep == LPS_IS_SLEEP) ieee->sta_wake_up(ieee->dev); if (nl) { - if (ieee->pHTInfo->iot_action & + if (ieee->ht_info->iot_action & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { ieee->ack_tx_to_ieee = 1; rtllib_sta_ps_send_null_frame(ieee, 0); @@ -2151,7 +2151,7 @@ void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success) if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) { spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - if (ieee->pHTInfo->iot_action & + if (ieee->ht_info->iot_action & HT_IOT_ACT_NULL_DATA_POWER_SAVING) rtllib_sta_ps_send_null_frame(ieee, 0); else @@ -2235,10 +2235,10 @@ rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, kfree(network); return 1; } - memcpy(ieee->pHTInfo->PeerHTCapBuf, + memcpy(ieee->ht_info->PeerHTCapBuf, network->bssht.bd_ht_cap_buf, network->bssht.bd_ht_cap_len); - memcpy(ieee->pHTInfo->PeerHTInfoBuf, + memcpy(ieee->ht_info->PeerHTInfoBuf, network->bssht.bd_ht_info_buf, network->bssht.bd_ht_info_len); if (ieee->handle_assoc_response != NULL) @@ -2295,7 +2295,7 @@ static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb) if (ieee->open_wep || !challenge) { ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATED; ieee->softmac_stats.rx_auth_rs_ok++; - if (!(ieee->pHTInfo->iot_action & HT_IOT_ACT_PURE_N_MODE)) { + if (!(ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE)) { if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { if (IsHTHalfNmodeAPs(ieee)) { bSupportNmode = true; @@ -2669,7 +2669,7 @@ static void rtllib_start_ibss_wq(void *data) if ((ieee->mode == IEEE_N_24G) || (ieee->mode == IEEE_N_5G)) HTUseDefaultSetting(ieee); else - ieee->pHTInfo->bCurrentHTSupport = false; + ieee->ht_info->bCurrentHTSupport = false; ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS, (u8 *)(&ieee->state)); diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index e02e7d9566b24..63edf68c0b49a 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -359,11 +359,11 @@ void rtllib_wx_sync_scan_wq(void *data) if (ieee->ScanOperationBackupHandler) ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->enable_ht && - ieee->pHTInfo->bCurBW40MHz) { + if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht && + ieee->ht_info->bCurBW40MHz) { b40M = 1; - chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; - bandwidth = (enum ht_channel_width)ieee->pHTInfo->bCurBW40MHz; + chan_offset = ieee->ht_info->CurSTAExtChnlOffset; + bandwidth = (enum ht_channel_width)ieee->ht_info->bCurBW40MHz; ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 8b01cfe033813..9ab8ee46ef668 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -266,14 +266,14 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, struct sk_buff *skb, struct cb_desc *tcb_desc) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; struct tx_ts_record *pTxTs = NULL; struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data; if (rtllib_act_scanning(ieee, false)) return; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) + if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) return; if (!IsQoSDataFrame(skb->data)) return; @@ -283,12 +283,12 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, if (tcb_desc->bdhcp || ieee->CntAfterLink < 2) return; - if (pHTInfo->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION) + if (ht_info->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION) return; if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) return; - if (pHTInfo->bCurrentAMPDUEnable) { + if (ht_info->bCurrentAMPDUEnable) { if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) { netdev_info(ieee->dev, "%s: can't get TS\n", __func__); @@ -313,19 +313,19 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, } if (ieee->iw_mode == IW_MODE_INFRA) { tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor; - tcb_desc->ampdu_density = pHTInfo->current_mpdu_density; + tcb_desc->ampdu_factor = ht_info->CurrentAMPDUFactor; + tcb_desc->ampdu_density = ht_info->current_mpdu_density; } } FORCED_AGG_SETTING: - switch (pHTInfo->ForcedAMPDUMode) { + switch (ht_info->ForcedAMPDUMode) { case HT_AGG_AUTO: break; case HT_AGG_FORCE_ENABLE: tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_density = pHTInfo->forced_mpdu_density; - tcb_desc->ampdu_factor = pHTInfo->forced_ampdu_factor; + tcb_desc->ampdu_density = ht_info->forced_mpdu_density; + tcb_desc->ampdu_factor = ht_info->forced_ampdu_factor; break; case HT_AGG_FORCE_DISABLE: @@ -350,32 +350,32 @@ static void rtllib_query_ShortPreambleMode(struct rtllib_device *ieee, static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee, struct cb_desc *tcb_desc) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; tcb_desc->bUseShortGI = false; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) + if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) return; - if (pHTInfo->forced_short_gi) { + if (ht_info->forced_short_gi) { tcb_desc->bUseShortGI = true; return; } - if (pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI40MHz) + if (ht_info->bCurBW40MHz && ht_info->bCurShortGI40MHz) tcb_desc->bUseShortGI = true; - else if (!pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI20MHz) + else if (!ht_info->bCurBW40MHz && ht_info->bCurShortGI20MHz) tcb_desc->bUseShortGI = true; } static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, struct cb_desc *tcb_desc) { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rt_hi_throughput *ht_info = ieee->ht_info; tcb_desc->bPacketBW = false; - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->enable_ht) + if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) return; if (tcb_desc->bMulticast || tcb_desc->bBroadcast) @@ -383,7 +383,7 @@ static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, if ((tcb_desc->data_rate & 0x80) == 0) return; - if (pHTInfo->bCurBW40MHz && pHTInfo->cur_tx_bw40mhz && + if (ht_info->bCurBW40MHz && ht_info->cur_tx_bw40mhz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) tcb_desc->bPacketBW = true; } @@ -392,7 +392,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, struct cb_desc *tcb_desc, struct sk_buff *skb) { - struct rt_hi_throughput *pHTInfo; + struct rt_hi_throughput *ht_info; tcb_desc->bRTSSTBC = false; tcb_desc->bRTSUseShortGI = false; @@ -418,15 +418,15 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, return; } - pHTInfo = ieee->pHTInfo; + ht_info = ieee->ht_info; while (true) { - if (pHTInfo->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) { + if (ht_info->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) { tcb_desc->bCTSEnable = true; tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; break; - } else if (pHTInfo->iot_action & (HT_IOT_ACT_FORCED_RTS | + } else if (ht_info->iot_action & (HT_IOT_ACT_FORCED_RTS | HT_IOT_ACT_PURE_N_MODE)) { tcb_desc->bRTSEnable = true; tcb_desc->rts_rate = MGN_24M; @@ -438,12 +438,12 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, tcb_desc->rts_rate = MGN_24M; break; } - if (pHTInfo->bCurrentHTSupport && pHTInfo->enable_ht) { - u8 HTOpMode = pHTInfo->current_op_mode; + if (ht_info->bCurrentHTSupport && ht_info->enable_ht) { + u8 HTOpMode = ht_info->current_op_mode; - if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || + if ((ht_info->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || - (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { + (!ht_info->bCurBW40MHz && HTOpMode == 3)) { tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; break; @@ -882,7 +882,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) tcb_desc->priority = skb->priority; if (ether_type == ETH_P_PAE) { - if (ieee->pHTInfo->iot_action & + if (ieee->ht_info->iot_action & HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); @@ -906,7 +906,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) tcb_desc->data_rate = rtllib_current_rate(ieee); if (bdhcp) { - if (ieee->pHTInfo->iot_action & + if (ieee->ht_info->iot_action & HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); -- GitLab From 586cb1d65cc44371115600bc981626725c864029 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:51 -0800 Subject: [PATCH 0597/1480] tools lib api: Clean up install_headers Add missing backslash that caused an install command to always appear in build output. Make the install headers more specific. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 3e5ef1e0e8908..3649c7f7ea651 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -100,12 +100,12 @@ install_lib: $(LIBFILE) cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) install_headers: - $(call QUIET_INSTALL, headers) \ + $(call QUIET_INSTALL, libapi_headers) \ $(call do_install,cpu.h,$(prefix)/include/api,644); \ $(call do_install,debug.h,$(prefix)/include/api,644); \ $(call do_install,io.h,$(prefix)/include/api,644); \ $(call do_install,fd/array.h,$(prefix)/include/api/fd,644); \ - $(call do_install,fs/fs.h,$(prefix)/include/api/fs,644); + $(call do_install,fs/fs.h,$(prefix)/include/api/fs,644); \ $(call do_install,fs/tracing_path.h,$(prefix)/include/api/fs,644); install: install_lib install_headers -- GitLab From daa45f3f3577556801c7b0b2df85eed1289fbcb6 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:52 -0800 Subject: [PATCH 0598/1480] tools lib bpf: Avoid install_headers make warning The perf build makes the install_headers target, however, as there is no action for this target a warning is always produced of: make[3]: Nothing to be done for 'install_headers'. Solve this by adding a display of 'INSTALL libbpf_headers'. Signed-off-by: Ian Rogers Acked-by: Andrii Nakryiko Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/bpf/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 4c904ef0b47e9..7f5f7d2ebe1f1 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -255,6 +255,7 @@ $(INSTALL_GEN_HDRS): $(INSTALL_PFX)/%.h: $(OUTPUT)%.h $(call do_install,$<,$(prefix)/include/bpf,644) install_headers: $(BPF_GENERATED) $(INSTALL_SRC_HDRS) $(INSTALL_GEN_HDRS) + $(call QUIET_INSTALL, libbpf_headers) install_pkgconfig: $(PC_FILE) $(call QUIET_INSTALL, $(PC_FILE)) \ -- GitLab From 806dda31b856d83d8ec211aa9831bac5f978271e Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:53 -0800 Subject: [PATCH 0599/1480] tools lib symbol: Clean up build output Missing @ when building libsymbol. Make the install echo specific to installing the libsymbol headers. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/symbol/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/symbol/Makefile b/tools/lib/symbol/Makefile index 4c1d6b53032d2..ea8707b3442a7 100644 --- a/tools/lib/symbol/Makefile +++ b/tools/lib/symbol/Makefile @@ -77,7 +77,7 @@ include $(srctree)/tools/scripts/Makefile.include all: fixdep $(LIBFILE) $(SYMBOL_IN): FORCE - $(MAKE) $(build)=libsymbol V=1 + @$(MAKE) $(build)=libsymbol $(LIBFILE): $(SYMBOL_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SYMBOL_IN) @@ -101,7 +101,7 @@ install_lib: $(LIBFILE) cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) install_headers: - $(call QUIET_INSTALL, headers) \ + $(call QUIET_INSTALL, libsymbol_headers) \ $(call do_install,kallsyms.h,$(prefix)/include/symbol,644); install: install_lib install_headers -- GitLab From e8951bfb4cb325a6b80310790dc78ac9b4a147eb Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:54 -0800 Subject: [PATCH 0600/1480] tools lib perf: Make install_headers clearer Add libperf to the name so that this install_headers build appears different to similar targets in different libraries. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index 1badc0a046768..a90fb8c6bed4d 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -188,7 +188,7 @@ install_lib: libs cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ) install_headers: - $(call QUIET_INSTALL, headers) \ + $(call QUIET_INSTALL, libperf_headers) \ $(call do_install,include/perf/bpf_perf.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/core.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/cpumap.h,$(prefix)/include/perf,644); \ -- GitLab From 77dce6890a2a715b186bdc149c843571a5bb47df Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:55 -0800 Subject: [PATCH 0601/1480] tools lib subcmd: Make install_headers clearer Add libsubcmd to the name so that this install_headers build appears different to similar targets in different libraries. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index e96566f8991cc..9a316d8b89df5 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -101,7 +101,7 @@ install_lib: $(LIBFILE) cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) install_headers: - $(call QUIET_INSTALL, headers) \ + $(call QUIET_INSTALL, libsubcmd_headers) \ $(call do_install,exec-cmd.h,$(prefix)/include/subcmd,644); \ $(call do_install,help.h,$(prefix)/include/subcmd,644); \ $(call do_install,pager.h,$(prefix)/include/subcmd,644); \ -- GitLab From e664f31e21a2d201507704f302ab32f498871b11 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 16:43:56 -0800 Subject: [PATCH 0602/1480] tools lib traceevent: Make install_headers clearer Add libtraceevent to the name so that this install_headers build appears different to similar targets in different libraries. Add ; after kbuffer.h install target for consistency. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Hao Luo Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221117004356.279422-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index c874c017c6369..98dfd4badea3b 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -234,11 +234,11 @@ install_pkgconfig: $(call do_install_pkgconfig_file,$(prefix)) install_headers: - $(call QUIET_INSTALL, headers) \ + $(call QUIET_INSTALL, traceevent_headers) \ $(call do_install,event-parse.h,$(includedir_SQ),644); \ $(call do_install,event-utils.h,$(includedir_SQ),644); \ $(call do_install,trace-seq.h,$(includedir_SQ),644); \ - $(call do_install,kbuffer.h,$(includedir_SQ),644) + $(call do_install,kbuffer.h,$(includedir_SQ),644); install: install_lib -- GitLab From f215054d749b17c56e014fdca2fcc592dac4529c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:43 -0800 Subject: [PATCH 0603/1480] perf test: Add -w/--workload option The -w/--workload option is to run a simple workload used by testing. This adds a basic framework to run the workloads and 'noploop' workload as an example. $ perf test -w noploop The noploop does a loop doing nothing (NOP) for a second by default. It can have an optional argument to specify the time in seconds. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/Build | 2 ++ tools/perf/tests/builtin-test.c | 24 +++++++++++++++++++++ tools/perf/tests/tests.h | 22 +++++++++++++++++++ tools/perf/tests/workloads/Build | 3 +++ tools/perf/tests/workloads/noploop.c | 32 ++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 tools/perf/tests/workloads/Build create mode 100644 tools/perf/tests/workloads/noploop.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 2064a640facbe..11b69023011b0 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -103,3 +103,5 @@ endif CFLAGS_attr.o += -DBINDIR="BUILD_STR($(bindir_SQ))" -DPYTHON="BUILD_STR($(PYTHON_WORD))" CFLAGS_python-use.o += -DPYTHONPATH="BUILD_STR($(OUTPUT)python)" -DPYTHON="BUILD_STR($(PYTHON_WORD))" CFLAGS_dwarf-unwind.o += -fno-optimize-sibling-calls + +perf-y += workloads/ diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 7122eae1d98d9..ce641ccfcf814 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -118,6 +118,10 @@ static struct test_suite **tests[] = { arch_tests, }; +static struct test_workload *workloads[] = { + &workload__noploop, +}; + static int num_subtests(const struct test_suite *t) { int num; @@ -475,6 +479,21 @@ static int perf_test__list(int argc, const char **argv) return 0; } +static int run_workload(const char *work, int argc, const char **argv) +{ + unsigned int i = 0; + struct test_workload *twl; + + for (i = 0; i < ARRAY_SIZE(workloads); i++) { + twl = workloads[i]; + if (!strcmp(twl->name, work)) + return twl->func(argc, argv); + } + + pr_info("No workload found: %s\n", work); + return -1; +} + int cmd_test(int argc, const char **argv) { const char *test_usage[] = { @@ -482,12 +501,14 @@ int cmd_test(int argc, const char **argv) NULL, }; const char *skip = NULL; + const char *workload = NULL; const struct option test_options[] = { OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('F', "dont-fork", &dont_fork, "Do not fork for testcase"), + OPT_STRING('w', "workload", &workload, "work", "workload to run for testing"), OPT_END() }; const char * const test_subcommands[] = { "list", NULL }; @@ -504,6 +525,9 @@ int cmd_test(int argc, const char **argv) if (argc >= 1 && !strcmp(argv[0], "list")) return perf_test__list(argc - 1, argv + 1); + if (workload) + return run_workload(workload, argc, argv); + symbol_conf.priv_size = sizeof(int); symbol_conf.sort_by_name = true; symbol_conf.try_vmlinux_path = true; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 5bbb8f6a48fcb..d315d0d6fc977 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -180,4 +180,26 @@ int test__arch_unwind_sample(struct perf_sample *sample, DECLARE_SUITE(vectors_page); #endif +/* + * Define test workloads to be used in test suites. + */ +typedef int (*workload_fnptr)(int argc, const char **argv); + +struct test_workload { + const char *name; + workload_fnptr func; +}; + +#define DECLARE_WORKLOAD(work) \ + extern struct test_workload workload__##work + +#define DEFINE_WORKLOAD(work) \ +struct test_workload workload__##work = { \ + .name = #work, \ + .func = work, \ +} + +/* The list of test workloads */ +DECLARE_WORKLOAD(noploop); + #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build new file mode 100644 index 0000000000000..f98e968d4633a --- /dev/null +++ b/tools/perf/tests/workloads/Build @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +perf-y += noploop.o diff --git a/tools/perf/tests/workloads/noploop.c b/tools/perf/tests/workloads/noploop.c new file mode 100644 index 0000000000000..940ea5910a84c --- /dev/null +++ b/tools/perf/tests/workloads/noploop.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include +#include +#include "../tests.h" + +static volatile sig_atomic_t done; + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +static int noploop(int argc, const char **argv) +{ + int sec = 1; + + if (argc > 0) + sec = atoi(argv[0]); + + signal(SIGINT, sighandler); + signal(SIGALRM, sighandler); + alarm(sec); + + while (!done) + continue; + + return 0; +} + +DEFINE_WORKLOAD(noploop); -- GitLab From 24e733b29f13284aac30c4d1fb9f19201951d770 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:44 -0800 Subject: [PATCH 0604/1480] perf test: Replace pipe test workload with noploop So that it can get rid of requirement of a compiler. Also define and use more local symbols to ease future changes. $ sudo ./perf test -v pipe 87: perf pipe recording and injection test : --- start --- test child forked, pid 748003 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 748014 748014 -1 |perf [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 99.83% perf perf [.] noploop [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 99.85% perf perf [.] noploop [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.160 MB /tmp/perf.data.2XYPdw (4007 samples) ] 99.83% perf perf [.] noploop test child finished with 0 ---- end ---- perf pipe recording and injection test: Ok Signed-off-by: Namhyung Kim Tested-by: James Clark Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/pipe_test.sh | 55 ++++++----------------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/tools/perf/tests/shell/pipe_test.sh b/tools/perf/tests/shell/pipe_test.sh index 1b32b4f283911..8dd115dd35a7e 100755 --- a/tools/perf/tests/shell/pipe_test.sh +++ b/tools/perf/tests/shell/pipe_test.sh @@ -2,68 +2,33 @@ # perf pipe recording and injection test # SPDX-License-Identifier: GPL-2.0 -# skip if there's no compiler -if ! [ -x "$(command -v cc)" ]; then - echo "failed: no compiler, install gcc" - exit 2 -fi - -file=$(mktemp /tmp/test.file.XXXXXX) data=$(mktemp /tmp/perf.data.XXXXXX) +prog="perf test -w noploop" +task="perf" +sym="noploop" -cat < -#include -#include - -volatile int done; - -void sigalrm(int sig) { - done = 1; -} - -__attribute__((noinline)) void noploop(void) { - while (!done) - continue; -} - -int main(int argc, char *argv[]) { - int sec = 1; - - if (argc > 1) - sec = atoi(argv[1]); - - signal(SIGALRM, sigalrm); - alarm(sec); - - noploop(); - return 0; -} -EOF - - -if ! perf record -e task-clock:u -o - ${file} | perf report -i - --task | grep test.file; then +if ! perf record -e task-clock:u -o - ${prog} | perf report -i - --task | grep ${task}; then echo "cannot find the test file in the perf report" exit 1 fi -if ! perf record -e task-clock:u -o - ${file} | perf inject -b | perf report -i - | grep noploop; then +if ! perf record -e task-clock:u -o - ${prog} | perf inject -b | perf report -i - | grep ${sym}; then echo "cannot find noploop function in pipe #1" exit 1 fi -perf record -e task-clock:u -o - ${file} | perf inject -b -o ${data} -if ! perf report -i ${data} | grep noploop; then +perf record -e task-clock:u -o - ${prog} | perf inject -b -o ${data} +if ! perf report -i ${data} | grep ${sym}; then echo "cannot find noploop function in pipe #2" exit 1 fi -perf record -e task-clock:u -o ${data} ${file} -if ! perf inject -b -i ${data} | perf report -i - | grep noploop; then +perf record -e task-clock:u -o ${data} ${prog} +if ! perf inject -b -i ${data} | perf report -i - | grep ${sym}; then echo "cannot find noploop function in pipe #3" exit 1 fi -rm -f ${file} ${data} ${data}.old +rm -f ${data} ${data}.old exit 0 -- GitLab From 69b352927885b17f03d3ee4ee38f580699af107a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:45 -0800 Subject: [PATCH 0605/1480] perf test: Add 'thloop' test workload The thloop is similar to noploop but runs in two threads. This is needed to verify perf record --per-thread to handle multi-threaded programs properly. $ perf test -w thloop It also takes an optional argument to specify runtime in seconds (default: 1). Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 1 + tools/perf/tests/workloads/thloop.c | 53 +++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 tools/perf/tests/workloads/thloop.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index ce641ccfcf814..161f38476e77b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -120,6 +120,7 @@ static struct test_suite **tests[] = { static struct test_workload *workloads[] = { &workload__noploop, + &workload__thloop, }; static int num_subtests(const struct test_suite *t) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index d315d0d6fc977..e6edfeeadaeba 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -201,5 +201,6 @@ struct test_workload workload__##work = { \ /* The list of test workloads */ DECLARE_WORKLOAD(noploop); +DECLARE_WORKLOAD(thloop); #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index f98e968d4633a..b8964b1099c0e 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 perf-y += noploop.o +perf-y += thloop.o diff --git a/tools/perf/tests/workloads/thloop.c b/tools/perf/tests/workloads/thloop.c new file mode 100644 index 0000000000000..29193b75717ef --- /dev/null +++ b/tools/perf/tests/workloads/thloop.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include +#include +#include +#include "../tests.h" + +static volatile sig_atomic_t done; +static volatile unsigned count; + +/* We want to check this symbol in perf report */ +noinline void test_loop(void); + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +noinline void test_loop(void) +{ + while (!done) + count++; +} + +static void *thfunc(void *arg) +{ + void (*loop_fn)(void) = arg; + + loop_fn(); + return NULL; +} + +static int thloop(int argc, const char **argv) +{ + int sec = 1; + pthread_t th; + + if (argc > 0) + sec = atoi(argv[0]); + + signal(SIGINT, sighandler); + signal(SIGALRM, sighandler); + alarm(sec); + + pthread_create(&th, NULL, thfunc, test_loop); + test_loop(); + pthread_join(th, NULL); + + return 0; +} + +DEFINE_WORKLOAD(thloop); -- GitLab From 0b8ff0ba2744f364e8f5fb695ae323bae0ecfd19 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:46 -0800 Subject: [PATCH 0606/1480] perf test: Replace record test workload with thloop So that it can get rid of requirements for a compiler. $ sudo ./perf test -v 92 92: perf record tests : --- start --- test child forked, pid 740204 Basic --per-thread mode test Basic --per-thread mode test [Success] Register capture test Register capture test [Success] Basic --system-wide mode test Basic --system-wide mode test [Success] Basic target workload test Basic target workload test [Success] test child finished with 0 ---- end ---- perf record tests: Ok Signed-off-by: Namhyung Kim Tested-by: James Clark Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 59 ++------------------------------ 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index e93b3a8871fe3..4dff89e3a3fd5 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -9,17 +9,13 @@ shelldir=$(dirname "$0") err=0 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) -testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX) +testprog="perf test -w thloop" testsym="test_loop" cleanup() { rm -rf "${perfdata}" rm -rf "${perfdata}".old - if [ "${testprog}" != "true" ]; then - rm -f "${testprog}" - fi - trap - EXIT TERM INT } @@ -29,53 +25,6 @@ trap_cleanup() { } trap trap_cleanup EXIT TERM INT -build_test_program() { - if ! [ -x "$(command -v cc)" ]; then - # No CC found. Fall back to 'true' - testprog=true - testsym=true - return - fi - - echo "Build a test program" - cat < -#include -#include - -void test_loop(void) { - volatile int count = 1000000; - - while (count--) - continue; -} - -void *thfunc(void *arg) { - int forever = *(int *)arg; - - do { - test_loop(); - } while (forever); - - return NULL; -} - -int main(int argc, char *argv[]) { - pthread_t th; - int forever = 0; - - if (argc > 1) - forever = atoi(argv[1]); - - pthread_create(&th, NULL, thfunc, &forever); - test_loop(); - pthread_join(th, NULL); - - return 0; -} -EOF -} - test_per_thread() { echo "Basic --per-thread mode test" if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null @@ -96,8 +45,8 @@ test_per_thread() { return fi - # run the test program in background (forever) - ${testprog} 1 & + # run the test program in background (for 30 seconds) + ${testprog} 30 & TESTPID=$! rm -f "${perfdata}" @@ -205,8 +154,6 @@ test_workload() { echo "Basic target workload test [Success]" } -build_test_program - test_per_thread test_register_capture test_system_wide -- GitLab From 357057ee55d3c99a5de5abe8150f7bca04f8e53b Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Thu, 17 Nov 2022 11:59:14 +0800 Subject: [PATCH 0607/1480] staging: vme_user: Fix possible UAF in tsi148_dma_list_add Smatch report warning as follows: drivers/staging/vme_user/vme_tsi148.c:1757 tsi148_dma_list_add() warn: '&entry->list' not removed from list In tsi148_dma_list_add(), the error path "goto err_dma" will not remove entry->list from list->entries, but entry will be freed, then list traversal may cause UAF. Fix by removeing it from list->entries before free(). Fixes: b2383c90a9d6 ("vme: tsi148: fix first DMA item mapping") Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221117035914.2954454-1-cuigaosheng1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme_user/vme_tsi148.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c index 020e0b3bce64b..0171f46d1848f 100644 --- a/drivers/staging/vme_user/vme_tsi148.c +++ b/drivers/staging/vme_user/vme_tsi148.c @@ -1751,6 +1751,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, return 0; err_dma: + list_del(&entry->list); err_dest: err_source: err_align: -- GitLab From 2b7962bd05163f5b20fb5f933092b997debf8ed6 Mon Sep 17 00:00:00 2001 From: Brent Pappas Date: Thu, 17 Nov 2022 14:54:43 -0500 Subject: [PATCH 0608/1480] staging: gdm724x: Replace macro GDM_TTY_READY with static inline function Replace the macro GDM_TTY_READY with a static inline function to follow the Linux kernel coding style. Signed-off-by: Brent Pappas Link: https://lore.kernel.org/r/20221117195443.19616-1-bpappas@pappasbrent.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_tty.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index cc6d80554c982..e1a84d6020f48 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -21,7 +21,10 @@ #define MUX_TX_MAX_SIZE 2048 -#define GDM_TTY_READY(gdm) (gdm && gdm->tty_dev && gdm->port.count) +static inline bool gdm_tty_ready(struct gdm *gdm) +{ + return gdm && gdm->tty_dev && gdm->port.count; +} static struct tty_driver *gdm_driver[TTY_MAX_COUNT]; static struct gdm *gdm_table[TTY_MAX_COUNT][GDM_TTY_MINOR]; @@ -113,7 +116,7 @@ static int gdm_tty_recv_complete(void *data, { struct gdm *gdm = tty_dev->gdm[index]; - if (!GDM_TTY_READY(gdm)) { + if (!gdm_tty_ready(gdm)) { if (complete == RECV_PACKET_PROCESS_COMPLETE) gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, gdm_tty_recv_complete); @@ -140,7 +143,7 @@ static void gdm_tty_send_complete(void *arg) { struct gdm *gdm = arg; - if (!GDM_TTY_READY(gdm)) + if (!gdm_tty_ready(gdm)) return; tty_port_tty_wakeup(&gdm->port); @@ -154,7 +157,7 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int sent_len = 0; int sending_len = 0; - if (!GDM_TTY_READY(gdm)) + if (!gdm_tty_ready(gdm)) return -ENODEV; if (!len) @@ -181,7 +184,7 @@ static unsigned int gdm_tty_write_room(struct tty_struct *tty) { struct gdm *gdm = tty->driver_data; - if (!GDM_TTY_READY(gdm)) + if (!gdm_tty_ready(gdm)) return 0; return WRITE_SIZE; -- GitLab From 733611730676de202fade0cb73792c17d5aa9903 Mon Sep 17 00:00:00 2001 From: Umang Jain Date: Fri, 18 Nov 2022 14:12:42 +0530 Subject: [PATCH 0609/1480] Revert "staging: mmal-vchiq: Avoid use of bool in structures" This reverts commit 640e77466e69d9c28de227bc76881f5501f532ca. In commit 7967656ffbfa ("coding-style: Clarify the expectations around bool") the check to dis-allow bool structure members was removed from checkpatch.pl. It promotes bool structure members to store boolean values. This enhances code readability. Signed-off-by: Umang Jain Reviewed-by: Dave Stevenson Reviewed-by: Kieran Bingham Link: https://lore.kernel.org/r/20221118084244.199909-2-umang.jain@ideasonboard.com Signed-off-by: Greg Kroah-Hartman --- .../staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 12 ++++++------ .../staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index cb921c94996a1..4abb6178cb9ff 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -863,9 +863,9 @@ static int port_info_get(struct vchiq_mmal_instance *instance, goto release_msg; if (rmsg->u.port_info_get_reply.port.is_enabled == 0) - port->enabled = 0; + port->enabled = false; else - port->enabled = 1; + port->enabled = true; /* copy the values out of the message */ port->handle = rmsg->u.port_info_get_reply.port_handle; @@ -1304,7 +1304,7 @@ static int port_disable(struct vchiq_mmal_instance *instance, if (!port->enabled) return 0; - port->enabled = 0; + port->enabled = false; ret = port_action_port(instance, port, MMAL_MSG_PORT_ACTION_TYPE_DISABLE); @@ -1359,7 +1359,7 @@ static int port_enable(struct vchiq_mmal_instance *instance, if (ret) goto done; - port->enabled = 1; + port->enabled = true; if (port->buffer_cb) { /* send buffer headers to videocore */ @@ -1531,7 +1531,7 @@ int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, pr_err("failed disconnecting src port\n"); goto release_unlock; } - src->connected->enabled = 0; + src->connected->enabled = false; src->connected = NULL; } @@ -1799,7 +1799,7 @@ int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, ret = disable_component(instance, component); if (ret == 0) - component->enabled = 0; + component->enabled = false; mutex_unlock(&instance->vchiq_mutex); diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h index 6006e29232b3a..6d984cf5a83ac 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h @@ -48,7 +48,7 @@ typedef void (*vchiq_mmal_buffer_cb)( int status, struct mmal_buffer *buffer); struct vchiq_mmal_port { - u32 enabled:1; + bool enabled; u32 handle; u32 type; /* port type, cached to use on port info set */ u32 index; /* port index, cached to use on port info set */ @@ -83,7 +83,7 @@ struct vchiq_mmal_port { struct vchiq_mmal_component { u32 in_use:1; - u32 enabled:1; + bool enabled; u32 handle; /* VideoCore handle for component */ u32 inputs; /* Number of input ports */ u32 outputs; /* Number of output ports */ -- GitLab From c0012a39cf6c7197ad93da0bdba7245c094f8469 Mon Sep 17 00:00:00 2001 From: Umang Jain Date: Fri, 18 Nov 2022 14:12:43 +0530 Subject: [PATCH 0610/1480] vc04_services: mmal-vchiq: Use bool for vchiq_mmal_component.in_use In commit 7967656ffbfa ("coding-style: Clarify the expectations around bool") the check to dis-allow bool structure members was removed from checkpatch.pl. It promotes bool structure members to store boolean values. This enhances code readability. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Dave Stevenson Link: https://lore.kernel.org/r/20221118084244.199909-3-umang.jain@ideasonboard.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 6 +++--- drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 4abb6178cb9ff..294b184d4a495 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -1648,7 +1648,7 @@ int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, for (idx = 0; idx < VCHIQ_MMAL_MAX_COMPONENTS; idx++) { if (!instance->component[idx].in_use) { component = &instance->component[idx]; - component->in_use = 1; + component->in_use = true; break; } } @@ -1724,7 +1724,7 @@ release_component: destroy_component(instance, component); unlock: if (component) - component->in_use = 0; + component->in_use = false; mutex_unlock(&instance->vchiq_mutex); return ret; @@ -1747,7 +1747,7 @@ int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, ret = destroy_component(instance, component); - component->in_use = 0; + component->in_use = false; mutex_unlock(&instance->vchiq_mutex); diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h index 6d984cf5a83ac..09f030919d4e2 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h @@ -82,7 +82,7 @@ struct vchiq_mmal_port { }; struct vchiq_mmal_component { - u32 in_use:1; + bool in_use; bool enabled; u32 handle; /* VideoCore handle for component */ u32 inputs; /* Number of input ports */ -- GitLab From f198d34759eb3d110d37bb42f6c39cd90bd0b0cb Mon Sep 17 00:00:00 2001 From: Umang Jain Date: Fri, 18 Nov 2022 14:12:44 +0530 Subject: [PATCH 0611/1480] vc04_services: bcm2835-camera: Use bool values for mmal_fmt.remove_padding mmal_fmt.remove_padding is defined as a boolean type hence, use boolean values for it instead of 0/1 integers. This enhances code readability. Signed-off-by: Umang Jain Reviewed-by: Dave Stevenson Reviewed-by: Kieran Bingham Link: https://lore.kernel.org/r/20221118084244.199909-4-umang.jain@ideasonboard.com Signed-off-by: Greg Kroah-Hartman --- .../bcm2835-camera/bcm2835-camera.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index fd456d1f70611..797ebe2a973a1 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -87,21 +87,21 @@ static struct mmal_fmt formats[] = { .depth = 12, .mmal_component = COMP_CAMERA, .ybbp = 1, - .remove_padding = 1, + .remove_padding = true, }, { .fourcc = V4L2_PIX_FMT_YUYV, .mmal = MMAL_ENCODING_YUYV, .depth = 16, .mmal_component = COMP_CAMERA, .ybbp = 2, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_RGB24, .mmal = MMAL_ENCODING_RGB24, .depth = 24, .mmal_component = COMP_CAMERA, .ybbp = 3, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_JPEG, .flags = V4L2_FMT_FLAG_COMPRESSED, @@ -109,7 +109,7 @@ static struct mmal_fmt formats[] = { .depth = 8, .mmal_component = COMP_IMAGE_ENCODE, .ybbp = 0, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_H264, .flags = V4L2_FMT_FLAG_COMPRESSED, @@ -117,7 +117,7 @@ static struct mmal_fmt formats[] = { .depth = 8, .mmal_component = COMP_VIDEO_ENCODE, .ybbp = 0, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_MJPEG, .flags = V4L2_FMT_FLAG_COMPRESSED, @@ -125,63 +125,63 @@ static struct mmal_fmt formats[] = { .depth = 8, .mmal_component = COMP_VIDEO_ENCODE, .ybbp = 0, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_YVYU, .mmal = MMAL_ENCODING_YVYU, .depth = 16, .mmal_component = COMP_CAMERA, .ybbp = 2, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_VYUY, .mmal = MMAL_ENCODING_VYUY, .depth = 16, .mmal_component = COMP_CAMERA, .ybbp = 2, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_UYVY, .mmal = MMAL_ENCODING_UYVY, .depth = 16, .mmal_component = COMP_CAMERA, .ybbp = 2, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_NV12, .mmal = MMAL_ENCODING_NV12, .depth = 12, .mmal_component = COMP_CAMERA, .ybbp = 1, - .remove_padding = 1, + .remove_padding = true, }, { .fourcc = V4L2_PIX_FMT_BGR24, .mmal = MMAL_ENCODING_BGR24, .depth = 24, .mmal_component = COMP_CAMERA, .ybbp = 3, - .remove_padding = 0, + .remove_padding = false, }, { .fourcc = V4L2_PIX_FMT_YVU420, .mmal = MMAL_ENCODING_YV12, .depth = 12, .mmal_component = COMP_CAMERA, .ybbp = 1, - .remove_padding = 1, + .remove_padding = true, }, { .fourcc = V4L2_PIX_FMT_NV21, .mmal = MMAL_ENCODING_NV21, .depth = 12, .mmal_component = COMP_CAMERA, .ybbp = 1, - .remove_padding = 1, + .remove_padding = true, }, { .fourcc = V4L2_PIX_FMT_BGR32, .mmal = MMAL_ENCODING_BGRA, .depth = 32, .mmal_component = COMP_CAMERA, .ybbp = 4, - .remove_padding = 0, + .remove_padding = false, }, }; @@ -1147,7 +1147,7 @@ static int mmal_setup_components(struct bcm2835_mmal_dev *dev, struct vchiq_mmal_port *port = NULL, *camera_port = NULL; struct vchiq_mmal_component *encode_component = NULL; struct mmal_fmt *mfmt = get_format(f); - u32 remove_padding; + bool remove_padding; if (!mfmt) return -EINVAL; -- GitLab From 9a2c1d64c8eb4fab0387c0943eb6666b246f96aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:03 +0100 Subject: [PATCH 0612/1480] staging: most: i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-570-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/i2c/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c index 285a071f02be1..df53a4c4f8504 100644 --- a/drivers/staging/most/i2c/i2c.c +++ b/drivers/staging/most/i2c/i2c.c @@ -284,7 +284,7 @@ static irqreturn_t most_irq_handler(int irq, void *_dev) * * Register the i2c client device as a MOST interface */ -static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int i2c_probe(struct i2c_client *client) { struct hdm_i2c *dev; int ret, i; @@ -359,7 +359,7 @@ static struct i2c_driver i2c_driver = { .driver = { .name = "hdm_i2c", }, - .probe = i2c_probe, + .probe_new = i2c_probe, .remove = i2c_remove, .id_table = i2c_id, }; -- GitLab From b62649822e8c03ec1319f9d33c753106b8c80bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:04 +0100 Subject: [PATCH 0613/1480] staging: olpc_dcon: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-571-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 4fb9b9f107996..2fba52e0bd7bd 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -579,7 +579,7 @@ static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) return 0; } -static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int dcon_probe(struct i2c_client *client) { struct dcon_priv *dcon; int rc, i, j; @@ -779,7 +779,7 @@ static struct i2c_driver dcon_driver = { }, .class = I2C_CLASS_DDC | I2C_CLASS_HWMON, .id_table = dcon_idtable, - .probe = dcon_probe, + .probe_new = dcon_probe, .remove = dcon_remove, .detect = dcon_detect, .address_list = normal_i2c, -- GitLab From 9dadff066244543780e5d9ee406b3ec7af19e22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:02 +0100 Subject: [PATCH 0614/1480] staging: iio: ade7854: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-569-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7854-i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index a9a06e8dda51f..70f64b68f5b9c 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -109,8 +109,7 @@ unlock: return ret; } -static int ade7854_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ade7854_i2c_probe(struct i2c_client *client) { struct ade7854_state *st; struct iio_dev *indio_dev; @@ -141,7 +140,7 @@ static struct i2c_driver ade7854_i2c_driver = { .driver = { .name = "ade7854", }, - .probe = ade7854_i2c_probe, + .probe_new = ade7854_i2c_probe, .id_table = ade7854_id, }; module_i2c_driver(ade7854_i2c_driver); -- GitLab From ddacd6ef44cac60c4fb8cd1a994fb13e32c1c761 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Nov 2022 15:48:21 +0100 Subject: [PATCH 0615/1480] usb: fotg210: Fix Kconfig for USB host modules The kernel robot reports a link failure when activating the FOTG210 host subdriver with =y on a system where the USB host core is a module (CONFIG_USB=m). This is a bit of special case, so mimic the Kconfig incantations from DWC3: let the subdrivers for host or peripheral depend on the host or gadget support being =y or the same as the FOTG210 core itself. This should ensure that either: - The host (CONFIG_USB) or gadget (CONFIG_GADGET) is compiled in and then the FOTG210 can be either module or compiled in. - The host or gadget is modular, and then the FOTG210 module must be a module too, or we cannot resolve the symbols at link time. Reported-by: kernel test robot Link: https://lore.kernel.org/linux-usb/202211112132.0BUPGKCd-lkp@intel.com/ Cc: Arnd Bergmann Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221111144821.113665-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/fotg210/Kconfig b/drivers/usb/fotg210/Kconfig index 534206ee0d1db..2db6ac9f80746 100644 --- a/drivers/usb/fotg210/Kconfig +++ b/drivers/usb/fotg210/Kconfig @@ -14,7 +14,7 @@ if USB_FOTG210 config USB_FOTG210_HCD bool "Faraday FOTG210 USB Host Controller support" - depends on USB + depends on USB=y || USB=USB_FOTG210 help Faraday FOTG210 is an OTG controller which can be configured as an USB2.0 host. It is designed to meet USB2.0 EHCI specification @@ -24,7 +24,7 @@ config USB_FOTG210_HCD module will be called fotg210-hcd. config USB_FOTG210_UDC - depends on USB_GADGET + depends on USB_GADGET=y || USB_GADGET=USB_FOTG210 bool "Faraday FOTG210 USB Peripheral Controller support" help Faraday USB2.0 OTG controller which can be configured as -- GitLab From 6d36e0e1a14ac9a382c7a157bce5354fd8b68134 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 21 Nov 2022 16:22:19 +0100 Subject: [PATCH 0616/1480] usb: USB_FOTG210 should depend on ARCH_GEMINI The Faraday Technology FOTG210 USB2 Dual Role Controller is only present on Cortina Systems Gemini SoCs. Hence add a dependency on ARCH_GEMINI, to prevent asking the user about its drivers when configuring a kernel without Cortina Systems Gemini SoC support. Fixes: 1dd33a9f1b95ab59 ("usb: fotg210: Collect pieces of dual mode controller") Signed-off-by: Geert Uytterhoeven Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/a989b3b798ecaf3b45f35160e30e605636d66a77.1669044086.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/fotg210/Kconfig b/drivers/usb/fotg210/Kconfig index 2db6ac9f80746..2b05968735baa 100644 --- a/drivers/usb/fotg210/Kconfig +++ b/drivers/usb/fotg210/Kconfig @@ -4,6 +4,7 @@ config USB_FOTG210 tristate "Faraday FOTG210 USB2 Dual Role controller" depends on USB || USB_GADGET depends on HAS_DMA && HAS_IOMEM + depends on ARCH_GEMINI || COMPILE_TEST default ARCH_GEMINI select MFD_SYSCON help -- GitLab From d40eaada4209959264be63b21e18e15030db0a38 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Nov 2022 12:51:58 +0100 Subject: [PATCH 0617/1480] fotg210-udc: Use dev pointer in probe and dev_messages Add a local struct device *dev pointer and use dev_err() etc to report status. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221114115201.302887-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 3c357ce42d3b1..b3106e4b31944 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -1091,6 +1091,7 @@ int fotg210_udc_probe(struct platform_device *pdev) struct resource *res, *ires; struct fotg210_udc *fotg210 = NULL; struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP]; + struct device *dev = &pdev->dev; int ret = 0; int i; @@ -1122,7 +1123,7 @@ int fotg210_udc_probe(struct platform_device *pdev) fotg210->reg = ioremap(res->start, resource_size(res)); if (fotg210->reg == NULL) { - pr_err("ioremap error.\n"); + dev_err(dev, "ioremap error\n"); goto err_alloc; } @@ -1133,8 +1134,8 @@ int fotg210_udc_probe(struct platform_device *pdev) fotg210->gadget.ops = &fotg210_gadget_ops; fotg210->gadget.max_speed = USB_SPEED_HIGH; - fotg210->gadget.dev.parent = &pdev->dev; - fotg210->gadget.dev.dma_mask = pdev->dev.dma_mask; + fotg210->gadget.dev.parent = dev; + fotg210->gadget.dev.dma_mask = dev->dma_mask; fotg210->gadget.name = udc_name; INIT_LIST_HEAD(&fotg210->gadget.ep_list); @@ -1180,15 +1181,15 @@ int fotg210_udc_probe(struct platform_device *pdev) ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED, udc_name, fotg210); if (ret < 0) { - pr_err("request_irq error (%d)\n", ret); + dev_err(dev, "request_irq error (%d)\n", ret); goto err_req; } - ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget); + ret = usb_add_gadget_udc(dev, &fotg210->gadget); if (ret) goto err_add_udc; - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); + dev_info(dev, "version %s\n", DRIVER_VERSION); return 0; -- GitLab From 5f217ccd520f155c2e3b3dd95627140dd5ec947e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Nov 2022 12:51:59 +0100 Subject: [PATCH 0618/1480] fotg210-udc: Support optional external PHY This adds support for an optional external PHY to the FOTG210 UDC driver. Tested with the GPIO VBUS PHY driver on the Gemini SoC. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221114115201.302887-2-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 72 +++++++++++++++++++++++++++++++ drivers/usb/fotg210/fotg210-udc.h | 2 + 2 files changed, 74 insertions(+) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index b3106e4b31944..4026103330e1d 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "fotg210.h" #include "fotg210-udc.h" @@ -1008,11 +1010,19 @@ static int fotg210_udc_start(struct usb_gadget *g, { struct fotg210_udc *fotg210 = gadget_to_fotg210(g); u32 value; + int ret; /* hook up the driver */ driver->driver.bus = NULL; fotg210->driver = driver; + if (!IS_ERR_OR_NULL(fotg210->phy)) { + ret = otg_set_peripheral(fotg210->phy->otg, + &fotg210->gadget); + if (ret) + dev_err(fotg210->dev, "can't bind to phy\n"); + } + /* enable device global interrupt */ value = ioread32(fotg210->reg + FOTG210_DMCR); value |= DMCR_GLINT_EN; @@ -1054,6 +1064,9 @@ static int fotg210_udc_stop(struct usb_gadget *g) struct fotg210_udc *fotg210 = gadget_to_fotg210(g); unsigned long flags; + if (!IS_ERR_OR_NULL(fotg210->phy)) + return otg_set_peripheral(fotg210->phy->otg, NULL); + spin_lock_irqsave(&fotg210->lock, flags); fotg210_init(fotg210); @@ -1069,12 +1082,50 @@ static const struct usb_gadget_ops fotg210_gadget_ops = { .udc_stop = fotg210_udc_stop, }; +/** + * fotg210_phy_event - Called by phy upon VBus event + * @nb: notifier block + * @action: phy action, is vbus connect or disconnect + * @data: the usb_gadget structure in fotg210 + * + * Called by the USB Phy when a cable connect or disconnect is sensed. + * + * Returns NOTIFY_OK or NOTIFY_DONE + */ +static int fotg210_phy_event(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct usb_gadget *gadget = data; + + if (!gadget) + return NOTIFY_DONE; + + switch (action) { + case USB_EVENT_VBUS: + usb_gadget_vbus_connect(gadget); + return NOTIFY_OK; + case USB_EVENT_NONE: + usb_gadget_vbus_disconnect(gadget); + return NOTIFY_OK; + default: + return NOTIFY_DONE; + } +} + +static struct notifier_block fotg210_phy_notifier = { + .notifier_call = fotg210_phy_event, +}; + int fotg210_udc_remove(struct platform_device *pdev) { struct fotg210_udc *fotg210 = platform_get_drvdata(pdev); int i; usb_del_gadget_udc(&fotg210->gadget); + if (!IS_ERR_OR_NULL(fotg210->phy)) { + usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier); + usb_put_phy(fotg210->phy); + } iounmap(fotg210->reg); free_irq(platform_get_irq(pdev, 0), fotg210); @@ -1114,6 +1165,22 @@ int fotg210_udc_probe(struct platform_device *pdev) if (fotg210 == NULL) goto err; + fotg210->dev = dev; + + fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); + if (IS_ERR(fotg210->phy)) { + ret = PTR_ERR(fotg210->phy); + if (ret == -EPROBE_DEFER) + goto err; + dev_info(dev, "no PHY found\n"); + fotg210->phy = NULL; + } else { + ret = usb_phy_init(fotg210->phy); + if (ret) + goto err; + dev_info(dev, "found and initialized PHY\n"); + } + for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); if (_ep[i] == NULL) @@ -1185,6 +1252,9 @@ int fotg210_udc_probe(struct platform_device *pdev) goto err_req; } + if (!IS_ERR_OR_NULL(fotg210->phy)) + usb_register_notifier(fotg210->phy, &fotg210_phy_notifier); + ret = usb_add_gadget_udc(dev, &fotg210->gadget); if (ret) goto err_add_udc; @@ -1194,6 +1264,8 @@ int fotg210_udc_probe(struct platform_device *pdev) return 0; err_add_udc: + if (!IS_ERR_OR_NULL(fotg210->phy)) + usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier); free_irq(ires->start, fotg210); err_req: diff --git a/drivers/usb/fotg210/fotg210-udc.h b/drivers/usb/fotg210/fotg210-udc.h index 08c32957503be..e3067d22a895c 100644 --- a/drivers/usb/fotg210/fotg210-udc.h +++ b/drivers/usb/fotg210/fotg210-udc.h @@ -234,6 +234,8 @@ struct fotg210_udc { unsigned long irq_trigger; + struct device *dev; + struct usb_phy *phy; struct usb_gadget gadget; struct usb_gadget_driver *driver; -- GitLab From 718a38d092ec920dd84a5e25510cc6721f527c3e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Nov 2022 12:52:00 +0100 Subject: [PATCH 0619/1480] fotg210-udc: Handle PCLK This adds optional handling of the peripheral clock PCLK. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221114115201.302887-3-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 30 ++++++++++++++++++++++++++++-- drivers/usb/fotg210/fotg210-udc.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 4026103330e1d..de0f72ca103c5 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -1132,6 +1133,10 @@ int fotg210_udc_remove(struct platform_device *pdev) fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req); for (i = 0; i < FOTG210_MAX_NUM_EP; i++) kfree(fotg210->ep[i]); + + if (!IS_ERR(fotg210->pclk)) + clk_disable_unprepare(fotg210->pclk); + kfree(fotg210); return 0; @@ -1167,17 +1172,34 @@ int fotg210_udc_probe(struct platform_device *pdev) fotg210->dev = dev; + /* It's OK not to supply this clock */ + fotg210->pclk = devm_clk_get(dev, "PCLK"); + if (!IS_ERR(fotg210->pclk)) { + ret = clk_prepare_enable(fotg210->pclk); + if (ret) { + dev_err(dev, "failed to enable PCLK\n"); + return ret; + } + } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) { + /* + * Percolate deferrals, for anything else, + * just live without the clocking. + */ + ret = -EPROBE_DEFER; + goto err; + } + fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); if (IS_ERR(fotg210->phy)) { ret = PTR_ERR(fotg210->phy); if (ret == -EPROBE_DEFER) - goto err; + goto err_pclk; dev_info(dev, "no PHY found\n"); fotg210->phy = NULL; } else { ret = usb_phy_init(fotg210->phy); if (ret) - goto err; + goto err_pclk; dev_info(dev, "found and initialized PHY\n"); } @@ -1277,6 +1299,10 @@ err_map: err_alloc: for (i = 0; i < FOTG210_MAX_NUM_EP; i++) kfree(fotg210->ep[i]); +err_pclk: + if (!IS_ERR(fotg210->pclk)) + clk_disable_unprepare(fotg210->pclk); + kfree(fotg210); err: diff --git a/drivers/usb/fotg210/fotg210-udc.h b/drivers/usb/fotg210/fotg210-udc.h index e3067d22a895c..fadb57ca8d786 100644 --- a/drivers/usb/fotg210/fotg210-udc.h +++ b/drivers/usb/fotg210/fotg210-udc.h @@ -231,6 +231,7 @@ struct fotg210_ep { struct fotg210_udc { spinlock_t lock; /* protect the struct */ void __iomem *reg; + struct clk *pclk; unsigned long irq_trigger; -- GitLab From f8b729ce97f66807f6b958e891888d0b1ed20a9e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Nov 2022 12:52:01 +0100 Subject: [PATCH 0620/1480] fotg210-udc: Get IRQ using platform_get_irq() The platform_get_irq() is necessary to use to get dynamic IRQ resolution when instantiating the device from the device tree. IRQs are not passed as resources in that case. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20221114115201.302887-4-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index de0f72ca103c5..44dfe66e189cd 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -1144,10 +1144,11 @@ int fotg210_udc_remove(struct platform_device *pdev) int fotg210_udc_probe(struct platform_device *pdev) { - struct resource *res, *ires; + struct resource *res; struct fotg210_udc *fotg210 = NULL; struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP]; struct device *dev = &pdev->dev; + int irq; int ret = 0; int i; @@ -1157,9 +1158,9 @@ int fotg210_udc_probe(struct platform_device *pdev) return -ENODEV; } - ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!ires) { - pr_err("platform_get_resource IORESOURCE_IRQ error.\n"); + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + pr_err("could not get irq\n"); return -ENODEV; } @@ -1189,7 +1190,7 @@ int fotg210_udc_probe(struct platform_device *pdev) goto err; } - fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); + fotg210->phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); if (IS_ERR(fotg210->phy)) { ret = PTR_ERR(fotg210->phy); if (ret == -EPROBE_DEFER) @@ -1267,7 +1268,7 @@ int fotg210_udc_probe(struct platform_device *pdev) fotg210_disable_unplug(fotg210); - ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED, + ret = request_irq(irq, fotg210_irq, IRQF_SHARED, udc_name, fotg210); if (ret < 0) { dev_err(dev, "request_irq error (%d)\n", ret); @@ -1288,7 +1289,7 @@ int fotg210_udc_probe(struct platform_device *pdev) err_add_udc: if (!IS_ERR_OR_NULL(fotg210->phy)) usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier); - free_irq(ires->start, fotg210); + free_irq(irq, fotg210); err_req: fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req); -- GitLab From 202f785b1863d8feef53f6489afd9abcb744e7bf Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 14 Nov 2022 21:38:04 +0100 Subject: [PATCH 0621/1480] usb: fotg210-udc: Remove a useless assignment There is no need to use an intermediate array for these memory allocations, so, axe it. While at it, turn a '== NULL' into a shorter '!' when testing memory allocation failure. Signed-off-by: Christophe JAILLET Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/deab9696fc4000499470e7ccbca7c36fca17bd4e.1668458274.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 44dfe66e189cd..b9ea6c6d931c6 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -1146,7 +1146,6 @@ int fotg210_udc_probe(struct platform_device *pdev) { struct resource *res; struct fotg210_udc *fotg210 = NULL; - struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP]; struct device *dev = &pdev->dev; int irq; int ret = 0; @@ -1205,10 +1204,9 @@ int fotg210_udc_probe(struct platform_device *pdev) } for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { - _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); - if (_ep[i] == NULL) + fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); + if (!fotg210->ep[i]) goto err_alloc; - fotg210->ep[i] = _ep[i]; } fotg210->reg = ioremap(res->start, resource_size(res)); -- GitLab From 488c2c67463cc704715e9d4b68c9edfcc20f299d Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 15 Nov 2022 11:31:53 +0100 Subject: [PATCH 0622/1480] MAINTAINERS: rectify entry for MICROCHIP USB251XB DRIVER Commit fff61d4ccf3d ("dt-bindings: usb: usb251xb: Convert to YAML schema") converts usb251xb.txt to usb251xb.yaml, but misses to adjust its reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Repair this file reference in MICROCHIP USB251XB DRIVER. Signed-off-by: Lukas Bulwahn Acked-by: Marek Vasut Link: https://lore.kernel.org/r/20221115103153.28502-1-lukas.bulwahn@gmail.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2a8c456c184e0..8cb2c2b7d6cf8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13644,7 +13644,7 @@ MICROCHIP USB251XB DRIVER M: Richard Leitner L: linux-usb@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/usb/usb251xb.txt +F: Documentation/devicetree/bindings/usb/usb251xb.yaml F: drivers/usb/misc/usb251xb.c MICROCHIP USBA UDC DRIVER -- GitLab From 7b462b05e47adaf11358f5c2c24db85c487b613e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 11 Nov 2022 16:57:24 +0000 Subject: [PATCH 0623/1480] usb: ftdi-elan: remove variable l Variable l is just being accumulated and it's never used anywhere else. The variable and the addition are redundant so remove it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221111165724.557152-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 33b35788bd0ba..8ce191e3a4c06 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -1624,7 +1624,6 @@ wait:if (ftdi->disconnected > 0) { char data[30 *3 + 4]; char *d = data; int m = (sizeof(data) - 1) / 3 - 1; - int l = 0; struct u132_target *target = &ftdi->target[ed]; struct u132_command *command = &ftdi->command[ COMMAND_MASK & ftdi->command_next]; @@ -1647,7 +1646,6 @@ wait:if (ftdi->disconnected > 0) { } else if (i++ < m) { int w = sprintf(d, " %02X", *b++); d += w; - l += w; } else d += sprintf(d, " .."); } -- GitLab From b6ddd180e3d9f92c1e482b3cdeec7dda086b1341 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 14 Nov 2022 17:59:24 +0100 Subject: [PATCH 0624/1480] usb: typec: Check for ops->exit instead of ops->enter in altmode_exit typec_altmode_exit checks if ops->enter is not NULL but then calls ops->exit a few lines below. Fix that and check for the function pointer it's about to call instead. Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes") Signed-off-by: Sven Peter Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221114165924.33487-1-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 26ea2fdec17dc..31c2a3130cadb 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -134,7 +134,7 @@ int typec_altmode_exit(struct typec_altmode *adev) if (!adev || !adev->active) return 0; - if (!pdev->ops || !pdev->ops->enter) + if (!pdev->ops || !pdev->ops->exit) return -EOPNOTSUPP; /* Moving to USB Safe State */ -- GitLab From 6552ba4cd0841c23486368ed4feb2229e0abd1b3 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 16 Nov 2022 17:06:00 +0200 Subject: [PATCH 0625/1480] dt-bindings: usb: dwc3: Add SM8550 compatible Document the SM8550 dwc3 compatible. Signed-off-by: Abel Vesa Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221116150600.3011160-1-abel.vesa@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index a6e6abb4dfa9b..a3f8a3f498529 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -39,6 +39,7 @@ properties: - qcom,sm8250-dwc3 - qcom,sm8350-dwc3 - qcom,sm8450-dwc3 + - qcom,sm8550-dwc3 - const: qcom,dwc3 reg: @@ -301,6 +302,7 @@ allOf: - qcom,sm8150-dwc3 - qcom,sm8250-dwc3 - qcom,sm8450-dwc3 + - qcom,sm8550-dwc3 then: properties: clocks: @@ -358,6 +360,7 @@ allOf: - qcom,sm8250-dwc3 - qcom,sm8350-dwc3 - qcom,sm8450-dwc3 + - qcom,sm8550-dwc3 then: properties: interrupts: -- GitLab From 0384e87e3fec735e47f1c133c796f32ef7a72a9b Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 21 Nov 2022 14:24:16 +0800 Subject: [PATCH 0626/1480] usb: typec: tcpci: fix of node refcount leak in tcpci_register_port() I got the following report while doing device(mt6370-tcpc) load test with CONFIG_OF_UNITTEST and CONFIG_OF_DYNAMIC enabled: OF: ERROR: memory leak, expected refcount 1 instead of 2, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node /i2c/pmic@34/tcpc/connector The 'fwnode' set in tcpci_parse_config() which is called in tcpci_register_port(), its node refcount is increased in device_get_named_child_node(). It needs be put while exiting, so call fwnode_handle_put() in the error path of tcpci_register_port() and in tcpci_unregister_port() to avoid leak. Fixes: 5e85a04c8c0d ("usb: typec: add fwnode to tcpc") Signed-off-by: Yang Yingliang Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221121062416.1026192-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index b2bfcebe218f0..72f8d1e876004 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -794,8 +794,10 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) return ERR_PTR(err); tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc); - if (IS_ERR(tcpci->port)) + if (IS_ERR(tcpci->port)) { + fwnode_handle_put(tcpci->tcpc.fwnode); return ERR_CAST(tcpci->port); + } return tcpci; } @@ -804,6 +806,7 @@ EXPORT_SYMBOL_GPL(tcpci_register_port); void tcpci_unregister_port(struct tcpci *tcpci) { tcpm_unregister_port(tcpci->port); + fwnode_handle_put(tcpci->tcpc.fwnode); } EXPORT_SYMBOL_GPL(tcpci_unregister_port); -- GitLab From e99e1a7d6f88b9c54dc32671bac29f26e58bde80 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 18 Nov 2022 19:01:16 +0800 Subject: [PATCH 0627/1480] usb: host: xhci-mtk: omit shared hcd if either root hub has no ports There is error log when add a usb3 root hub without ports: "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" so omit the shared hcd if either of the root hubs has no ports, but usually there is no usb3 port. Signed-off-by: Chunfeng Yun Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20221118110116.20165-1-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 01705e559c422..cff3c4aea0362 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -485,6 +485,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) const struct hc_driver *driver; struct xhci_hcd *xhci; struct resource *res; + struct usb_hcd *usb3_hcd; struct usb_hcd *hcd; int ret = -ENODEV; int wakeup_irq; @@ -593,6 +594,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci = hcd_to_xhci(hcd); xhci->main_hcd = hcd; + xhci->allow_single_roothub = 1; /* * imod_interval is the interrupt moderation value in nanoseconds. @@ -602,24 +604,29 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci->imod_interval = 5000; device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval); - xhci->shared_hcd = usb_create_shared_hcd(driver, dev, - dev_name(dev), hcd); - if (!xhci->shared_hcd) { - ret = -ENOMEM; - goto disable_device_wakeup; - } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) - goto put_usb3_hcd; + goto disable_device_wakeup; - if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && + if (!xhci_has_one_roothub(xhci)) { + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, + dev_name(dev), hcd); + if (!xhci->shared_hcd) { + ret = -ENOMEM; + goto dealloc_usb2_hcd; + } + } + + usb3_hcd = xhci_get_usb3_hcd(xhci); + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && !(xhci->quirks & XHCI_BROKEN_STREAMS)) - xhci->shared_hcd->can_do_streams = 1; + usb3_hcd->can_do_streams = 1; - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); - if (ret) - goto dealloc_usb2_hcd; + if (xhci->shared_hcd) { + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); + if (ret) + goto put_usb3_hcd; + } if (wakeup_irq > 0) { ret = dev_pm_set_dedicated_wake_irq_reverse(dev, wakeup_irq); @@ -641,13 +648,13 @@ dealloc_usb3_hcd: usb_remove_hcd(xhci->shared_hcd); xhci->shared_hcd = NULL; -dealloc_usb2_hcd: - usb_remove_hcd(hcd); - put_usb3_hcd: - xhci_mtk_sch_exit(mtk); usb_put_hcd(xhci->shared_hcd); +dealloc_usb2_hcd: + xhci_mtk_sch_exit(mtk); + usb_remove_hcd(hcd); + disable_device_wakeup: device_init_wakeup(dev, false); @@ -679,10 +686,15 @@ static int xhci_mtk_remove(struct platform_device *pdev) dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); - usb_remove_hcd(shared_hcd); - xhci->shared_hcd = NULL; + if (shared_hcd) { + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; + } usb_remove_hcd(hcd); - usb_put_hcd(shared_hcd); + + if (shared_hcd) + usb_put_hcd(shared_hcd); + usb_put_hcd(hcd); xhci_mtk_sch_exit(mtk); clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); @@ -700,13 +712,16 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; int ret; xhci_dbg(xhci, "%s: stop port polling\n", __func__); clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); del_timer_sync(&hcd->rh_timer); - clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - del_timer_sync(&xhci->shared_hcd->rh_timer); + if (shared_hcd) { + clear_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + del_timer_sync(&shared_hcd->rh_timer); + } ret = xhci_mtk_host_disable(mtk); if (ret) @@ -718,8 +733,10 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) restart_poll_rh: xhci_dbg(xhci, "%s: restart port polling\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - usb_hcd_poll_rh_status(xhci->shared_hcd); + if (shared_hcd) { + set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + usb_hcd_poll_rh_status(shared_hcd); + } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return ret; @@ -730,6 +747,7 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; int ret; usb_wakeup_set(mtk, false); @@ -742,8 +760,10 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) goto disable_clks; xhci_dbg(xhci, "%s: restart port polling\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - usb_hcd_poll_rh_status(xhci->shared_hcd); + if (shared_hcd) { + set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + usb_hcd_poll_rh_status(shared_hcd); + } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return 0; -- GitLab From 19c220e9ab00f50edefb9667e3101e84a5112df2 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 14 Nov 2022 18:44:46 +0100 Subject: [PATCH 0628/1480] usb: typec: tipd: Cleanup resources if devm_tps6598_psy_register fails We can't just return if devm_tps6598_psy_register fails since previous resources are not devres managed and have yet to be cleaned up. Fixes: 10eb0b6ac63a ("usb: typec: tps6598x: Export some power supply properties") Signed-off-by: Sven Peter Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221114174449.34634-1-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tipd/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 2a77bab948f54..83a7a82e55f10 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -814,7 +814,7 @@ static int tps6598x_probe(struct i2c_client *client) ret = devm_tps6598_psy_register(tps); if (ret) - return ret; + goto err_role_put; tps->port = typec_register_port(&client->dev, &typec_cap); if (IS_ERR(tps->port)) { -- GitLab From 782c70edc4852a5d39be12377a85501546236212 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 14 Nov 2022 18:44:47 +0100 Subject: [PATCH 0629/1480] usb: typec: tipd: Fix spurious fwnode_handle_put in error path The err_role_put error path always calls fwnode_handle_put to release the fwnode. This path can be reached after probe itself has already released that fwnode though. Fix that by moving fwnode_handle_put in the happy path to the very end. Fixes: 18a6c866bb19 ("usb: typec: tps6598x: Add USB role switching logic") Signed-off-by: Sven Peter Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221114174449.34634-2-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tipd/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 83a7a82e55f10..59059310ba748 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -821,7 +821,6 @@ static int tps6598x_probe(struct i2c_client *client) ret = PTR_ERR(tps->port); goto err_role_put; } - fwnode_handle_put(fwnode); if (status & TPS_STATUS_PLUG_PRESENT) { ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status); @@ -845,6 +844,7 @@ static int tps6598x_probe(struct i2c_client *client) } i2c_set_clientdata(client, tps); + fwnode_handle_put(fwnode); return 0; -- GitLab From 4c8f27ba9ede0118cac9d775204f9b0ecdb877b0 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 14 Nov 2022 18:44:48 +0100 Subject: [PATCH 0630/1480] usb: typec: tipd: Fix typec_unregister_port error paths typec_unregister_port is only called for some error paths after typec_register_port was successful. Ensure it's called in all cases. Fixes: 92440202a880 ("usb: typec: tipd: Only update power status on IRQ") Signed-off-by: Sven Peter Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221114174449.34634-3-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tipd/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 59059310ba748..195c9c16f817f 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -826,7 +826,7 @@ static int tps6598x_probe(struct i2c_client *client) ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status); if (ret < 0) { dev_err(tps->dev, "failed to read power status: %d\n", ret); - goto err_role_put; + goto err_unregister_port; } ret = tps6598x_connect(tps, status); if (ret) @@ -839,8 +839,7 @@ static int tps6598x_probe(struct i2c_client *client) dev_name(&client->dev), tps); if (ret) { tps6598x_disconnect(tps, 0); - typec_unregister_port(tps->port); - goto err_role_put; + goto err_unregister_port; } i2c_set_clientdata(client, tps); @@ -848,6 +847,8 @@ static int tps6598x_probe(struct i2c_client *client) return 0; +err_unregister_port: + typec_unregister_port(tps->port); err_role_put: usb_role_switch_put(tps->role_sw); err_fwnode_put: -- GitLab From 53a256ea9596ec78a9f5dd51f2b49c2355b15d6e Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 14 Nov 2022 18:44:49 +0100 Subject: [PATCH 0631/1480] usb: typec: tipd: Move tps6598x_disconnect error path to its own label While the code currently correctly calls tps6598x_disconnect before jumping to the error cleanup label it's inconsistent compared to all the other cleanup actions and prone to introduce bugs if any more resources are added. Signed-off-by: Sven Peter Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221114174449.34634-4-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tipd/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 195c9c16f817f..982bd2cad931d 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -837,16 +837,16 @@ static int tps6598x_probe(struct i2c_client *client) irq_handler, IRQF_SHARED | IRQF_ONESHOT, dev_name(&client->dev), tps); - if (ret) { - tps6598x_disconnect(tps, 0); - goto err_unregister_port; - } + if (ret) + goto err_disconnect; i2c_set_clientdata(client, tps); fwnode_handle_put(fwnode); return 0; +err_disconnect: + tps6598x_disconnect(tps, 0); err_unregister_port: typec_unregister_port(tps->port); err_role_put: -- GitLab From ffbe2feac59b37c8dc536727552b4f375e1b9aec Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 18 Nov 2022 12:25:32 +0200 Subject: [PATCH 0632/1480] usb: musb: omap2430: Fix probe regression for missing resources Probe for omap2430 glue layer is now broken for interrupt resources in all cases. Commit 239071064732 ("partially Revert "usb: musb: Set the DT node on the child device"") broke probing for SoCs using ti-sysc interconnect target module as the dt node is not found. Commit a1a2b7125e10 ("of/platform: Drop static setup of IRQ resource from DT core") caused omap3 to fail with error "-ENXIO: IRQ mc not found" as the IRQ resources are no longer automatically populated from devicetree. Let's fix the issues by calling device_set_of_node_from_dev() only if the SoC has been updated to probe with ti-sysc. And for legacy SoCs, let's populate the resources manually as needed. Note that once we have updated the SoCs to probe with proper devicetree data in all cases, this is no longer needed. But doing that requires patching both devicetree and SoC code, so let's fix the probe issues first. Fixes: a1a2b7125e10 ("of/platform: Drop static setup of IRQ resource from DT core") Fixes: 239071064732 ("partially Revert "usb: musb: Set the DT node on the child device"") Cc: H. Nikolaus Schaller Reported-by: Sicelo Mhlongo Tested-by: Sicelo Mhlongo Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20221118102532.34458-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/omap2430.c | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index f571a65ae6ee2..476f55d1fec30 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -310,6 +311,7 @@ static int omap2430_probe(struct platform_device *pdev) struct device_node *control_node; struct platform_device *control_pdev; int ret = -ENOMEM, val; + bool populate_irqs = false; if (!np) return -ENODEV; @@ -328,6 +330,18 @@ static int omap2430_probe(struct platform_device *pdev) musb->dev.dma_mask = &omap2430_dmamask; musb->dev.coherent_dma_mask = omap2430_dmamask; + /* + * Legacy SoCs using omap_device get confused if node is moved + * because of interconnect properties mixed into the node. + */ + if (of_get_property(np, "ti,hwmods", NULL)) { + dev_warn(&pdev->dev, "please update to probe with ti-sysc\n"); + populate_irqs = true; + } else { + device_set_of_node_from_dev(&musb->dev, &pdev->dev); + } + of_node_put(np); + glue->dev = &pdev->dev; glue->musb = musb; glue->status = MUSB_UNKNOWN; @@ -389,6 +403,46 @@ static int omap2430_probe(struct platform_device *pdev) goto err2; } + if (populate_irqs) { + struct resource musb_res[3]; + struct resource *res; + int i = 0; + + memset(musb_res, 0, sizeof(*musb_res) * ARRAY_SIZE(musb_res)); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + goto err2; + + musb_res[i].start = res->start; + musb_res[i].end = res->end; + musb_res[i].flags = res->flags; + musb_res[i].name = res->name; + i++; + + ret = of_irq_get_byname(np, "mc"); + if (ret > 0) { + musb_res[i].start = ret; + musb_res[i].flags = IORESOURCE_IRQ; + musb_res[i].name = "mc"; + i++; + } + + ret = of_irq_get_byname(np, "dma"); + if (ret > 0) { + musb_res[i].start = ret; + musb_res[i].flags = IORESOURCE_IRQ; + musb_res[i].name = "dma"; + i++; + } + + ret = platform_device_add_resources(musb, musb_res, i); + if (ret) { + dev_err(&pdev->dev, "failed to add IRQ resources\n"); + goto err2; + } + } + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); -- GitLab From 3205054dc6fe2425ff24827a51fdf7cbbb528680 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 16 Nov 2022 12:04:44 +0100 Subject: [PATCH 0633/1480] usb: dwc3: improve the config dependency of USB_DWC3_XILINX A request to Manish Narani (see Link) asked for clarification of the reference to the config ARCH_VERSAL in the support of Xilinx SoCs with DesignWare Core USB3 IP. As there is no response, clean up the reference to the non-existing config symbol. While at it, follow up on Felipe Balbi's request to add the alternative COMPILE_TEST dependency. Link: https://lore.kernel.org/all/CAKXUXMwgWfX8+OvY0aCwRNukencwJERAZzU7p4eOLXQ2zv6rAg@mail.gmail.com/ Signed-off-by: Lukas Bulwahn Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20221116110444.8340-1-lukas.bulwahn@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 03ededa86da1f..b2f72b0e75c6b 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -152,11 +152,11 @@ config USB_DWC3_IMX8MP config USB_DWC3_XILINX tristate "Xilinx Platforms" - depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + depends on (ARCH_ZYNQMP || COMPILE_TEST) && OF default USB_DWC3 help Support Xilinx SoCs with DesignWare Core USB3 IP. - This driver handles both ZynqMP and Versal SoC operations. + This driver handles ZynqMP SoC operations. Say 'Y' or 'M' if you have one such device. config USB_DWC3_AM62 -- GitLab From 581c848b610dbf3fe1ed4d85fd53d0743c61faba Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 20 Nov 2022 15:15:09 +0100 Subject: [PATCH 0634/1480] extcon: usbc-tusb320: Update state on probe even if no IRQ pending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently this driver triggers extcon and typec state update in its probe function, to read out current state reported by the chip and report the correct state to upper layers. This synchronization is performed correctly, but only in case the chip indicates a pending interrupt in reg09 register. This fails to cover the situation where all interrupts reported by the chip were already handled by Linux before reboot, then the system rebooted, and then Linux starts again. In this case, the TUSB320 no longer reports any interrupts in reg09, and the state update does not perform any update as it depends on that interrupt indication. Fix this by turning tusb320_irq_handler() into a thin wrapper around tusb320_state_update_handler(), where the later now contains the bulk of the code of tusb320_irq_handler(), but adds new function parameter "force_update". The "force_update" parameter can be used by the probe function to assure that the state synchronization is always performed, independent of the interrupt indicated in reg09. The interrupt handler tusb320_irq_handler() callback uses force_update=false to avoid state updates on potential spurious interrupts and retain current behavior. Fixes: 06bc4ca115cdd ("extcon: Add driver for TI TUSB320") Signed-off-by: Marek Vasut Reviewed-by: Alvin Šipraga Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221120141509.81012-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon-usbc-tusb320.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c index 2a120d8d3c272..9dfa545427ca1 100644 --- a/drivers/extcon/extcon-usbc-tusb320.c +++ b/drivers/extcon/extcon-usbc-tusb320.c @@ -313,9 +313,9 @@ static void tusb320_typec_irq_handler(struct tusb320_priv *priv, u8 reg9) typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB); } -static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) +static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv, + bool force_update) { - struct tusb320_priv *priv = dev_id; unsigned int reg; if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { @@ -323,7 +323,7 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) return IRQ_NONE; } - if (!(reg & TUSB320_REG9_INTERRUPT_STATUS)) + if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS)) return IRQ_NONE; tusb320_extcon_irq_handler(priv, reg); @@ -340,6 +340,13 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) +{ + struct tusb320_priv *priv = dev_id; + + return tusb320_state_update_handler(priv, false); +} + static const struct regmap_config tusb320_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -466,7 +473,7 @@ static int tusb320_probe(struct i2c_client *client, return ret; /* update initial state */ - tusb320_irq_handler(client->irq, priv); + tusb320_state_update_handler(priv, true); /* Reset chip to its default state */ ret = tusb320_reset(priv); @@ -477,7 +484,7 @@ static int tusb320_probe(struct i2c_client *client, * State and polarity might change after a reset, so update * them again and make sure the interrupt status bit is cleared. */ - tusb320_irq_handler(client->irq, priv); + tusb320_state_update_handler(priv, true); ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, tusb320_irq_handler, -- GitLab From afdc12887f2b2ecf20d065a7d81ad29824155083 Mon Sep 17 00:00:00 2001 From: Jiantao Zhang Date: Mon, 21 Nov 2022 13:08:05 +0000 Subject: [PATCH 0635/1480] USB: gadget: Fix use-after-free during usb config switch In the process of switching USB config from rndis to other config, if the hardware does not support the ->pullup callback, or the hardware encounters a low probability fault, both of them may cause the ->pullup callback to fail, which will then cause a system panic (use after free). The gadget drivers sometimes need to be unloaded regardless of the hardware's behavior. Analysis as follows: ======================================================================= (1) write /config/usb_gadget/g1/UDC "none" gether_disconnect+0x2c/0x1f8 rndis_disable+0x4c/0x74 composite_disconnect+0x74/0xb0 configfs_composite_disconnect+0x60/0x7c usb_gadget_disconnect+0x70/0x124 usb_gadget_unregister_driver+0xc8/0x1d8 gadget_dev_desc_UDC_store+0xec/0x1e4 (2) rm /config/usb_gadget/g1/configs/b.1/f1 rndis_deregister+0x28/0x54 rndis_free+0x44/0x7c usb_put_function+0x14/0x1c config_usb_cfg_unlink+0xc4/0xe0 configfs_unlink+0x124/0x1c8 vfs_unlink+0x114/0x1dc (3) rmdir /config/usb_gadget/g1/functions/rndis.gs4 panic+0x1fc/0x3d0 do_page_fault+0xa8/0x46c do_mem_abort+0x3c/0xac el1_sync_handler+0x40/0x78 0xffffff801138f880 rndis_close+0x28/0x34 eth_stop+0x74/0x110 dev_close_many+0x48/0x194 rollback_registered_many+0x118/0x814 unregister_netdev+0x20/0x30 gether_cleanup+0x1c/0x38 rndis_attr_release+0xc/0x14 kref_put+0x74/0xb8 configfs_rmdir+0x314/0x374 If gadget->ops->pullup() return an error, function rndis_close() will be called, then it will causes a use-after-free problem. ======================================================================= Fixes: 0a55187a1ec8 ("USB: gadget core: Issue ->disconnect() callback from usb_gadget_disconnect()") Signed-off-by: Jiantao Zhang Signed-off-by: TaoXue Link: https://lore.kernel.org/r/20221121130805.10735-1-water.zhangjiantao@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index c63c0c2cf649d..bf9878e1a72a8 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -734,13 +734,13 @@ int usb_gadget_disconnect(struct usb_gadget *gadget) } ret = gadget->ops->pullup(gadget, 0); - if (!ret) { + if (!ret) gadget->connected = 0; - mutex_lock(&udc_lock); - if (gadget->udc->driver) - gadget->udc->driver->disconnect(gadget); - mutex_unlock(&udc_lock); - } + + mutex_lock(&udc_lock); + if (gadget->udc->driver) + gadget->udc->driver->disconnect(gadget); + mutex_unlock(&udc_lock); out: trace_usb_gadget_disconnect(gadget, ret); -- GitLab From 05b2e347a58385b8b00051fef61f10a512b5aa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:18 +0100 Subject: [PATCH 0636/1480] usb: typec: ucsi: stm32g0: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221118224540.619276-585-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index 7b92f0c8de708..93fead0096b7b 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -626,7 +626,7 @@ static int ucsi_stm32g0_probe_bootloader(struct ucsi *ucsi) return 0; } -static int ucsi_stm32g0_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int ucsi_stm32g0_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct ucsi_stm32g0 *g0; @@ -763,7 +763,7 @@ static struct i2c_driver ucsi_stm32g0_i2c_driver = { .of_match_table = of_match_ptr(ucsi_stm32g0_typec_of_match), .pm = pm_sleep_ptr(&ucsi_stm32g0_pm_ops), }, - .probe = ucsi_stm32g0_probe, + .probe_new = ucsi_stm32g0_probe, .remove = ucsi_stm32g0_remove, .id_table = ucsi_stm32g0_typec_i2c_devid }; -- GitLab From d24182b10cd5c734499c6185e9c63403ee1de5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:17 +0100 Subject: [PATCH 0637/1480] usb: typec: ucsi/ucsi_ccg: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221118224540.619276-584-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi_ccg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 835f1c4372ba2..46441f1477f28 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -1338,8 +1338,7 @@ static struct attribute *ucsi_ccg_attrs[] = { }; ATTRIBUTE_GROUPS(ucsi_ccg); -static int ucsi_ccg_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ucsi_ccg_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct ucsi_ccg *uc; @@ -1482,7 +1481,7 @@ static struct i2c_driver ucsi_ccg_driver = { .dev_groups = ucsi_ccg_groups, .acpi_match_table = amd_i2c_ucsi_match, }, - .probe = ucsi_ccg_probe, + .probe_new = ucsi_ccg_probe, .remove = ucsi_ccg_remove, .id_table = ucsi_ccg_device_id, }; -- GitLab From f02586d70aeb491a17c179c857aa4a361760bf0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:16 +0100 Subject: [PATCH 0638/1480] usb: typec: tcpm/tcpci_rt1711h: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Heikki Krogerus Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20221118224540.619276-583-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpci_rt1711h.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci_rt1711h.c b/drivers/usb/typec/tcpm/tcpci_rt1711h.c index 7b217c712c11a..a0e9e3fe8564c 100644 --- a/drivers/usb/typec/tcpm/tcpci_rt1711h.c +++ b/drivers/usb/typec/tcpm/tcpci_rt1711h.c @@ -327,8 +327,7 @@ static int rt1711h_check_revision(struct i2c_client *i2c, struct rt1711h_chip *c return ret; } -static int rt1711h_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) +static int rt1711h_probe(struct i2c_client *client) { int ret; struct rt1711h_chip *chip; @@ -413,7 +412,7 @@ static struct i2c_driver rt1711h_i2c_driver = { .name = "rt1711h", .of_match_table = of_match_ptr(rt1711h_of_match), }, - .probe = rt1711h_probe, + .probe_new = rt1711h_probe, .remove = rt1711h_remove, .id_table = rt1711h_id, }; -- GitLab From c852ec1c0192ff0ce032a1f0bbf23be01c98479d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:15 +0100 Subject: [PATCH 0639/1480] usb: typec: tcpm/tcpci_maxim: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Guenter Roeck Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221118224540.619276-582-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpci_maxim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c index 03f89e6f1a78e..83e140ffcc3e3 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -438,7 +438,7 @@ static int tcpci_init(struct tcpci *tcpci, struct tcpci_data *data) return -1; } -static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) +static int max_tcpci_probe(struct i2c_client *client) { int ret; struct max_tcpci_chip *chip; @@ -519,7 +519,7 @@ static struct i2c_driver max_tcpci_i2c_driver = { .name = "maxtcpc", .of_match_table = of_match_ptr(max_tcpci_of_match), }, - .probe = max_tcpci_probe, + .probe_new = max_tcpci_probe, .remove = max_tcpci_remove, .id_table = max_tcpci_id, }; -- GitLab From bdd0400d0f7245091ca8eff781825e93db1a135f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:14 +0100 Subject: [PATCH 0640/1480] usb: typec: tcpm/tcpci: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Guenter Roeck Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221118224540.619276-581-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 72f8d1e876004..fe781a38dc826 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -810,8 +810,7 @@ void tcpci_unregister_port(struct tcpci *tcpci) } EXPORT_SYMBOL_GPL(tcpci_unregister_port); -static int tcpci_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) +static int tcpci_probe(struct i2c_client *client) { struct tcpci_chip *chip; int err; @@ -881,7 +880,7 @@ static struct i2c_driver tcpci_i2c_driver = { .name = "tcpci", .of_match_table = of_match_ptr(tcpci_of_match), }, - .probe = tcpci_probe, + .probe_new = tcpci_probe, .remove = tcpci_remove, .id_table = tcpci_id, }; -- GitLab From 3646730ee44f42dd91619e30c917c0140853a948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:13 +0100 Subject: [PATCH 0641/1480] usb: typec: tcpm/fusb302: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Heikki Krogerus Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20221118224540.619276-580-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/fusb302.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c index 721b2a548084c..1ffce00d94b46 100644 --- a/drivers/usb/typec/tcpm/fusb302.c +++ b/drivers/usb/typec/tcpm/fusb302.c @@ -1677,8 +1677,7 @@ static struct fwnode_handle *fusb302_fwnode_get(struct device *dev) return fwnode; } -static int fusb302_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int fusb302_probe(struct i2c_client *client) { struct fusb302_chip *chip; struct i2c_adapter *adapter = client->adapter; @@ -1837,7 +1836,7 @@ static struct i2c_driver fusb302_driver = { .pm = &fusb302_pm_ops, .of_match_table = of_match_ptr(fusb302_dt_match), }, - .probe = fusb302_probe, + .probe_new = fusb302_probe, .remove = fusb302_remove, .id_table = fusb302_i2c_device_id, }; -- GitLab From b5583ea8b9ea659241e3f0cb8c9ca56f9a9630b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:12 +0100 Subject: [PATCH 0642/1480] usb: typec: hd3ss3220: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221118224540.619276-579-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/hd3ss3220.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index 2a58185fb14c4..f128664cb130a 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -148,8 +148,7 @@ static const struct regmap_config config = { .max_register = 0x0A, }; -static int hd3ss3220_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hd3ss3220_probe(struct i2c_client *client) { struct typec_capability typec_cap = { }; struct hd3ss3220 *hd3ss3220; @@ -264,7 +263,7 @@ static struct i2c_driver hd3ss3220_driver = { .name = "hd3ss3220", .of_match_table = of_match_ptr(dev_ids), }, - .probe = hd3ss3220_probe, + .probe_new = hd3ss3220_probe, .remove = hd3ss3220_remove, }; -- GitLab From cfb8e41ae81311eef73fc50e401e93543204de3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:11 +0100 Subject: [PATCH 0643/1480] usb: typec: anx7411: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-578-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/anx7411.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c index b8f3b75fd7eb9..3d5edce270a44 100644 --- a/drivers/usb/typec/anx7411.c +++ b/drivers/usb/typec/anx7411.c @@ -1440,8 +1440,7 @@ static int anx7411_psy_register(struct anx7411_data *ctx) return PTR_ERR_OR_ZERO(ctx->psy); } -static int anx7411_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int anx7411_i2c_probe(struct i2c_client *client) { struct anx7411_data *plat; struct device *dev = &client->dev; @@ -1585,7 +1584,7 @@ static struct i2c_driver anx7411_driver = { .of_match_table = anx_match_table, .pm = &anx7411_pm_ops, }, - .probe = anx7411_i2c_probe, + .probe_new = anx7411_i2c_probe, .remove = anx7411_i2c_remove, .id_table = anx7411_id, -- GitLab From 9f7cc30769ac0681669b963ede092f12afe829b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:10 +0100 Subject: [PATCH 0644/1480] usb: phy: isp1301: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-577-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/phy-isp1301.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index c2777a5c1f4ed..f4ee14d985853 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -92,8 +92,7 @@ static int isp1301_phy_set_vbus(struct usb_phy *phy, int on) return 0; } -static int isp1301_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) +static int isp1301_probe(struct i2c_client *client) { struct isp1301 *isp; struct usb_phy *phy; @@ -133,7 +132,7 @@ static struct i2c_driver isp1301_driver = { .name = DRV_NAME, .of_match_table = isp1301_of_match, }, - .probe = isp1301_probe, + .probe_new = isp1301_probe, .remove = isp1301_remove, .id_table = isp1301_id, }; -- GitLab From c3ed6965fe7400c97d806edb282ad08810acdee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:09 +0100 Subject: [PATCH 0645/1480] usb: isp1301-omap: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-576-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/phy-isp1301-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index e5d3f206097c7..931610b76f3d8 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -1471,7 +1471,7 @@ isp1301_start_hnp(struct usb_otg *otg) /*-------------------------------------------------------------------------*/ static int -isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +isp1301_probe(struct i2c_client *i2c) { int status; struct isp1301 *isp; @@ -1616,7 +1616,7 @@ static struct i2c_driver isp1301_driver = { .driver = { .name = "isp1301_omap", }, - .probe = isp1301_probe, + .probe_new = isp1301_probe, .remove = isp1301_remove, .id_table = isp1301_id, }; -- GitLab From d4468280d8bcd68a7303efcb5a404efb680de1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:08 +0100 Subject: [PATCH 0646/1480] usb: usb4604: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-575-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb4604.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/usb4604.c b/drivers/usb/misc/usb4604.c index 2142af9bbdecd..6b5e77231efa1 100644 --- a/drivers/usb/misc/usb4604.c +++ b/drivers/usb/misc/usb4604.c @@ -97,8 +97,7 @@ static int usb4604_probe(struct usb4604 *hub) return usb4604_switch_mode(hub, hub->mode); } -static int usb4604_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int usb4604_i2c_probe(struct i2c_client *i2c) { struct usb4604 *hub; @@ -155,7 +154,7 @@ static struct i2c_driver usb4604_i2c_driver = { .pm = pm_ptr(&usb4604_i2c_pm_ops), .of_match_table = of_match_ptr(usb4604_of_match), }, - .probe = usb4604_i2c_probe, + .probe_new = usb4604_i2c_probe, .id_table = usb4604_id, }; module_i2c_driver(usb4604_i2c_driver); -- GitLab From 4b1e537ad367b415f30fc37c1f4403ddd12a88d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:07 +0100 Subject: [PATCH 0647/1480] usb: misc: usb3503: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-574-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb3503.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index c70ca475c7c7e..bd47c4437ca46 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -280,8 +280,7 @@ err_clk: return err; } -static int usb3503_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int usb3503_i2c_probe(struct i2c_client *i2c) { struct usb3503 *hub; int err; @@ -400,7 +399,7 @@ static struct i2c_driver usb3503_i2c_driver = { .pm = pm_ptr(&usb3503_i2c_pm_ops), .of_match_table = of_match_ptr(usb3503_of_match), }, - .probe = usb3503_i2c_probe, + .probe_new = usb3503_i2c_probe, .remove = usb3503_i2c_remove, .id_table = usb3503_id, }; -- GitLab From 907140462eb511f3d98aa89c0665da1b618d3545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:06 +0100 Subject: [PATCH 0648/1480] usb: usb251xb: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Acked-by: Richard Leitner Link: https://lore.kernel.org/r/20221118224540.619276-573-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb251xb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index 54337d72bb9ff..e3abe67a155d0 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -699,8 +699,7 @@ static int usb251xb_probe(struct usb251xb *hub) return 0; } -static int usb251xb_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int usb251xb_i2c_probe(struct i2c_client *i2c) { struct usb251xb *hub; @@ -758,7 +757,7 @@ static struct i2c_driver usb251xb_i2c_driver = { .of_match_table = of_match_ptr(usb251xb_of_match), .pm = &usb251xb_pm_ops, }, - .probe = usb251xb_i2c_probe, + .probe_new = usb251xb_i2c_probe, .id_table = usb251xb_id, }; -- GitLab From 02a476d932287cf3096f78962ccb70d94d6203c6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Nov 2022 10:46:45 +0100 Subject: [PATCH 0649/1480] kobject: make kobject_get_ownership() take a constant kobject * The call, kobject_get_ownership(), does not modify the kobject passed into it, so make it const. This propagates down into the kobj_type function callbacks so make the kobject passed into them also const, ensuring that nothing in the kobject is being changed here. This helps make it more obvious what calls and callbacks do, and do not, modify structures passed to them. Cc: Trond Myklebust Cc: Anna Schumaker Cc: Roopa Prabhu Cc: "David S. Miller" Cc: Eric Dumazet Cc: Paolo Abeni Cc: Chuck Lever Cc: Jeff Layton Cc: linux-nfs@vger.kernel.org Cc: bridge@lists.linux-foundation.org Cc: netdev@vger.kernel.org Acked-by: Jakub Kicinski Acked-by: Rafael J. Wysocki Acked-by: Nikolay Aleksandrov Link: https://lore.kernel.org/r/20221121094649.1556002-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 2 +- drivers/base/core.c | 8 ++++---- fs/nfs/sysfs.c | 4 ++-- include/linux/kobject.h | 8 ++++---- lib/kobject.c | 4 ++-- net/bridge/br_if.c | 2 +- net/core/net-sysfs.c | 8 ++++---- net/sunrpc/sysfs.c | 8 ++++---- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 8ceafb7d0203b..86ec554cfe604 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -62,7 +62,7 @@ static void class_release(struct kobject *kobj) kfree(cp); } -static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj) +static const struct kobj_ns_type_operations *class_child_ns_type(const struct kobject *kobj) { struct subsys_private *cp = to_subsys_private(kobj); struct class *class = cp->class; diff --git a/drivers/base/core.c b/drivers/base/core.c index ab01828fe6c1f..a79b99ecf4d8b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2335,7 +2335,7 @@ static void device_release(struct kobject *kobj) kfree(p); } -static const void *device_namespace(struct kobject *kobj) +static const void *device_namespace(const struct kobject *kobj) { const struct device *dev = kobj_to_dev(kobj); const void *ns = NULL; @@ -2346,7 +2346,7 @@ static const void *device_namespace(struct kobject *kobj) return ns; } -static void device_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) +static void device_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { const struct device *dev = kobj_to_dev(kobj); @@ -2986,9 +2986,9 @@ static void class_dir_release(struct kobject *kobj) } static const -struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) +struct kobj_ns_type_operations *class_dir_child_ns_type(const struct kobject *kobj) { - struct class_dir *dir = to_class_dir(kobj); + const struct class_dir *dir = to_class_dir(kobj); return dir->class->ns_type; } diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c index a6f7403669631..67a87800b3a97 100644 --- a/fs/nfs/sysfs.c +++ b/fs/nfs/sysfs.c @@ -26,7 +26,7 @@ static void nfs_netns_object_release(struct kobject *kobj) } static const struct kobj_ns_type_operations *nfs_netns_object_child_ns_type( - struct kobject *kobj) + const struct kobject *kobj) { return &net_ns_type_operations; } @@ -130,7 +130,7 @@ static void nfs_netns_client_release(struct kobject *kobj) kfree(c); } -static const void *nfs_netns_client_namespace(struct kobject *kobj) +static const void *nfs_netns_client_namespace(const struct kobject *kobj) { return container_of(kobj, struct nfs_netns_client, kobject)->net; } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index fc40fc81aeb1d..d978dbceb50d1 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -113,7 +113,7 @@ extern struct kobject * __must_check kobject_get_unless_zero( extern void kobject_put(struct kobject *kobj); extern const void *kobject_namespace(struct kobject *kobj); -extern void kobject_get_ownership(struct kobject *kobj, +extern void kobject_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid); extern char *kobject_get_path(const struct kobject *kobj, gfp_t flag); @@ -121,9 +121,9 @@ struct kobj_type { void (*release)(struct kobject *kobj); const struct sysfs_ops *sysfs_ops; const struct attribute_group **default_groups; - const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); - const void *(*namespace)(struct kobject *kobj); - void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid); + const struct kobj_ns_type_operations *(*child_ns_type)(const struct kobject *kobj); + const void *(*namespace)(const struct kobject *kobj); + void (*get_ownership)(const struct kobject *kobj, kuid_t *uid, kgid_t *gid); }; struct kobj_uevent_env { diff --git a/lib/kobject.c b/lib/kobject.c index ba1017cd67d16..26e744a46d247 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -45,7 +45,7 @@ const void *kobject_namespace(struct kobject *kobj) * representation of given kobject. Normally used to adjust ownership of * objects in a container. */ -void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) +void kobject_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { *uid = GLOBAL_ROOT_UID; *gid = GLOBAL_ROOT_GID; @@ -907,7 +907,7 @@ static void kset_release(struct kobject *kobj) kfree(kset); } -static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) +static void kset_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { if (kobj->parent) kobject_get_ownership(kobj->parent, uid, gid); diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 228fd5b20f109..ad13b48e3e08a 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -262,7 +262,7 @@ static void release_nbp(struct kobject *kobj) kfree(p); } -static void brport_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) +static void brport_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { struct net_bridge_port *p = kobj_to_brport(kobj); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index a8c5a7cd9701d..9cfc80b8ed25f 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1020,7 +1020,7 @@ static void rx_queue_release(struct kobject *kobj) netdev_put(queue->dev, &queue->dev_tracker); } -static const void *rx_queue_namespace(struct kobject *kobj) +static const void *rx_queue_namespace(const struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); struct device *dev = &queue->dev->dev; @@ -1032,7 +1032,7 @@ static const void *rx_queue_namespace(struct kobject *kobj) return ns; } -static void rx_queue_get_ownership(struct kobject *kobj, +static void rx_queue_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { const struct net *net = rx_queue_namespace(kobj); @@ -1623,7 +1623,7 @@ static void netdev_queue_release(struct kobject *kobj) netdev_put(queue->dev, &queue->dev_tracker); } -static const void *netdev_queue_namespace(struct kobject *kobj) +static const void *netdev_queue_namespace(const struct kobject *kobj) { struct netdev_queue *queue = to_netdev_queue(kobj); struct device *dev = &queue->dev->dev; @@ -1635,7 +1635,7 @@ static const void *netdev_queue_namespace(struct kobject *kobj) return ns; } -static void netdev_queue_get_ownership(struct kobject *kobj, +static void netdev_queue_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid) { const struct net *net = netdev_queue_namespace(kobj); diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index c1f559892ae8a..1e05a2d723f4c 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -31,7 +31,7 @@ static void rpc_sysfs_object_release(struct kobject *kobj) } static const struct kobj_ns_type_operations * -rpc_sysfs_object_child_ns_type(struct kobject *kobj) +rpc_sysfs_object_child_ns_type(const struct kobject *kobj) { return &net_ns_type_operations; } @@ -381,17 +381,17 @@ static void rpc_sysfs_xprt_release(struct kobject *kobj) kfree(xprt); } -static const void *rpc_sysfs_client_namespace(struct kobject *kobj) +static const void *rpc_sysfs_client_namespace(const struct kobject *kobj) { return container_of(kobj, struct rpc_sysfs_client, kobject)->net; } -static const void *rpc_sysfs_xprt_switch_namespace(struct kobject *kobj) +static const void *rpc_sysfs_xprt_switch_namespace(const struct kobject *kobj) { return container_of(kobj, struct rpc_sysfs_xprt_switch, kobject)->net; } -static const void *rpc_sysfs_xprt_namespace(struct kobject *kobj) +static const void *rpc_sysfs_xprt_namespace(const struct kobject *kobj) { return container_of(kobj, struct rpc_sysfs_xprt, kobject)->xprt->xprt_net; -- GitLab From 542aa24646ca20ccedb70829a95254ce602cdcbd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Nov 2022 10:46:46 +0100 Subject: [PATCH 0650/1480] kobject: make kobject_namespace take a const * kobject_namespace() should take a const *kobject as it does not modify the kobject passed to it. Change that, and the functions kobj_child_ns_ops() and kobj_ns_ops() needed to also be changed to const *. Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221121094649.1556002-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 +- include/linux/kobject_ns.h | 4 ++-- lib/kobject.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/linux/kobject.h b/include/linux/kobject.h index d978dbceb50d1..5a2d58e10bf55 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -112,7 +112,7 @@ extern struct kobject * __must_check kobject_get_unless_zero( struct kobject *kobj); extern void kobject_put(struct kobject *kobj); -extern const void *kobject_namespace(struct kobject *kobj); +extern const void *kobject_namespace(const struct kobject *kobj); extern void kobject_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid); extern char *kobject_get_path(const struct kobject *kobj, gfp_t flag); diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h index 2b5b64256cf4b..be707748e7cec 100644 --- a/include/linux/kobject_ns.h +++ b/include/linux/kobject_ns.h @@ -47,8 +47,8 @@ struct kobj_ns_type_operations { int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); int kobj_ns_type_registered(enum kobj_ns_type type); -const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); -const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); +const struct kobj_ns_type_operations *kobj_child_ns_ops(const struct kobject *parent); +const struct kobj_ns_type_operations *kobj_ns_ops(const struct kobject *kobj); bool kobj_ns_current_may_mount(enum kobj_ns_type type); void *kobj_ns_grab_current(enum kobj_ns_type type); diff --git a/lib/kobject.c b/lib/kobject.c index 26e744a46d247..6e0bf03f4f364 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -25,7 +25,7 @@ * and thus @kobj should have a namespace tag associated with it. Returns * %NULL otherwise. */ -const void *kobject_namespace(struct kobject *kobj) +const void *kobject_namespace(const struct kobject *kobj) { const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj); @@ -1039,7 +1039,7 @@ int kobj_ns_type_registered(enum kobj_ns_type type) return registered; } -const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent) +const struct kobj_ns_type_operations *kobj_child_ns_ops(const struct kobject *parent) { const struct kobj_ns_type_operations *ops = NULL; @@ -1049,7 +1049,7 @@ const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent) return ops; } -const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj) +const struct kobj_ns_type_operations *kobj_ns_ops(const struct kobject *kobj) { return kobj_child_ns_ops(kobj->parent); } -- GitLab From c45a88bb3f6cdaeb29d8ee98463610ad815721ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Nov 2022 10:46:47 +0100 Subject: [PATCH 0651/1480] kobject: kset_uevent_ops: make filter() callback take a const * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filter() callback in struct kset_uevent_ops does not modify the kobject passed into it, so make the pointer const to enforce this restriction. When doing so, fix up all existing filter() callbacks to have the correct signature to preserve the build. Cc: Sumit Semwal Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Acked-by: Rafael J. Wysocki Acked-by: Christian König for the changes to Link: https://lore.kernel.org/r/20221121094649.1556002-3-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 2 +- drivers/base/core.c | 4 ++-- drivers/dma-buf/dma-buf-sysfs-stats.c | 2 +- include/linux/kobject.h | 2 +- kernel/params.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 7ca47e5b3c1f4..4ec6dbab73be5 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -163,7 +163,7 @@ static struct kobj_type bus_ktype = { .release = bus_release, }; -static int bus_uevent_filter(struct kobject *kobj) +static int bus_uevent_filter(const struct kobject *kobj) { const struct kobj_type *ktype = get_ktype(kobj); diff --git a/drivers/base/core.c b/drivers/base/core.c index a79b99ecf4d8b..005a2b092f3ee 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2362,12 +2362,12 @@ static struct kobj_type device_ktype = { }; -static int dev_uevent_filter(struct kobject *kobj) +static int dev_uevent_filter(const struct kobject *kobj) { const struct kobj_type *ktype = get_ktype(kobj); if (ktype == &device_ktype) { - struct device *dev = kobj_to_dev(kobj); + const struct device *dev = kobj_to_dev(kobj); if (dev->bus) return 1; if (dev->class) diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/dma-buf-sysfs-stats.c index 2bba0babcb62b..f69d68122b9b1 100644 --- a/drivers/dma-buf/dma-buf-sysfs-stats.c +++ b/drivers/dma-buf/dma-buf-sysfs-stats.c @@ -132,7 +132,7 @@ void dma_buf_stats_teardown(struct dma_buf *dmabuf) /* Statistics files do not need to send uevents. */ -static int dmabuf_sysfs_uevent_filter(struct kobject *kobj) +static int dmabuf_sysfs_uevent_filter(const struct kobject *kobj) { return 0; } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 5a2d58e10bf55..640f59d4b3de7 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -135,7 +135,7 @@ struct kobj_uevent_env { }; struct kset_uevent_ops { - int (* const filter)(struct kobject *kobj); + int (* const filter)(const struct kobject *kobj); const char *(* const name)(struct kobject *kobj); int (* const uevent)(struct kobject *kobj, struct kobj_uevent_env *env); }; diff --git a/kernel/params.c b/kernel/params.c index 5b92310425c50..d2237209cedac 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -926,7 +926,7 @@ static const struct sysfs_ops module_sysfs_ops = { .store = module_attr_store, }; -static int uevent_filter(struct kobject *kobj) +static int uevent_filter(const struct kobject *kobj) { const struct kobj_type *ktype = get_ktype(kobj); -- GitLab From a53d1acc978321734a8fd7388f2c050a7219ab69 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Nov 2022 10:46:48 +0100 Subject: [PATCH 0652/1480] kobject: kset_uevent_ops: make name() callback take a const * The name() callback in struct kset_uevent_ops does not modify the kobject passed into it, so make the pointer const to enforce this restriction. When doing so, fix up the single existing name() callback to have the correct signature to preserve the build. Acked-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20221121094649.1556002-4-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- include/linux/kobject.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 005a2b092f3ee..a3e14143ec0cf 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2376,9 +2376,9 @@ static int dev_uevent_filter(const struct kobject *kobj) return 0; } -static const char *dev_uevent_name(struct kobject *kobj) +static const char *dev_uevent_name(const struct kobject *kobj) { - struct device *dev = kobj_to_dev(kobj); + const struct device *dev = kobj_to_dev(kobj); if (dev->bus) return dev->bus->name; diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 640f59d4b3de7..58a5b75612e35 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -136,7 +136,7 @@ struct kobj_uevent_env { struct kset_uevent_ops { int (* const filter)(const struct kobject *kobj); - const char *(* const name)(struct kobject *kobj); + const char *(* const name)(const struct kobject *kobj); int (* const uevent)(struct kobject *kobj, struct kobj_uevent_env *env); }; -- GitLab From 9f041c5d8296b3a04cf3ead473a124fb538490dc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Nov 2022 10:46:49 +0100 Subject: [PATCH 0653/1480] driver core: pass a const * into of_device_uevent() of_device_uevent() does not modify the struct device * passed into it, so make it a const * to enforce this. Also the documentation for the function was really wrong so fix that up at the same time. Cc: Rob Herring Cc: Frank Rowand Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20221121094649.1556002-5-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/of/device.c | 6 +++--- include/linux/of_device.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/of/device.c b/drivers/of/device.c index 8cefe5a7d04e2..c674a13c30558 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -332,10 +332,10 @@ EXPORT_SYMBOL_GPL(of_device_modalias); /** * of_device_uevent - Display OF related uevent information - * @dev: Device to apply DMA configuration - * @env: Kernel object's userspace event reference + * @dev: Device to display the uevent information for + * @env: Kernel object's userspace event reference to fill up */ -void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) +void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env) { const char *compat, *type; struct alias_prop *app; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 1a803e4335d30..ab7d557d541d5 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -35,7 +35,7 @@ extern const void *of_device_get_match_data(const struct device *dev); extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_request_module(struct device *dev); -extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +extern void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env); extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env); static inline struct device_node *of_cpu_device_node_get(int cpu) @@ -64,7 +64,7 @@ static inline int of_driver_match_device(struct device *dev, return 0; } -static inline void of_device_uevent(struct device *dev, +static inline void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env) { } static inline const void *of_device_get_match_data(const struct device *dev) -- GitLab From 947d66b68f3c4e7cf8f3f3500807b9d2a0de28ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Fri, 11 Nov 2022 16:25:02 +0200 Subject: [PATCH 0654/1480] n_tty: Rename tail to old_tail in n_tty_read() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The local tail variable in n_tty_read() is used for one purpose, it keeps the old tail. Thus, rename it appropriately to improve code readability. Signed-off-by: Ilpo Järvinen Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/22b37499-ff9a-7fc1-f6e0-58411328d122@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 597019690ae62..c8f56c9b1a1c8 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2130,7 +2130,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, ssize_t retval = 0; long timeout; bool packet; - size_t tail; + size_t old_tail; /* * Is this a continuation of a read started earler? @@ -2193,7 +2193,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, } packet = tty->ctrl.packet; - tail = ldata->read_tail; + old_tail = ldata->read_tail; add_wait_queue(&tty->read_wait, &wait); while (nr) { @@ -2282,7 +2282,7 @@ more_to_be_read: if (time) timeout = time; } - if (tail != ldata->read_tail) + if (old_tail != ldata->read_tail) n_tty_kick_worker(tty); up_read(&tty->termios_rwsem); -- GitLab From cbdf6759e5b798b35ceafbae50fb7dd2340c9751 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 15 Nov 2022 08:17:21 +0100 Subject: [PATCH 0655/1480] tty: serial: altera_jtaguart: remove flag from altera_jtaguart_rx_chars() TTY_NORMAL is the only value it contains, so remove the variable and use the constant instead. Cc: Tobias Klauser Signed-off-by: Jiri Slaby (SUSE) Reviewed-by: Tobias Klauser Link: https://lore.kernel.org/r/20221115071724.5185-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index aa49553fac584..8d17297115841 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -126,18 +126,17 @@ static void altera_jtaguart_set_termios(struct uart_port *port, static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) { struct uart_port *port = &pp->port; - unsigned char ch, flag; + unsigned char ch; unsigned long status; while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & ALTERA_JTAGUART_DATA_RVALID_MSK) { ch = status & ALTERA_JTAGUART_DATA_DATA_MSK; - flag = TTY_NORMAL; port->icount.rx++; if (uart_handle_sysrq_char(port, ch)) continue; - uart_insert_char(port, 0, 0, ch, flag); + uart_insert_char(port, 0, 0, ch, TTY_NORMAL); } tty_flip_buffer_push(&port->state->port); -- GitLab From 070fa1d2bf089937559183320c4066c065312665 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 15 Nov 2022 08:17:22 +0100 Subject: [PATCH 0656/1480] tty: serial: altera_jtaguart: remove unused altera_jtaguart::sigs Nothing uses struct altera_jtaguart::sigs. Remove it. Cc: Tobias Klauser Signed-off-by: Jiri Slaby (SUSE) Reviewed-by: Tobias Klauser Link: https://lore.kernel.org/r/20221115071724.5185-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 8d17297115841..b83eade64b220 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -55,7 +55,6 @@ */ struct altera_jtaguart { struct uart_port port; - unsigned int sigs; /* Local copy of line sigs */ unsigned long imr; /* Local IMR mirror */ }; -- GitLab From 4e2b16a62d9975c4f6135e6a79a8e00cbad812d6 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 15 Nov 2022 08:17:23 +0100 Subject: [PATCH 0657/1480] tty: serial: altera_jtaguart: use uart_port::read_status_mask Instead of self-defined struct altera_jtaguart::imr, use preexisting uart_port::read_status_mask. Note that imr was ulong. But there is no reason for that, its values are uints. And readl/writel's are used to read it/write to it. Cc: Tobias Klauser Signed-off-by: Jiri Slaby (SUSE) Reviewed-by: Tobias Klauser Link: https://lore.kernel.org/r/20221115071724.5185-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 41 +++++++++++----------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index b83eade64b220..6808abd277853 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -55,7 +55,6 @@ */ struct altera_jtaguart { struct uart_port port; - unsigned long imr; /* Local IMR mirror */ }; static unsigned int altera_jtaguart_tx_space(struct uart_port *port, u32 *ctlp) @@ -84,29 +83,23 @@ static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs) static void altera_jtaguart_start_tx(struct uart_port *port) { - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); - - pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK; - writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); + port->read_status_mask |= ALTERA_JTAGUART_CONTROL_WE_MSK; + writel(port->read_status_mask, + port->membase + ALTERA_JTAGUART_CONTROL_REG); } static void altera_jtaguart_stop_tx(struct uart_port *port) { - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); - - pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; - writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); + port->read_status_mask &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; + writel(port->read_status_mask, + port->membase + ALTERA_JTAGUART_CONTROL_REG); } static void altera_jtaguart_stop_rx(struct uart_port *port) { - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); - - pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK; - writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); + port->read_status_mask &= ~ALTERA_JTAGUART_CONTROL_RE_MSK; + writel(port->read_status_mask, + port->membase + ALTERA_JTAGUART_CONTROL_REG); } static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state) @@ -163,7 +156,7 @@ static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) unsigned int isr; isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> - ALTERA_JTAGUART_CONTROL_RI_OFF) & pp->imr; + ALTERA_JTAGUART_CONTROL_RI_OFF) & port->read_status_mask; spin_lock(&port->lock); @@ -187,8 +180,6 @@ static void altera_jtaguart_config_port(struct uart_port *port, int flags) static int altera_jtaguart_startup(struct uart_port *port) { - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); unsigned long flags; int ret; @@ -203,8 +194,9 @@ static int altera_jtaguart_startup(struct uart_port *port) spin_lock_irqsave(&port->lock, flags); /* Enable RX interrupts now */ - pp->imr = ALTERA_JTAGUART_CONTROL_RE_MSK; - writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); + port->read_status_mask = ALTERA_JTAGUART_CONTROL_RE_MSK; + writel(port->read_status_mask, + port->membase + ALTERA_JTAGUART_CONTROL_REG); spin_unlock_irqrestore(&port->lock, flags); @@ -213,15 +205,14 @@ static int altera_jtaguart_startup(struct uart_port *port) static void altera_jtaguart_shutdown(struct uart_port *port) { - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); unsigned long flags; spin_lock_irqsave(&port->lock, flags); /* Disable all interrupts now */ - pp->imr = 0; - writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); + port->read_status_mask = 0; + writel(port->read_status_mask, + port->membase + ALTERA_JTAGUART_CONTROL_REG); spin_unlock_irqrestore(&port->lock, flags); -- GitLab From 4d167f635a4d33f6b645f60c2a265f93668fdd8d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 15 Nov 2022 08:17:24 +0100 Subject: [PATCH 0658/1480] tty: serial: altera_jtaguart: remove struct altera_jtaguart It contains only struct uart_port, so no need for another structure. Remove it and convert the rest to use struct uart_port directly. Cc: Tobias Klauser Signed-off-by: Jiri Slaby (SUSE) Reviewed-by: Tobias Klauser Link: https://lore.kernel.org/r/20221115071724.5185-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 29 +++++++++------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 6808abd277853..9f843d1cee40e 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -50,13 +50,6 @@ #define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400 #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000 -/* - * Local per-uart structure. - */ -struct altera_jtaguart { - struct uart_port port; -}; - static unsigned int altera_jtaguart_tx_space(struct uart_port *port, u32 *ctlp) { u32 ctl = readl(port->membase + ALTERA_JTAGUART_CONTROL_REG); @@ -115,9 +108,8 @@ static void altera_jtaguart_set_termios(struct uart_port *port, tty_termios_copy_hw(termios, old); } -static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) +static void altera_jtaguart_rx_chars(struct uart_port *port) { - struct uart_port *port = &pp->port; unsigned char ch; unsigned long status; @@ -134,9 +126,8 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) tty_flip_buffer_push(&port->state->port); } -static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) +static void altera_jtaguart_tx_chars(struct uart_port *port) { - struct uart_port *port = &pp->port; unsigned int count; u8 ch; @@ -151,8 +142,6 @@ static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) { struct uart_port *port = data; - struct altera_jtaguart *pp = - container_of(port, struct altera_jtaguart, port); unsigned int isr; isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> @@ -161,9 +150,9 @@ static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) spin_lock(&port->lock); if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) - altera_jtaguart_rx_chars(pp); + altera_jtaguart_rx_chars(port); if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) - altera_jtaguart_tx_chars(pp); + altera_jtaguart_tx_chars(port); spin_unlock(&port->lock); @@ -265,7 +254,7 @@ static const struct uart_ops altera_jtaguart_ops = { }; #define ALTERA_JTAGUART_MAXPORTS 1 -static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; +static struct uart_port altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) @@ -308,7 +297,7 @@ static void altera_jtaguart_console_putc(struct uart_port *port, unsigned char c static void altera_jtaguart_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; + struct uart_port *port = &altera_jtaguart_ports[co->index]; uart_console_write(port, s, count, altera_jtaguart_console_putc); } @@ -320,7 +309,7 @@ static int __init altera_jtaguart_console_setup(struct console *co, if (co->index < 0 || co->index >= ALTERA_JTAGUART_MAXPORTS) return -EINVAL; - port = &altera_jtaguart_ports[co->index].port; + port = &altera_jtaguart_ports[co->index]; if (port->membase == NULL) return -ENODEV; return 0; @@ -400,7 +389,7 @@ static int altera_jtaguart_probe(struct platform_device *pdev) if (i >= ALTERA_JTAGUART_MAXPORTS) return -EINVAL; - port = &altera_jtaguart_ports[i].port; + port = &altera_jtaguart_ports[i]; res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) @@ -444,7 +433,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev) if (i == -1) i = 0; - port = &altera_jtaguart_ports[i].port; + port = &altera_jtaguart_ports[i]; uart_remove_one_port(&altera_jtaguart_driver, port); iounmap(port->membase); -- GitLab From 94cdb9f33698478b0e7062586633c42c6158a786 Mon Sep 17 00:00:00 2001 From: Jiamei Xie Date: Thu, 17 Nov 2022 18:32:37 +0800 Subject: [PATCH 0659/1480] serial: amba-pl011: avoid SBSA UART accessing DMACR register Chapter "B Generic UART" in "ARM Server Base System Architecture" [1] documentation describes a generic UART interface. Such generic UART does not support DMA. In current code, sbsa_uart_pops and amba_pl011_pops share the same stop_rx operation, which will invoke pl011_dma_rx_stop, leading to an access of the DMACR register. This commit adds a using_rx_dma check in pl011_dma_rx_stop to avoid the access to DMACR register for SBSA UARTs which does not support DMA. When the kernel enables DMA engine with "CONFIG_DMA_ENGINE=y", Linux SBSA PL011 driver will access PL011 DMACR register in some functions. For most real SBSA Pl011 hardware implementations, the DMACR write behaviour will be ignored. So these DMACR operations will not cause obvious problems. But for some virtual SBSA PL011 hardware, like Xen virtual SBSA PL011 (vpl011) device, the behaviour might be different. Xen vpl011 emulation will inject a data abort to guest, when guest is accessing an unimplemented UART register. As Xen VPL011 is SBSA compatible, it will not implement DMACR register. So when Linux SBSA PL011 driver access DMACR register, it will get an unhandled data abort fault and the application will get a segmentation fault: Unhandled fault at 0xffffffc00944d048 Mem abort info: ESR = 0x96000000 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x00: ttbr address size fault Data abort info: ISV = 0, ISS = 0x00000000 CM = 0, WnR = 0 swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000020e2e000 [ffffffc00944d048] pgd=100000003ffff803, p4d=100000003ffff803, pud=100000003ffff803, pmd=100000003fffa803, pte=006800009c090f13 Internal error: ttbr address size fault: 96000000 [#1] PREEMPT SMP ... Call trace: pl011_stop_rx+0x70/0x80 tty_port_shutdown+0x7c/0xb4 tty_port_close+0x60/0xcc uart_close+0x34/0x8c tty_release+0x144/0x4c0 __fput+0x78/0x220 ____fput+0x1c/0x30 task_work_run+0x88/0xc0 do_notify_resume+0x8d0/0x123c el0_svc+0xa8/0xc0 el0t_64_sync_handler+0xa4/0x130 el0t_64_sync+0x1a0/0x1a4 Code: b9000083 b901f001 794038a0 8b000042 (b9000041) ---[ end trace 83dd93df15c3216f ]--- note: bootlogd[132] exited with preempt_count 1 /etc/rcS.d/S07bootlogd: line 47: 132 Segmentation fault start-stop-daemon This has been discussed in the Xen community, and we think it should fix this in Linux. See [2] for more information. [1] https://developer.arm.com/documentation/den0094/c/?lang=en [2] https://lists.xenproject.org/archives/html/xen-devel/2022-11/msg00543.html Fixes: 0dd1e247fd39 (drivers: PL011: add support for the ARM SBSA generic UART) Signed-off-by: Jiamei Xie Reviewed-by: Andre Przywara Link: https://lore.kernel.org/r/20221117103237.86856-1-jiamei.xie@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6d8552506091c..6b9deb4211b5e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1044,6 +1044,9 @@ static void pl011_dma_rx_callback(void *data) */ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap) { + if (!uap->using_rx_dma) + return; + /* FIXME. Just disable the DMA enable */ uap->dmacr &= ~UART011_RXDMAE; pl011_write(uap->dmacr, uap, REG_DMACR); -- GitLab From 032d5a71ed378ffc6a2d41a187d8488a4f9fe415 Mon Sep 17 00:00:00 2001 From: delisun Date: Thu, 10 Nov 2022 10:01:08 +0800 Subject: [PATCH 0660/1480] serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clearing the RX FIFO will cause data loss. Copy the pl011_enabl_interrupts implementation, and remove the clear interrupt and FIFO part of the code. Fixes: 211565b10099 ("serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle") Signed-off-by: delisun Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20221110020108.7700-1-delisun@pateo.com.cn Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6b9deb4211b5e..d75c39f4622b7 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1830,8 +1830,17 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) static void pl011_unthrottle_rx(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); + unsigned long flags; - pl011_enable_interrupts(uap); + spin_lock_irqsave(&uap->port.lock, flags); + + uap->im = UART011_RTIM; + if (!pl011_dma_rx_running(uap)) + uap->im |= UART011_RXIM; + + pl011_write(uap->im, uap, REG_IMSC); + + spin_unlock_irqrestore(&uap->port.lock, flags); } static int pl011_startup(struct uart_port *port) -- GitLab From b30e66863c60bb5c7da2151a65afb2ee419b9df4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 11 Nov 2022 15:28:38 -0600 Subject: [PATCH 0661/1480] dt-bindings: serial: xlnx,opb-uartlite: Drop 'contains' from 'xlnx,use-parity' 'contains' applies to arrays, but 'xlnx,use-parity' is a scalar. So drop 'contains' from the 'if' schema. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20221111212838.4103828-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/xlnx,opb-uartlite.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml b/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml index f7617b88c7c36..2f4390e8d4e88 100644 --- a/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml +++ b/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml @@ -67,8 +67,7 @@ allOf: - if: properties: xlnx,use-parity: - contains: - const: 1 + const: 1 then: required: - xlnx,odd-parity -- GitLab From 0d114e9ff940ebad8e88267013bf96c605a6b336 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Fri, 18 Nov 2022 18:06:02 +0100 Subject: [PATCH 0662/1480] serial: stm32: move dma_request_chan() before clk_prepare_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If dma_request_chan() returns a PROBE_DEFER error, clk_disable_unprepare() will be called and USART clock will be disabled. But early console can be still active on the same USART. While moving dma_request_chan() before clk_prepare_enable(), the clock won't be taken in case of a DMA PROBE_DEFER error, and so it doesn't need to be disabled. Then USART is still clocked for early console. Fixes: a7770a4bfcf4 ("serial: stm32: defer probe for dma devices") Reported-by: Uwe Kleine-König Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20221118170602.1057863-1-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 47 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 24def72b25653..a1490033aa164 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1680,22 +1680,10 @@ static int stm32_usart_serial_probe(struct platform_device *pdev) if (!stm32port->info) return -EINVAL; - ret = stm32_usart_init_port(stm32port, pdev); - if (ret) - return ret; - - if (stm32port->wakeup_src) { - device_set_wakeup_capable(&pdev->dev, true); - ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq); - if (ret) - goto err_deinit_port; - } - stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx"); - if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto err_wakeirq; - } + if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) + return -EPROBE_DEFER; + /* Fall back in interrupt mode for any non-deferral error */ if (IS_ERR(stm32port->rx_ch)) stm32port->rx_ch = NULL; @@ -1709,6 +1697,17 @@ static int stm32_usart_serial_probe(struct platform_device *pdev) if (IS_ERR(stm32port->tx_ch)) stm32port->tx_ch = NULL; + ret = stm32_usart_init_port(stm32port, pdev); + if (ret) + goto err_dma_tx; + + if (stm32port->wakeup_src) { + device_set_wakeup_capable(&pdev->dev, true); + ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq); + if (ret) + goto err_deinit_port; + } + if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) { /* Fall back in interrupt mode */ dma_release_channel(stm32port->rx_ch); @@ -1745,19 +1744,11 @@ err_port: pm_runtime_set_suspended(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); - if (stm32port->tx_ch) { + if (stm32port->tx_ch) stm32_usart_of_dma_tx_remove(stm32port, pdev); - dma_release_channel(stm32port->tx_ch); - } - if (stm32port->rx_ch) stm32_usart_of_dma_rx_remove(stm32port, pdev); -err_dma_rx: - if (stm32port->rx_ch) - dma_release_channel(stm32port->rx_ch); - -err_wakeirq: if (stm32port->wakeup_src) dev_pm_clear_wake_irq(&pdev->dev); @@ -1767,6 +1758,14 @@ err_deinit_port: stm32_usart_deinit_port(stm32port); +err_dma_tx: + if (stm32port->tx_ch) + dma_release_channel(stm32port->tx_ch); + +err_dma_rx: + if (stm32port->rx_ch) + dma_release_channel(stm32port->rx_ch); + return ret; } -- GitLab From 24ce048b0d4d4d8542c26459e53be4b7840d374c Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Tue, 15 Nov 2022 09:38:32 -0800 Subject: [PATCH 0663/1480] tty: synclink_gt: unwind actions in error path of net device open Resent again, last attempt still altered the plain text. Zhengchao Shao identified by inspection bugs in the error path of hdlcdev_open() in synclink_gt.c The function did not fully unwind actions in the error path. The use of try_module_get()/module_put() is unnecessary, potentially hazardous and is removed. The synclink_gt driver is already pinned any point the net device is registered, a requirement for calling this entry point. The call hdlc_open() to init the generic HDLC layer is moved to after driver level init/checks and proper rollback of previous actions is added. This is a more sensible ordering as the most common error paths are at the driver level and the driver level rollbacks require less processing than hdlc_open()/hdlc_close(). This has been tested with supported hardware. Signed-off-by:Paul Fulghum Link: https://lore.kernel.org/r/7599F007-8985-4469-BE00-52BD1530210E@microgate.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 25e9befdda3a8..72b76cdde534d 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1433,16 +1433,8 @@ static int hdlcdev_open(struct net_device *dev) int rc; unsigned long flags; - if (!try_module_get(THIS_MODULE)) - return -EBUSY; - DBGINFO(("%s hdlcdev_open\n", dev->name)); - /* generic HDLC layer open processing */ - rc = hdlc_open(dev); - if (rc) - return rc; - /* arbitrate between network and tty opens */ spin_lock_irqsave(&info->netlock, flags); if (info->port.count != 0 || info->netcount != 0) { @@ -1461,6 +1453,16 @@ static int hdlcdev_open(struct net_device *dev) return rc; } + /* generic HDLC layer open processing */ + rc = hdlc_open(dev); + if (rc) { + shutdown(info); + spin_lock_irqsave(&info->netlock, flags); + info->netcount = 0; + spin_unlock_irqrestore(&info->netlock, flags); + return rc; + } + /* assert RTS and DTR, apply hardware settings */ info->signals |= SerialSignal_RTS | SerialSignal_DTR; program_hw(info); @@ -1506,7 +1508,6 @@ static int hdlcdev_close(struct net_device *dev) info->netcount=0; spin_unlock_irqrestore(&info->netlock, flags); - module_put(THIS_MODULE); return 0; } -- GitLab From 96e8298945010d4b0a0c21841566401848a42afc Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 14 Nov 2022 17:18:13 +0200 Subject: [PATCH 0664/1480] serdev: Replace poll loop by readx_poll_timeout() macro The readx_poll_timeout() consolidates the necessary code under macro. Replace current code with it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221114151813.37294-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/serdev.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 66f624fc618ca..5f6bfe4f6d955 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -279,18 +280,10 @@ static inline bool serdev_device_get_cts(struct serdev_device *serdev) static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms) { - unsigned long timeout; bool signal; - timeout = jiffies + msecs_to_jiffies(timeout_ms); - while (time_is_after_jiffies(timeout)) { - signal = serdev_device_get_cts(serdev); - if (signal == state) - return 0; - usleep_range(1000, 2000); - } - - return -ETIMEDOUT; + return readx_poll_timeout(serdev_device_get_cts, serdev, signal, signal == state, + 2000, timeout_ms * 1000); } static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable) -- GitLab From 4f5cb8c5e9151c678fc2be533c070c6f7522940e Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Thu, 10 Nov 2022 19:38:57 +0800 Subject: [PATCH 0665/1480] tty: serial: fsl_lpuart: enable wakeup source for lpuart LPUART supports both synchronous wakeup and asynchronous wakeup(wakeup the system when the UART clocks are shut-off), the synchronous wakeup is configured by UARTCTRL_RIE interrupt, and the asynchronous wakeup is configured by UARTBAUD_RXEDGIE interrupt. Add lpuart_uport_is_active() to determine if the uart port needs to get into the suspend states, also add lpuart_suspend_noirq() and lpuart_resume_noirq() to enable and disable the wakeup irq bits if the uart port needs to be set as wakeup source. When use lpuart with DMA mode, it still needs to switch to the cpu mode in .suspend() that enable cpu interrupts RIE and RXEDGIE as wakeup source, after system resume back, needs to setup DMA again, .resume() will share the HW setup code with .startup(), so abstract the same code to the api like lpuart32_hw_setup(). Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20221110113859.8485-2-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 281 +++++++++++++++++++++++--------- 1 file changed, 200 insertions(+), 81 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index bd685491eead2..07c1524ef0087 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -1627,10 +1628,23 @@ err: sport->lpuart_dma_rx_use = false; } +static void lpuart_hw_setup(struct lpuart_port *sport) +{ + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock, flags); + + lpuart_setup_watermark_enable(sport); + + lpuart_rx_dma_startup(sport); + lpuart_tx_dma_startup(sport); + + spin_unlock_irqrestore(&sport->port.lock, flags); +} + static int lpuart_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long flags; unsigned char temp; /* determine FIFO size and enable FIFO mode */ @@ -1644,15 +1658,7 @@ static int lpuart_startup(struct uart_port *port) UARTPFIFO_FIFOSIZE_MASK); lpuart_request_dma(sport); - - spin_lock_irqsave(&sport->port.lock, flags); - - lpuart_setup_watermark_enable(sport); - - lpuart_rx_dma_startup(sport); - lpuart_tx_dma_startup(sport); - - spin_unlock_irqrestore(&sport->port.lock, flags); + lpuart_hw_setup(sport); return 0; } @@ -1675,10 +1681,25 @@ static void lpuart32_configure(struct lpuart_port *sport) lpuart32_write(&sport->port, temp, UARTCTRL); } +static void lpuart32_hw_setup(struct lpuart_port *sport) +{ + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock, flags); + + lpuart32_setup_watermark_enable(sport); + + lpuart_rx_dma_startup(sport); + lpuart_tx_dma_startup(sport); + + lpuart32_configure(sport); + + spin_unlock_irqrestore(&sport->port.lock, flags); +} + static int lpuart32_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long flags; unsigned long temp; /* determine FIFO size */ @@ -1703,17 +1724,8 @@ static int lpuart32_startup(struct uart_port *port) } lpuart_request_dma(sport); + lpuart32_hw_setup(sport); - spin_lock_irqsave(&sport->port.lock, flags); - - lpuart32_setup_watermark_enable(sport); - - lpuart_rx_dma_startup(sport); - lpuart_tx_dma_startup(sport); - - lpuart32_configure(sport); - - spin_unlock_irqrestore(&sport->port.lock, flags); return 0; } @@ -2766,97 +2778,204 @@ static int lpuart_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused lpuart_suspend(struct device *dev) +static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on) { - struct lpuart_port *sport = dev_get_drvdata(dev); - unsigned long temp; - bool irq_wake; + unsigned int val, baud; if (lpuart_is_32(sport)) { - /* disable Rx/Tx and interrupts */ - temp = lpuart32_read(&sport->port, UARTCTRL); - temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE); - lpuart32_write(&sport->port, temp, UARTCTRL); + val = lpuart32_read(&sport->port, UARTCTRL); + baud = lpuart32_read(&sport->port, UARTBAUD); + if (on) { + /* set rx_watermark to 0 in wakeup source mode */ + lpuart32_write(&sport->port, 0, UARTWATER); + val |= UARTCTRL_RIE; + /* clear RXEDGIF flag before enable RXEDGIE interrupt */ + lpuart32_write(&sport->port, UARTSTAT_RXEDGIF, UARTSTAT); + baud |= UARTBAUD_RXEDGIE; + } else { + val &= ~UARTCTRL_RIE; + baud &= ~UARTBAUD_RXEDGIE; + } + lpuart32_write(&sport->port, val, UARTCTRL); + lpuart32_write(&sport->port, baud, UARTBAUD); } else { - /* disable Rx/Tx and interrupts */ - temp = readb(sport->port.membase + UARTCR2); - temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); - writeb(temp, sport->port.membase + UARTCR2); + val = readb(sport->port.membase + UARTCR2); + if (on) + val |= UARTCR2_RIE; + else + val &= ~UARTCR2_RIE; + writeb(val, sport->port.membase + UARTCR2); } +} - uart_suspend_port(&lpuart_reg, &sport->port); +static bool lpuart_uport_is_active(struct lpuart_port *sport) +{ + struct tty_port *port = &sport->port.state->port; + struct tty_struct *tty; + struct device *tty_dev; + int may_wake = 0; - /* uart_suspend_port() might set wakeup flag */ - irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); + tty = tty_port_tty_get(port); + if (tty) { + tty_dev = tty->dev; + may_wake = device_may_wakeup(tty_dev); + tty_kref_put(tty); + } - if (sport->lpuart_dma_rx_use) { - /* - * EDMA driver during suspend will forcefully release any - * non-idle DMA channels. If port wakeup is enabled or if port - * is console port or 'no_console_suspend' is set the Rx DMA - * cannot resume as expected, hence gracefully release the - * Rx DMA path before suspend and start Rx DMA path on resume. - */ - if (irq_wake) { - del_timer_sync(&sport->lpuart_timer); - lpuart_dma_rx_free(&sport->port); - } + if ((tty_port_initialized(port) && may_wake) || + (!console_suspend_enabled && uart_console(&sport->port))) + return true; + + return false; +} + +static int __maybe_unused lpuart_suspend_noirq(struct device *dev) +{ + struct lpuart_port *sport = dev_get_drvdata(dev); + bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); + + if (lpuart_uport_is_active(sport)) + serial_lpuart_enable_wakeup(sport, !!irq_wake); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused lpuart_resume_noirq(struct device *dev) +{ + struct lpuart_port *sport = dev_get_drvdata(dev); + unsigned int val; + + pinctrl_pm_select_default_state(dev); + + if (lpuart_uport_is_active(sport)) { + serial_lpuart_enable_wakeup(sport, false); - /* Disable Rx DMA to use UART port as wakeup source */ + /* clear the wakeup flags */ if (lpuart_is_32(sport)) { - temp = lpuart32_read(&sport->port, UARTBAUD); - lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, - UARTBAUD); - } else { - writeb(readb(sport->port.membase + UARTCR5) & - ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); + val = lpuart32_read(&sport->port, UARTSTAT); + lpuart32_write(&sport->port, val, UARTSTAT); } } - if (sport->lpuart_dma_tx_use) { - sport->dma_tx_in_progress = false; - dmaengine_terminate_all(sport->dma_tx_chan); - } - - if (sport->port.suspended && !irq_wake) - lpuart_disable_clks(sport); - return 0; } -static int __maybe_unused lpuart_resume(struct device *dev) +static int __maybe_unused lpuart_suspend(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); - bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); + unsigned long temp, flags; - if (sport->port.suspended && !irq_wake) - lpuart_enable_clks(sport); + uart_suspend_port(&lpuart_reg, &sport->port); - if (lpuart_is_32(sport)) - lpuart32_setup_watermark_enable(sport); - else - lpuart_setup_watermark_enable(sport); + if (lpuart_uport_is_active(sport)) { + spin_lock_irqsave(&sport->port.lock, flags); + if (lpuart_is_32(sport)) { + /* disable Rx/Tx and interrupts */ + temp = lpuart32_read(&sport->port, UARTCTRL); + temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE); + lpuart32_write(&sport->port, temp, UARTCTRL); + } else { + /* disable Rx/Tx and interrupts */ + temp = readb(sport->port.membase + UARTCR2); + temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); + writeb(temp, sport->port.membase + UARTCR2); + } + spin_unlock_irqrestore(&sport->port.lock, flags); - if (sport->lpuart_dma_rx_use) { - if (irq_wake) { - if (!lpuart_start_rx_dma(sport)) - rx_dma_timer_init(sport); - else - sport->lpuart_dma_rx_use = false; + if (sport->lpuart_dma_rx_use) { + /* + * EDMA driver during suspend will forcefully release any + * non-idle DMA channels. If port wakeup is enabled or if port + * is console port or 'no_console_suspend' is set the Rx DMA + * cannot resume as expected, hence gracefully release the + * Rx DMA path before suspend and start Rx DMA path on resume. + */ + del_timer_sync(&sport->lpuart_timer); + lpuart_dma_rx_free(&sport->port); + + /* Disable Rx DMA to use UART port as wakeup source */ + spin_lock_irqsave(&sport->port.lock, flags); + if (lpuart_is_32(sport)) { + temp = lpuart32_read(&sport->port, UARTBAUD); + lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, + UARTBAUD); + } else { + writeb(readb(sport->port.membase + UARTCR5) & + ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); + } + spin_unlock_irqrestore(&sport->port.lock, flags); + } + + if (sport->lpuart_dma_tx_use) { + spin_lock_irqsave(&sport->port.lock, flags); + if (lpuart_is_32(sport)) { + temp = lpuart32_read(&sport->port, UARTBAUD); + temp &= ~UARTBAUD_TDMAE; + lpuart32_write(&sport->port, temp, UARTBAUD); + } else { + temp = readb(sport->port.membase + UARTCR5); + temp &= ~UARTCR5_TDMAS; + writeb(temp, sport->port.membase + UARTCR5); + } + spin_unlock_irqrestore(&sport->port.lock, flags); + sport->dma_tx_in_progress = false; + dmaengine_terminate_all(sport->dma_tx_chan); } } - lpuart_tx_dma_startup(sport); + return 0; +} - if (lpuart_is_32(sport)) - lpuart32_configure(sport); +static void lpuart_console_fixup(struct lpuart_port *sport) +{ + struct tty_port *port = &sport->port.state->port; + struct uart_port *uport = &sport->port; + struct ktermios termios; + + /* i.MX7ULP enter VLLS mode that lpuart module power off and registers + * all lost no matter the port is wakeup source. + * For console port, console baud rate setting lost and print messy + * log when enable the console port as wakeup source. To avoid the + * issue happen, user should not enable uart port as wakeup source + * in VLLS mode, or restore console setting here. + */ + if (is_imx7ulp_lpuart(sport) && lpuart_uport_is_active(sport) && + console_suspend_enabled && uart_console(&sport->port)) { + + mutex_lock(&port->mutex); + memset(&termios, 0, sizeof(struct ktermios)); + termios.c_cflag = uport->cons->cflag; + if (port->tty && termios.c_cflag == 0) + termios = port->tty->termios; + uport->ops->set_termios(uport, &termios, NULL); + mutex_unlock(&port->mutex); + } +} + +static int __maybe_unused lpuart_resume(struct device *dev) +{ + struct lpuart_port *sport = dev_get_drvdata(dev); + + if (lpuart_uport_is_active(sport)) { + if (lpuart_is_32(sport)) + lpuart32_hw_setup(sport); + else + lpuart_hw_setup(sport); + } + lpuart_console_fixup(sport); uart_resume_port(&lpuart_reg, &sport->port); return 0; } -static SIMPLE_DEV_PM_OPS(lpuart_pm_ops, lpuart_suspend, lpuart_resume); +static const struct dev_pm_ops lpuart_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpuart_suspend_noirq, + lpuart_resume_noirq) + SET_SYSTEM_SLEEP_PM_OPS(lpuart_suspend, lpuart_resume) +}; static struct platform_driver lpuart_driver = { .probe = lpuart_probe, -- GitLab From 43543e6f539b3e646348c253059f75e27d63c94d Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Thu, 10 Nov 2022 19:38:58 +0800 Subject: [PATCH 0666/1480] tty: serial: fsl_lpuart: Add runtime pm support Add runtime pm support to manage the lpuart clock. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20221110113859.8485-3-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 07c1524ef0087..9e04728bcc0b9 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -233,6 +234,7 @@ /* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */ #define DMA_RX_TIMEOUT (10) +#define UART_AUTOSUSPEND_TIMEOUT 3000 #define DRIVER_NAME "fsl-lpuart" #define DEV_NAME "ttyLP" @@ -793,6 +795,20 @@ static void lpuart32_start_tx(struct uart_port *port) } } +static void +lpuart_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) +{ + switch (state) { + case UART_PM_STATE_OFF: + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put_autosuspend(port->dev); + break; + default: + pm_runtime_get_sync(port->dev); + break; + } +} + /* return TIOCSER_TEMT when transmitter is not busy */ static unsigned int lpuart_tx_empty(struct uart_port *port) { @@ -2229,6 +2245,7 @@ static const struct uart_ops lpuart_pops = { .startup = lpuart_startup, .shutdown = lpuart_shutdown, .set_termios = lpuart_set_termios, + .pm = lpuart_uart_pm, .type = lpuart_type, .request_port = lpuart_request_port, .release_port = lpuart_release_port, @@ -2253,6 +2270,7 @@ static const struct uart_ops lpuart32_pops = { .startup = lpuart32_startup, .shutdown = lpuart32_shutdown, .set_termios = lpuart32_set_termios, + .pm = lpuart_uart_pm, .type = lpuart_type, .request_port = lpuart_request_port, .release_port = lpuart_release_port, @@ -2733,6 +2751,11 @@ static int lpuart_probe(struct platform_device *pdev) handler = lpuart_int; } + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = lpuart_global_reset(sport); if (ret) goto failed_reset; @@ -2757,6 +2780,9 @@ failed_irq_request: failed_attach_port: failed_get_rs485: failed_reset: + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); lpuart_disable_clks(sport); return ret; } @@ -2775,9 +2801,30 @@ static int lpuart_remove(struct platform_device *pdev) if (sport->dma_rx_chan) dma_release_channel(sport->dma_rx_chan); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); return 0; } +static int __maybe_unused lpuart_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpuart_port *sport = platform_get_drvdata(pdev); + + lpuart_disable_clks(sport); + + return 0; +}; + +static int __maybe_unused lpuart_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpuart_port *sport = platform_get_drvdata(pdev); + + return lpuart_enable_clks(sport); +}; + static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on) { unsigned int val, baud; @@ -2923,6 +2970,10 @@ static int __maybe_unused lpuart_suspend(struct device *dev) sport->dma_tx_in_progress = false; dmaengine_terminate_all(sport->dma_tx_chan); } + } else if (pm_runtime_active(sport->port.dev)) { + lpuart_disable_clks(sport); + pm_runtime_disable(sport->port.dev); + pm_runtime_set_suspended(sport->port.dev); } return 0; @@ -2957,12 +3008,19 @@ static void lpuart_console_fixup(struct lpuart_port *sport) static int __maybe_unused lpuart_resume(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); + int ret; if (lpuart_uport_is_active(sport)) { if (lpuart_is_32(sport)) lpuart32_hw_setup(sport); else lpuart_hw_setup(sport); + } else if (pm_runtime_active(sport->port.dev)) { + ret = lpuart_enable_clks(sport); + if (ret) + return ret; + pm_runtime_set_active(sport->port.dev); + pm_runtime_enable(sport->port.dev); } lpuart_console_fixup(sport); @@ -2972,6 +3030,8 @@ static int __maybe_unused lpuart_resume(struct device *dev) } static const struct dev_pm_ops lpuart_pm_ops = { + SET_RUNTIME_PM_OPS(lpuart_runtime_suspend, + lpuart_runtime_resume, NULL) SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpuart_suspend_noirq, lpuart_resume_noirq) SET_SYSTEM_SLEEP_PM_OPS(lpuart_suspend, lpuart_resume) -- GitLab From 22cf92bb3908e1bbc22b03371e9e67e7bd455e0f Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Thu, 10 Nov 2022 19:38:59 +0800 Subject: [PATCH 0667/1480] tty: serial: fsl_lpuart: Use pm_ptr() to avoid need to make pm __maybe_unused Use pm_ptr() to remove the need to mark the pm functions as __maybe_unused when the kernel is built without CONFIG_PM support. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20221110113859.8485-4-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 9e04728bcc0b9..c1c8aa3e0fac8 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2807,7 +2807,7 @@ static int lpuart_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused lpuart_runtime_suspend(struct device *dev) +static int lpuart_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct lpuart_port *sport = platform_get_drvdata(pdev); @@ -2817,7 +2817,7 @@ static int __maybe_unused lpuart_runtime_suspend(struct device *dev) return 0; }; -static int __maybe_unused lpuart_runtime_resume(struct device *dev) +static int lpuart_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct lpuart_port *sport = platform_get_drvdata(pdev); @@ -2876,7 +2876,7 @@ static bool lpuart_uport_is_active(struct lpuart_port *sport) return false; } -static int __maybe_unused lpuart_suspend_noirq(struct device *dev) +static int lpuart_suspend_noirq(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); @@ -2889,7 +2889,7 @@ static int __maybe_unused lpuart_suspend_noirq(struct device *dev) return 0; } -static int __maybe_unused lpuart_resume_noirq(struct device *dev) +static int lpuart_resume_noirq(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); unsigned int val; @@ -2909,7 +2909,7 @@ static int __maybe_unused lpuart_resume_noirq(struct device *dev) return 0; } -static int __maybe_unused lpuart_suspend(struct device *dev) +static int lpuart_suspend(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); unsigned long temp, flags; @@ -3005,7 +3005,7 @@ static void lpuart_console_fixup(struct lpuart_port *sport) } } -static int __maybe_unused lpuart_resume(struct device *dev) +static int lpuart_resume(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); int ret; @@ -3030,11 +3030,11 @@ static int __maybe_unused lpuart_resume(struct device *dev) } static const struct dev_pm_ops lpuart_pm_ops = { - SET_RUNTIME_PM_OPS(lpuart_runtime_suspend, + RUNTIME_PM_OPS(lpuart_runtime_suspend, lpuart_runtime_resume, NULL) - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpuart_suspend_noirq, + NOIRQ_SYSTEM_SLEEP_PM_OPS(lpuart_suspend_noirq, lpuart_resume_noirq) - SET_SYSTEM_SLEEP_PM_OPS(lpuart_suspend, lpuart_resume) + SYSTEM_SLEEP_PM_OPS(lpuart_suspend, lpuart_resume) }; static struct platform_driver lpuart_driver = { @@ -3043,7 +3043,7 @@ static struct platform_driver lpuart_driver = { .driver = { .name = "fsl-lpuart", .of_match_table = lpuart_dt_ids, - .pm = &lpuart_pm_ops, + .pm = pm_ptr(&lpuart_pm_ops), }, }; -- GitLab From 8be3a7bf773700534a6e8f87f6ed2ed111254be5 Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Tue, 22 Nov 2022 19:45:59 +0800 Subject: [PATCH 0668/1480] serial: pch: Fix PCI device refcount leak in pch_request_dma() As comment of pci_get_slot() says, it returns a pci_device with its refcount increased. The caller must decrement the reference count by calling pci_dev_put(). Since 'dma_dev' is only used to filter the channel in filter(), we can call pci_dev_put() before exiting from pch_request_dma(). Add the missing pci_dev_put() for the normal and error path. Fixes: 3c6a483275f4 ("Serial: EG20T: add PCH_UART driver") Signed-off-by: Xiongfeng Wang Link: https://lore.kernel.org/r/20221122114559.27692-1-wangxiongfeng2@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index c76719c0f453a..3d54a43768cd2 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -694,6 +694,7 @@ static void pch_request_dma(struct uart_port *port) if (!chan) { dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n", __func__); + pci_dev_put(dma_dev); return; } priv->chan_tx = chan; @@ -710,6 +711,7 @@ static void pch_request_dma(struct uart_port *port) __func__); dma_release_channel(priv->chan_tx); priv->chan_tx = NULL; + pci_dev_put(dma_dev); return; } @@ -717,6 +719,8 @@ static void pch_request_dma(struct uart_port *port) priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize, &priv->rx_buf_dma, GFP_KERNEL); priv->chan_rx = chan; + + pci_dev_put(dma_dev); } static void pch_dma_rx_complete(void *arg) -- GitLab From 1307c5d33cce8a41dd77c2571e4df65a5b627feb Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Tue, 22 Nov 2022 15:04:26 -0500 Subject: [PATCH 0669/1480] serial: altera_uart: fix locking in polling mode Since altera_uart_interrupt() may also be called from a poll timer in "serving_softirq" context, use spin_[lock_irqsave|unlock_irqrestore] variants, which are appropriate for both softirq and hardware interrupt contexts. Fixes: 2f8b9c15cd88 ("altera_uart: Add support for polling mode (IRQ-less)") Signed-off-by: Gabriel Somlo Link: https://lore.kernel.org/r/20221122200426.888349-1-gsomlo@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 316074bb23e9f..9ce3d24af5360 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -259,16 +259,17 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) { struct uart_port *port = data; struct altera_uart *pp = container_of(port, struct altera_uart, port); + unsigned long flags; unsigned int isr; isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); if (isr & ALTERA_UART_STATUS_RRDY_MSK) altera_uart_rx_chars(port); if (isr & ALTERA_UART_STATUS_TRDY_MSK) altera_uart_tx_chars(port); - spin_unlock(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); return IRQ_RETVAL(isr); } -- GitLab From 1a6ec673fb627c26e2267ca0a03849f91dbd9b40 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Wed, 23 Nov 2022 06:12:12 +0000 Subject: [PATCH 0670/1480] serial: sunsab: Fix error handling in sunsab_init() The sunsab_init() returns the platform_driver_register() directly without checking its return value, if platform_driver_register() failed, the allocated sunsab_ports is leaked. Fix by free sunsab_ports and set it to NULL when platform_driver_register() failed. Fixes: c4d37215a824 ("[SERIAL] sunsab: Convert to of_driver framework.") Signed-off-by: Yuan Can Link: https://lore.kernel.org/r/20221123061212.52593-1-yuancan@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsab.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 94db67f21abf2..48b39fdb0397a 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1131,7 +1131,13 @@ static int __init sunsab_init(void) } } - return platform_driver_register(&sab_driver); + err = platform_driver_register(&sab_driver); + if (err) { + kfree(sunsab_ports); + sunsab_ports = NULL; + } + + return err; } static void __exit sunsab_exit(void) -- GitLab From 8682ab0eea89c300ebb120c02ead3999ca5560a8 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Wed, 23 Nov 2022 10:36:19 +0800 Subject: [PATCH 0671/1480] tty: serial: fsl_lpuart: switch to new dmaengine_terminate_* API Convert dmaengine_terminate_all() calls to synchronous and asynchronous versions where appropriate. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20221123023619.30173-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index c1c8aa3e0fac8..5e69fb73f570f 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -583,7 +583,7 @@ static void lpuart_flush_buffer(struct uart_port *port) sport->dma_tx_nents, DMA_TO_DEVICE); sport->dma_tx_in_progress = false; } - dmaengine_terminate_all(chan); + dmaengine_terminate_async(chan); } if (lpuart_is_32(sport)) { @@ -1327,7 +1327,7 @@ static void lpuart_dma_rx_free(struct uart_port *port) struct lpuart_port, port); struct dma_chan *chan = sport->dma_rx_chan; - dmaengine_terminate_all(chan); + dmaengine_terminate_sync(chan); dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); kfree(sport->rx_ring.buf); sport->rx_ring.tail = 0; @@ -1757,7 +1757,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) if (wait_event_interruptible_timeout(sport->dma_wait, !sport->dma_tx_in_progress, msecs_to_jiffies(300)) <= 0) { sport->dma_tx_in_progress = false; - dmaengine_terminate_all(sport->dma_tx_chan); + dmaengine_terminate_sync(sport->dma_tx_chan); } sport->lpuart_dma_tx_use = false; } @@ -2968,7 +2968,7 @@ static int lpuart_suspend(struct device *dev) } spin_unlock_irqrestore(&sport->port.lock, flags); sport->dma_tx_in_progress = false; - dmaengine_terminate_all(sport->dma_tx_chan); + dmaengine_terminate_sync(sport->dma_tx_chan); } } else if (pm_runtime_active(sport->port.dev)) { lpuart_disable_clks(sport); -- GitLab From 94ec165c9f98189ce9aa50cfcb7181ba23f92eb7 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 23 Nov 2022 09:27:35 +0100 Subject: [PATCH 0672/1480] serial: atmel: cleanup atmel_start+stop_tx() Define local variables holding information about whether pdc or dma is used in the HW. These are retested several times by calls to atmel_use_pdc_tx() and atmel_use_dma_tx(). So to make the code more readable, simply cache the values. This is also a preparatory patch for the next one (where is_pdc is used once more in atmel_stop_tx()). Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: linux-arm-kernel@lists.infradead.org Reported-by: Michael Walle Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221123082736.24566-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4ca04676c4066..65f63dccfd728 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -552,8 +552,9 @@ static u_int atmel_get_mctrl(struct uart_port *port) static void atmel_stop_tx(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + bool is_pdc = atmel_use_pdc_tx(port); - if (atmel_use_pdc_tx(port)) { + if (is_pdc) { /* disable PDC transmit */ atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); } @@ -572,7 +573,6 @@ static void atmel_stop_tx(struct uart_port *port) if (atmel_uart_is_half_duplex(port)) if (!atomic_read(&atmel_port->tasklet_shutdown)) atmel_start_rx(port); - } /* @@ -581,20 +581,22 @@ static void atmel_stop_tx(struct uart_port *port) static void atmel_start_tx(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + bool is_pdc = atmel_use_pdc_tx(port); + bool is_dma = is_pdc || atmel_use_dma_tx(port); - if (atmel_use_pdc_tx(port) && (atmel_uart_readl(port, ATMEL_PDC_PTSR) + if (is_pdc && (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN)) /* The transmitter is already running. Yes, we really need this.*/ return; - if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port)) - if (atmel_uart_is_half_duplex(port)) - atmel_stop_rx(port); + if (is_dma && atmel_uart_is_half_duplex(port)) + atmel_stop_rx(port); - if (atmel_use_pdc_tx(port)) + if (is_pdc) { /* re-enable PDC transmit */ atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); + } /* Enable interrupts */ atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); -- GitLab From 6373ab4dfee731deec62b4452ea641611feff9b3 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 23 Nov 2022 09:27:36 +0100 Subject: [PATCH 0673/1480] serial: atmel: don't stop the transmitter when doing PIO Writing ATMEL_US_TXDIS to ATMEL_US_CR makes the transmitter NOT to send the just queued character. This means when the character is last and uart calls ops->stop_tx(), the character is not sent at all. The usart datasheet is not much specific on this, it just says the transmitter is stopped. But apparently, the character is dropped. So we should stop the transmitter only for DMA and PDC transfers to not send any more characters. For PIO, this is unexpected and deviates from other drivers. In particular, the below referenced commit broke TX as it added a call to ->stop_tx() after the very last character written to the transmitter. So fix this by limiting the write of ATMEL_US_TXDIS to DMA transfers only. Even there, I don't know if it is correctly implemented. Are all the queued characters sent once ->start_tx() is called? Anyone tested flow control -- be it hard (RTSCTS) or the soft (XOFF/XON) one? Fixes: 2d141e683e9a ("tty: serial: use uart_port_tx() helper") Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: linux-arm-kernel@lists.infradead.org Reported-by: Michael Walle Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221123082736.24566-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 65f63dccfd728..f1c06e12efa0b 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -553,19 +553,22 @@ static void atmel_stop_tx(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); bool is_pdc = atmel_use_pdc_tx(port); + bool is_dma = is_pdc || atmel_use_dma_tx(port); if (is_pdc) { /* disable PDC transmit */ atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); } - /* - * Disable the transmitter. - * This is mandatory when DMA is used, otherwise the DMA buffer - * is fully transmitted. - */ - atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS); - atmel_port->tx_stopped = true; + if (is_dma) { + /* + * Disable the transmitter. + * This is mandatory when DMA is used, otherwise the DMA buffer + * is fully transmitted. + */ + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS); + atmel_port->tx_stopped = true; + } /* Disable interrupts */ atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); @@ -601,9 +604,11 @@ static void atmel_start_tx(struct uart_port *port) /* Enable interrupts */ atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); - /* re-enable the transmitter */ - atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); - atmel_port->tx_stopped = false; + if (is_dma) { + /* re-enable the transmitter */ + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); + atmel_port->tx_stopped = false; + } } /* -- GitLab From 41522f7442905814c654dbe2ca7b8d3605c7e0cc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:47 -0800 Subject: [PATCH 0674/1480] perf test: Add 'leafloop' test workload The leafloop workload is to run an infinite loop in the test_leaf function. This is needed for the ARM fp callgraph test to verify if it gets the correct callchains. $ perf test -w leafloop Committer notes: Add a: -U_FORTIFY_SOURCE to the leafloop CFLAGS as the main perf flags set it and it requires building with optimization, and this new test has a -O0. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 3 +++ tools/perf/tests/workloads/leafloop.c | 34 +++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 tools/perf/tests/workloads/leafloop.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 161f38476e77b..0ed5ac452f6ee 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -121,6 +121,7 @@ static struct test_suite **tests[] = { static struct test_workload *workloads[] = { &workload__noploop, &workload__thloop, + &workload__leafloop, }; static int num_subtests(const struct test_suite *t) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index e6edfeeadaeba..86804dd6452b7 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -202,5 +202,6 @@ struct test_workload workload__##work = { \ /* The list of test workloads */ DECLARE_WORKLOAD(noploop); DECLARE_WORKLOAD(thloop); +DECLARE_WORKLOAD(leafloop); #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index b8964b1099c0e..03dc675a4a7c8 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -2,3 +2,6 @@ perf-y += noploop.o perf-y += thloop.o +perf-y += leafloop.o + +CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/leafloop.c b/tools/perf/tests/workloads/leafloop.c new file mode 100644 index 0000000000000..1bf5cc97649b0 --- /dev/null +++ b/tools/perf/tests/workloads/leafloop.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include "../tests.h" + +/* We want to check these symbols in perf script */ +noinline void leaf(volatile int b); +noinline void parent(volatile int b); + +static volatile int a; + +noinline void leaf(volatile int b) +{ + for (;;) + a += b; +} + +noinline void parent(volatile int b) +{ + leaf(b); +} + +static int leafloop(int argc, const char **argv) +{ + int c = 1; + + if (argc > 0) + c = atoi(argv[0]); + + parent(c); + return 0; +} + +DEFINE_WORKLOAD(leafloop); -- GitLab From 7cf0b4a73a4a4f36bb4ef53d066b811b7621c635 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:48 -0800 Subject: [PATCH 0675/1480] perf test: Replace arm callgraph fp test workload with leafloop So that it can get rid of requirement of a compiler. Reviewed-by: Leo Yan Signed-off-by: Namhyung Kim Tested-by: James Clark Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/tests/shell/test_arm_callgraph_fp.sh | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/tools/perf/tests/shell/test_arm_callgraph_fp.sh b/tools/perf/tests/shell/test_arm_callgraph_fp.sh index ec108d45d3c61..e61d8deaa0c41 100755 --- a/tools/perf/tests/shell/test_arm_callgraph_fp.sh +++ b/tools/perf/tests/shell/test_arm_callgraph_fp.sh @@ -4,44 +4,16 @@ lscpu | grep -q "aarch64" || exit 2 -if ! [ -x "$(command -v cc)" ]; then - echo "failed: no compiler, install gcc" - exit 2 -fi - PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX) -TEST_PROGRAM_SOURCE=$(mktemp /tmp/test_program.XXXXX.c) -TEST_PROGRAM=$(mktemp /tmp/test_program.XXXXX) +TEST_PROGRAM="perf test -w leafloop" cleanup_files() { rm -f $PERF_DATA - rm -f $TEST_PROGRAM_SOURCE - rm -f $TEST_PROGRAM } trap cleanup_files exit term int -cat << EOF > $TEST_PROGRAM_SOURCE -int a = 0; -void leaf(void) { - for (;;) - a += a; -} -void parent(void) { - leaf(); -} -int main(void) { - parent(); - return 0; -} -EOF - -echo " + Compiling test program ($TEST_PROGRAM)..." - -CFLAGS="-g -O0 -fno-inline -fno-omit-frame-pointer" -cc $CFLAGS $TEST_PROGRAM_SOURCE -o $TEST_PROGRAM || exit 1 - # Add a 1 second delay to skip samples that are not in the leaf() function perf record -o $PERF_DATA --call-graph fp -e cycles//u -D 1000 --user-callchains -- $TEST_PROGRAM 2> /dev/null & PID=$! @@ -58,11 +30,11 @@ wait $PID # program # 728 leaf # 753 parent -# 76c main +# 76c leafloop # ... perf script -i $PERF_DATA -F comm,ip,sym | head -n4 perf script -i $PERF_DATA -F comm,ip,sym | head -n4 | \ awk '{ if ($2 != "") sym[i++] = $2 } END { if (sym[0] != "leaf" || sym[1] != "parent" || - sym[2] != "main") exit 1 }' + sym[2] != "leafloop") exit 1 }' -- GitLab From 39281709a6e2301ac4c6ac7015c7793392ca2dfe Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:49 -0800 Subject: [PATCH 0676/1480] perf test: Add 'sqrtloop' test workload The sqrtloop creates a child process to run an infinite loop calling sqrt() with rand(). This is needed for ARM SPE fork test. $ perf test -w sqrtloop It can take an optional argument to specify how long it will run in seconds (default: 1). Committer notes: Explicitely ignored the sqrt() return to fix the build on systems where the compiler complains it isn't being used. And added a sqrtloop specific CFLAGS to disable optimizations to make this a bit more robust wrt dead code elimination. Doing that a -U_FORTIFY_SOURCE needs to be added, as -O0 is incompatible with it. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 ++ tools/perf/tests/workloads/sqrtloop.c | 45 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 tools/perf/tests/workloads/sqrtloop.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 0ed5ac452f6ee..9acb7a93eeb97 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -122,6 +122,7 @@ static struct test_workload *workloads[] = { &workload__noploop, &workload__thloop, &workload__leafloop, + &workload__sqrtloop, }; static int num_subtests(const struct test_suite *t) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 86804dd6452b7..18c40319e67c7 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -203,5 +203,6 @@ struct test_workload workload__##work = { \ DECLARE_WORKLOAD(noploop); DECLARE_WORKLOAD(thloop); DECLARE_WORKLOAD(leafloop); +DECLARE_WORKLOAD(sqrtloop); #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index 03dc675a4a7c8..2312a338f01c0 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -3,5 +3,7 @@ perf-y += noploop.o perf-y += thloop.o perf-y += leafloop.o +perf-y += sqrtloop.o +CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/sqrtloop.c b/tools/perf/tests/workloads/sqrtloop.c new file mode 100644 index 0000000000000..ccc94c6a6676a --- /dev/null +++ b/tools/perf/tests/workloads/sqrtloop.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include +#include +#include +#include +#include "../tests.h" + +static volatile sig_atomic_t done; + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +static int __sqrtloop(int sec) +{ + signal(SIGALRM, sighandler); + alarm(sec); + + while (!done) + (void)sqrt(rand()); + return 0; +} + +static int sqrtloop(int argc, const char **argv) +{ + int sec = 1; + + if (argc > 0) + sec = atoi(argv[0]); + + switch (fork()) { + case 0: + return __sqrtloop(sec); + case -1: + return -1; + default: + wait(NULL); + } + return 0; +} + +DEFINE_WORKLOAD(sqrtloop); -- GitLab From e011979ec4c3482b68be05e2fdf98fefce4cd75b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:50 -0800 Subject: [PATCH 0677/1480] perf test: Replace arm spe fork test workload with sqrtloop So that it can get rid of requirement of a compiler. I've also removed killall as it'll kill perf process now and run the test workload for 10 sec instead. Signed-off-by: Namhyung Kim Tested-by: James Clark Tested-by: Leo Yan Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/test_arm_spe_fork.sh | 44 +-------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/tools/perf/tests/shell/test_arm_spe_fork.sh b/tools/perf/tests/shell/test_arm_spe_fork.sh index c920d3583d30a..da810e1b2b9e7 100755 --- a/tools/perf/tests/shell/test_arm_spe_fork.sh +++ b/tools/perf/tests/shell/test_arm_spe_fork.sh @@ -11,14 +11,7 @@ skip_if_no_arm_spe_event() { skip_if_no_arm_spe_event || exit 2 -# skip if there's no compiler -if ! [ -x "$(command -v cc)" ]; then - echo "failed: no compiler, install gcc" - exit 2 -fi - -TEST_PROGRAM_SOURCE=$(mktemp /tmp/__perf_test.program.XXXXX.c) -TEST_PROGRAM=$(mktemp /tmp/__perf_test.program.XXXXX) +TEST_PROGRAM="perf test -w sqrtloop 10" PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX) PERF_RECORD_LOG=$(mktemp /tmp/__perf_test.log.XXXXX) @@ -27,43 +20,10 @@ cleanup_files() echo "Cleaning up files..." rm -f ${PERF_RECORD_LOG} rm -f ${PERF_DATA} - rm -f ${TEST_PROGRAM_SOURCE} - rm -f ${TEST_PROGRAM} } trap cleanup_files exit term int -# compile test program -cat << EOF > $TEST_PROGRAM_SOURCE -#include -#include -#include -#include -#include - -int workload() { - while (1) - sqrt(rand()); - return 0; -} - -int main() { - switch (fork()) { - case 0: - return workload(); - case -1: - return 1; - default: - wait(NULL); - } - return 0; -} -EOF - -echo "Compiling test program..." -CFLAGS="-lm" -cc $TEST_PROGRAM_SOURCE $CFLAGS -o $TEST_PROGRAM || exit 1 - echo "Recording workload..." perf record -o ${PERF_DATA} -e arm_spe/period=65536/ -vvv -- $TEST_PROGRAM > ${PERF_RECORD_LOG} 2>&1 & PERFPID=$! @@ -78,8 +38,6 @@ echo Log lines after 1 second = $log1 kill $PERFPID wait $PERFPID -# test program may leave an orphan process running the workload -killall $(basename $TEST_PROGRAM) if [ "$log0" = "$log1" ]; then -- GitLab From a104f0ea99d846df19aad8a5476eb9bc39fa42ca Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:51 -0800 Subject: [PATCH 0678/1480] perf test: Add 'brstack' test workload The brstack is to run different kinds of branches repeatedly. This is necessary for brstack test case to verify if it has correct branch info. $ perf test -w brstack I renamed the internal functions to have brstack_ prefix as it's too generic name. Add a -U_FORTIFY_SOURCE to the brstack CFLAGS, as the main perf flags set it and it requires building with optimization, and this new test has a -O0. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-10-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 ++ tools/perf/tests/workloads/brstack.c | 40 ++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 tools/perf/tests/workloads/brstack.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 9acb7a93eeb97..69fa56939309b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -123,6 +123,7 @@ static struct test_workload *workloads[] = { &workload__thloop, &workload__leafloop, &workload__sqrtloop, + &workload__brstack, }; static int num_subtests(const struct test_suite *t) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 18c40319e67c7..dc96f59cac2ef 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -204,5 +204,6 @@ DECLARE_WORKLOAD(noploop); DECLARE_WORKLOAD(thloop); DECLARE_WORKLOAD(leafloop); DECLARE_WORKLOAD(sqrtloop); +DECLARE_WORKLOAD(brstack); #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index 2312a338f01c0..ae06a5538b171 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -4,6 +4,8 @@ perf-y += noploop.o perf-y += thloop.o perf-y += leafloop.o perf-y += sqrtloop.o +perf-y += brstack.o CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE +CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/brstack.c b/tools/perf/tests/workloads/brstack.c new file mode 100644 index 0000000000000..0b60bd37b9d1a --- /dev/null +++ b/tools/perf/tests/workloads/brstack.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include "../tests.h" + +#define BENCH_RUNS 999999 + +static volatile int cnt; + +static void brstack_bar(void) { +} /* return */ + +static void brstack_foo(void) { + brstack_bar(); /* call */ +} /* return */ + +static void brstack_bench(void) { + void (*brstack_foo_ind)(void) = brstack_foo; + + if ((cnt++) % 3) /* branch (cond) */ + brstack_foo(); /* call */ + brstack_bar(); /* call */ + brstack_foo_ind(); /* call (ind) */ +} + +static int brstack(int argc, const char **argv) +{ + int num_loops = BENCH_RUNS; + + if (argc > 0) + num_loops = atoi(argv[0]); + + while (1) { + if ((cnt++) > num_loops) + break; + brstack_bench();/* call */ + } /* branch (uncond) */ + return 0; +} + +DEFINE_WORKLOAD(brstack); -- GitLab From 7bc1dd96cf48e1b44773698e7c97481f5f455f6c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:52 -0800 Subject: [PATCH 0679/1480] perf test: Replace brstack test workload So that it can get rid of requirement of a compiler. Also rename the symbols to match with the perf test workload. Signed-off-by: Namhyung Kim Tested-by: James Clark Acked-by: German Gomez Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-11-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/test_brstack.sh | 66 +++++--------------------- 1 file changed, 12 insertions(+), 54 deletions(-) diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh index d7ff5c4b4da4c..5856639b565b1 100755 --- a/tools/perf/tests/shell/test_brstack.sh +++ b/tools/perf/tests/shell/test_brstack.sh @@ -4,13 +4,6 @@ # SPDX-License-Identifier: GPL-2.0 # German Gomez , 2022 -# we need a C compiler to build the test programs -# so bail if none is found -if ! [ -x "$(command -v cc)" ]; then - echo "failed: no compiler, install gcc" - exit 2 -fi - # skip the test if the hardware doesn't support branch stack sampling # and if the architecture doesn't support filter types: any,save_type,u if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then @@ -19,6 +12,7 @@ if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev fi TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX) +TESTPROG="perf test -w brstack" cleanup() { rm -rf $TMPDIR @@ -26,57 +20,24 @@ cleanup() { trap cleanup exit term int -gen_test_program() { - # generate test program - cat << EOF > $1 -#define BENCH_RUNS 999999 -int cnt; -void bar(void) { -} /* return */ -void foo(void) { - bar(); /* call */ -} /* return */ -void bench(void) { - void (*foo_ind)(void) = foo; - if ((cnt++) % 3) /* branch (cond) */ - foo(); /* call */ - bar(); /* call */ - foo_ind(); /* call (ind) */ -} -int main(void) -{ - int cnt = 0; - while (1) { - if ((cnt++) > BENCH_RUNS) - break; - bench(); /* call */ - } /* branch (uncond) */ - return 0; -} -EOF -} - test_user_branches() { echo "Testing user branch stack sampling" - gen_test_program "$TEMPDIR/program.c" - cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out - - perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1 + perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- ${TESTPROG} > /dev/null 2>&1 perf script -i $TMPDIR/perf.data --fields brstacksym | xargs -n1 > $TMPDIR/perf.script # example of branch entries: - # foo+0x14/bar+0x40/P/-/-/0/CALL + # brstack_foo+0x14/brstack_bar+0x40/P/-/-/0/CALL set -x - egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/IND_CALL$" $TMPDIR/perf.script - egrep -m1 "^foo\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script - egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/CALL$" $TMPDIR/perf.script - egrep -m1 "^bench\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script - egrep -m1 "^bar\+[^ ]*/foo\+[^ ]*/RET$" $TMPDIR/perf.script - egrep -m1 "^foo\+[^ ]*/bench\+[^ ]*/RET$" $TMPDIR/perf.script - egrep -m1 "^bench\+[^ ]*/bench\+[^ ]*/COND$" $TMPDIR/perf.script - egrep -m1 "^main\+[^ ]*/main\+[^ ]*/UNCOND$" $TMPDIR/perf.script + egrep -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/IND_CALL$" $TMPDIR/perf.script + egrep -m1 "^brstack_foo\+[^ ]*/brstack_bar\+[^ ]*/CALL$" $TMPDIR/perf.script + egrep -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/CALL$" $TMPDIR/perf.script + egrep -m1 "^brstack_bench\+[^ ]*/brstack_bar\+[^ ]*/CALL$" $TMPDIR/perf.script + egrep -m1 "^brstack_bar\+[^ ]*/brstack_foo\+[^ ]*/RET$" $TMPDIR/perf.script + egrep -m1 "^brstack_foo\+[^ ]*/brstack_bench\+[^ ]*/RET$" $TMPDIR/perf.script + egrep -m1 "^brstack_bench\+[^ ]*/brstack_bench\+[^ ]*/COND$" $TMPDIR/perf.script + egrep -m1 "^brstack\+[^ ]*/brstack\+[^ ]*/UNCOND$" $TMPDIR/perf.script set +x # some branch types are still not being tested: @@ -91,10 +52,7 @@ test_filter() { echo "Testing branch stack filtering permutation ($filter,$expect)" - gen_test_program "$TEMPDIR/program.c" - cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out - - perf record -o $TMPDIR/perf.data --branch-filter $filter,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1 + perf record -o $TMPDIR/perf.data --branch-filter $filter,save_type,u -- ${TESTPROG} > /dev/null 2>&1 perf script -i $TMPDIR/perf.data --fields brstack | xargs -n1 > $TMPDIR/perf.script # fail if we find any branch type that doesn't match any of the expected ones -- GitLab From 3dfc01fe9d12a1e832f49deab37279faa8a9ebc8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:53 -0800 Subject: [PATCH 0680/1480] perf test: Add 'datasym' test workload The datasym workload is to check if perf mem command gets the data addresses precisely. This is needed for data symbol test. $ perf test -w datasym I had to keep the buf1 in the data section, otherwise it could end up in the BSS and was mmaped as a separate //anon region, then it was not symbolized at all. It needs to be fixed separately. Committer notes: Add a -U _FORTIFY_SOURCE to the datasym CFLAGS, as the main perf flags set it and it requires building with optimization, and this new test has a -O0. Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-12-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 ++ tools/perf/tests/workloads/datasym.c | 24 ++++++++++++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 tools/perf/tests/workloads/datasym.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 69fa56939309b..4c6ae59a4dfd7 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -124,6 +124,7 @@ static struct test_workload *workloads[] = { &workload__leafloop, &workload__sqrtloop, &workload__brstack, + &workload__datasym, }; static int num_subtests(const struct test_suite *t) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index dc96f59cac2ef..e15f24cfc9094 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -205,5 +205,6 @@ DECLARE_WORKLOAD(thloop); DECLARE_WORKLOAD(leafloop); DECLARE_WORKLOAD(sqrtloop); DECLARE_WORKLOAD(brstack); +DECLARE_WORKLOAD(datasym); #endif /* TESTS_H */ diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index ae06a5538b171..a1f34d5861e36 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -5,7 +5,9 @@ perf-y += thloop.o perf-y += leafloop.o perf-y += sqrtloop.o perf-y += brstack.o +perf-y += datasym.o CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_datasym.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c new file mode 100644 index 0000000000000..ddd40bc63448a --- /dev/null +++ b/tools/perf/tests/workloads/datasym.c @@ -0,0 +1,24 @@ +#include +#include "../tests.h" + +typedef struct _buf { + char data1; + char reserved[55]; + char data2; +} buf __attribute__((aligned(64))); + +static buf buf1 = { + /* to have this in the data section */ + .reserved[0] = 1, +}; + +static int datasym(int argc __maybe_unused, const char **argv __maybe_unused) +{ + for (;;) { + buf1.data1++; + buf1.data2 += buf1.data1; + } + return 0; +} + +DEFINE_WORKLOAD(datasym); -- GitLab From 0b77fe474696aaaa592d52c7316c135401337aec Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 16 Nov 2022 15:38:54 -0800 Subject: [PATCH 0681/1480] perf test: Replace data symbol test workload with datasym So that it can get rid of requirement of a compiler. $ sudo ./perf test -v 109 109: Test data symbol : --- start --- test child forked, pid 844526 Recording workload... [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.354 MB /tmp/__perf_test.perf.data.GFeZO (4847 samples) ] Cleaning up files... test child finished with 0 ---- end ---- Test data symbol: Ok Signed-off-by: Namhyung Kim Tested-by: James Clark Cc: Adrian Hunter Cc: Athira Jajeev Cc: German Gomez Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Peter Zijlstra Cc: Zhengjun Xing Link: https://lore.kernel.org/r/20221116233854.1596378-13-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/test_data_symbol.sh | 29 +--------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/tools/perf/tests/shell/test_data_symbol.sh b/tools/perf/tests/shell/test_data_symbol.sh index cd6eb54d235d8..d871e6c743efd 100755 --- a/tools/perf/tests/shell/test_data_symbol.sh +++ b/tools/perf/tests/shell/test_data_symbol.sh @@ -11,13 +11,7 @@ skip_if_no_mem_event() { skip_if_no_mem_event || exit 2 -# skip if there's no compiler -if ! [ -x "$(command -v cc)" ]; then - echo "skip: no compiler, install gcc" - exit 2 -fi - -TEST_PROGRAM=$(mktemp /tmp/__perf_test.program.XXXXX) +TEST_PROGRAM="perf test -w datasym" PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX) check_result() { @@ -45,31 +39,10 @@ cleanup_files() { echo "Cleaning up files..." rm -f ${PERF_DATA} - rm -f ${TEST_PROGRAM} } trap cleanup_files exit term int -# compile test program -echo "Compiling test program..." -cat << EOF | cc -o ${TEST_PROGRAM} -x c - -typedef struct _buf { - char data1; - char reserved[55]; - char data2; -} buf __attribute__((aligned(64))); - -static buf buf1; - -int main(void) { - for (;;) { - buf1.data1++; - buf1.data2 += buf1.data1; - } - return 0; -} -EOF - echo "Recording workload..." # perf mem/c2c internally uses IBS PMU on AMD CPU which doesn't support -- GitLab From a3720e969c6de39210809ca9aaebec81919d6c6c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 16 Nov 2022 14:46:31 -0800 Subject: [PATCH 0682/1480] perf build: Fix LIBTRACEEVENT_DYNAMIC The tools/lib includes fixes break LIBTRACEVENT_DYNAMIC as the makefile erroneously had dependencies on building libtraceevent even when not linking with it. This change fixes the issues with LIBTRACEEVENT_DYNAMIC by making the built files optional. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Jiri Olsa Cc: Mark Rutland Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221116224631.207631-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 25 ++++++++++++++++++++++--- tools/perf/util/setup.py | 3 ++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 8c0df762fb02f..a17a6ea85e817 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -242,8 +242,10 @@ sub-make: fixdep else # force_fixdep LIBAPI_DIR = $(srctree)/tools/lib/api/ +ifndef LIBTRACEEVENT_DYNAMIC LIBTRACEEVENT_DIR = $(srctree)/tools/lib/traceevent/ LIBTRACEEVENT_PLUGINS_DIR = $(LIBTRACEEVENT_DIR)/plugins +endif LIBBPF_DIR = $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ LIBSYMBOL_DIR = $(srctree)/tools/lib/symbol/ @@ -293,6 +295,7 @@ SCRIPT_SH += perf-iostat.sh grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) +ifndef LIBTRACEEVENT_DYNAMIC ifneq ($(OUTPUT),) LIBTRACEEVENT_OUTPUT = $(abspath $(OUTPUT))/libtraceevent else @@ -306,13 +309,16 @@ LIBTRACEEVENT = $(LIBTRACEEVENT_OUTPUT)/libtraceevent.a export LIBTRACEEVENT LIBTRACEEVENT_DYNAMIC_LIST = $(LIBTRACEEVENT_PLUGINS_OUTPUT)/libtraceevent-dynamic-list CFLAGS += -I$(LIBTRACEEVENT_OUTPUT)/include - # # The static build has no dynsym table, so this does not work for # static build. Looks like linker starts to scream about that now # (in Fedora 26) so we need to switch it off for static build. DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = $(if $(findstring -static,$(LDFLAGS)),,$(DYNAMIC_LIST_LDFLAGS)) +else +LIBTRACEEVENT_DYNAMIC_LIST = +LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = +endif ifneq ($(OUTPUT),) LIBAPI_OUTPUT = $(abspath $(OUTPUT))/libapi @@ -375,7 +381,11 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf*.so PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) +ifndef LIBTRACEEVENT_DYNAMIC PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI) +else +PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI) +endif SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) @@ -785,9 +795,12 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(LIBPERF) \ $(LIBSUBCMD) \ $(LIBSYMBOL) \ - $(LIBTRACEEVENT) \ bpf-skel +ifndef LIBTRACEEVENT_DYNAMIC +prepare: $(LIBTRACEEVENT) +endif + $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ @@ -843,6 +856,7 @@ endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) +ifndef LIBTRACEEVENT_DYNAMIC LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(filter-out -static,$(LDFLAGS))' $(LIBTRACEEVENT): FORCE | $(LIBTRACEEVENT_OUTPUT) @@ -872,6 +886,7 @@ install-traceevent-plugins: libtraceevent_plugins $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ $(LIBTRACEEVENT_FLAGS) install +endif $(LIBAPI): FORCE | $(LIBAPI_OUTPUT) $(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \ @@ -1152,7 +1167,7 @@ endif # BUILD_BPF_SKEL bpf-skel-clean: $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean libtraceevent_plugins-clean +clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected @@ -1192,6 +1207,10 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(call QUIET_CLEAN, Documentation) \ $(MAKE) -C $(DOC_DIR) O=$(OUTPUT) clean >/dev/null +ifndef LIBTRACEEVENT_DYNAMIC +clean:: $(LIBTRACEEVENT)-clean libtraceevent_plugins-clean +endif + # # To provide FEATURE-DUMP into $(FEATURE_DUMP_COPY) # file if defined, with no further action. diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 5b1e6468d5e8b..43e7ca40b2ec4 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -77,7 +77,8 @@ perf = Extension('perf', include_dirs = ['util/include'], libraries = extra_libraries, extra_compile_args = cflags, - extra_objects = [libtraceevent, libapikfs, libperf], + extra_objects = [ x for x in [libtraceevent, libapikfs, libperf] + if x is not None], ) setup(name='perf', -- GitLab From e5c6109f4813246aa21e2c441e3cde549efa1f18 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 14 Nov 2022 13:07:22 -0800 Subject: [PATCH 0683/1480] perf list: Reorganize to use callbacks to allow honouring command line options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than controlling the list output with passed flags, add callbacks that are called when an event or metric are encountered. State is passed to the callback so that command line options can be respected, alternatively the callbacks can be changed. Fix a few bugs: - wordwrap to columns metric descriptions and expressions; - remove unnecessary whitespace after PMU event names; - the metric filter is a glob but matched using strstr which will always fail, switch to using a proper globmatch, - the detail flag gives details for extra kernel PMU events like branch-instructions. In metricgroup.c switch from struct mep being a rbtree of metricgroups containing a list of metrics, to the tree directly containing all the metrics. In general the alias for a name is passed to the print routine rather than being contained in the name with OR. Committer notes: Check the asprint() return to address this on fedora 36: util/print-events.c: In function ‘print_sdt_events’: util/print-events.c:183:33: error: ignoring return value of ‘asprintf’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result] 183 | asprintf(&evt_name, "%s@%s(%.12s)", sdt_name->s, path, bid); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors $ gcc --version | head -1 gcc (GCC) 12.2.1 20220819 (Red Hat 12.2.1-2) $ Fix ps.pmu_glob setting when dealing with *:* events, it was being left with a freed pointer that then at the end of cmd_list() would be double freed. Check if pmu_name is NULL in default_print_event() before calling strglobmatch(pmu_name, ...) to avoid a segfault. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-10-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-list.c | 333 +++++++++++++++++++++++++----- tools/perf/util/metricgroup.c | 243 ++++++---------------- tools/perf/util/metricgroup.h | 4 +- tools/perf/util/pmu.c | 145 +++++-------- tools/perf/util/pmu.h | 5 +- tools/perf/util/print-events.c | 364 +++++++++++++++++---------------- tools/perf/util/print-events.h | 42 ++-- 7 files changed, 624 insertions(+), 512 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index cc84ced6da266..0c84fdb3ad37c 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -15,31 +15,240 @@ #include "util/pmu-hybrid.h" #include "util/debug.h" #include "util/metricgroup.h" +#include "util/string2.h" +#include "util/strlist.h" #include #include #include -static bool desc_flag = true; -static bool details_flag; +/** + * struct print_state - State and configuration passed to the default_print + * functions. + */ +struct print_state { + /** + * @pmu_glob: Optionally restrict PMU and metric matching to PMU or + * debugfs subsystem name. + */ + char *pmu_glob; + /** @event_glob: Optional pattern matching glob. */ + char *event_glob; + /** @name_only: Print event or metric names only. */ + bool name_only; + /** @desc: Print the event or metric description. */ + bool desc; + /** @long_desc: Print longer event or metric description. */ + bool long_desc; + /** @deprecated: Print deprecated events or metrics. */ + bool deprecated; + /** + * @detailed: Print extra information on the perf event such as names + * and expressions used internally by events. + */ + bool detailed; + /** @metrics: Controls printing of metric and metric groups. */ + bool metrics; + /** @metricgroups: Controls printing of metric and metric groups. */ + bool metricgroups; + /** @last_topic: The last printed event topic. */ + char *last_topic; + /** @last_metricgroups: The last printed metric group. */ + char *last_metricgroups; + /** @visited_metrics: Metrics that are printed to avoid duplicates. */ + struct strlist *visited_metrics; +}; + +static void default_print_start(void *ps) +{ + struct print_state *print_state = ps; + + if (!print_state->name_only && pager_in_use()) + printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); +} + +static void default_print_end(void *print_state __maybe_unused) {} + +static void wordwrap(const char *s, int start, int max, int corr) +{ + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + s = skip_spaces(s); + } +} + +static void default_print_event(void *ps, const char *pmu_name, const char *topic, + const char *event_name, const char *event_alias, + const char *scale_unit __maybe_unused, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr) +{ + struct print_state *print_state = ps; + int pos; + + if (deprecated && !print_state->deprecated) + return; + + if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob)) + return; + + if (print_state->event_glob && + (!event_name || !strglobmatch(event_name, print_state->event_glob)) && + (!event_alias || !strglobmatch(event_alias, print_state->event_glob)) && + (!topic || !strglobmatch_nocase(topic, print_state->event_glob))) + return; + + if (print_state->name_only) { + if (event_alias && strlen(event_alias)) + printf("%s ", event_alias); + else + printf("%s ", event_name); + return; + } + + if (strcmp(print_state->last_topic, topic ?: "")) { + if (topic) + printf("\n%s:\n", topic); + free(print_state->last_topic); + print_state->last_topic = strdup(topic ?: ""); + } + + if (event_alias && strlen(event_alias)) + pos = printf(" %s OR %s", event_name, event_alias); + else + pos = printf(" %s", event_name); + + if (!topic && event_type_desc) { + for (; pos < 53; pos++) + putchar(' '); + printf("[%s]\n", event_type_desc); + } else + putchar('\n'); + + if (desc && print_state->desc) { + printf("%*s", 8, "["); + wordwrap(desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + + if (long_desc && print_state->long_desc) { + printf("%*s", 8, "["); + wordwrap(long_desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + + if (print_state->detailed && encoding_desc) { + printf("%*s%s", 8, "", encoding_desc); + if (metric_name) + printf(" MetricName: %s", metric_name); + if (metric_expr) + printf(" MetricExpr: %s", metric_expr); + putchar('\n'); + } +} + +static void default_print_metric(void *ps, + const char *group, + const char *name, + const char *desc, + const char *long_desc, + const char *expr, + const char *unit __maybe_unused) +{ + struct print_state *print_state = ps; + + if (print_state->event_glob && + (!print_state->metrics || !name || !strglobmatch(name, print_state->event_glob)) && + (!print_state->metricgroups || !group || !strglobmatch(group, print_state->event_glob))) + return; + + if (!print_state->name_only && !print_state->last_metricgroups) { + if (print_state->metricgroups) { + printf("\nMetric Groups:\n"); + if (!print_state->metrics) + putchar('\n'); + } else { + printf("\nMetrics:\n\n"); + } + } + if (!print_state->last_metricgroups || + strcmp(print_state->last_metricgroups, group ?: "")) { + if (group && print_state->metricgroups) { + if (print_state->name_only) + printf("%s ", group); + else if (print_state->metrics) + printf("\n%s:\n", group); + else + printf("%s\n", group); + } + free(print_state->last_metricgroups); + print_state->last_metricgroups = strdup(group ?: ""); + } + if (!print_state->metrics) + return; + + if (print_state->name_only) { + if (print_state->metrics && + !strlist__has_entry(print_state->visited_metrics, name)) { + printf("%s ", name); + strlist__add(print_state->visited_metrics, name); + } + return; + } + printf(" %s\n", name); + + if (desc && print_state->desc) { + printf("%*s", 8, "["); + wordwrap(desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + if (long_desc && print_state->long_desc) { + printf("%*s", 8, "["); + wordwrap(long_desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + if (expr && print_state->detailed) { + printf("%*s", 8, "["); + wordwrap(expr, 8, pager_get_columns(), 0); + printf("]\n"); + } +} int cmd_list(int argc, const char **argv) { int i, ret = 0; - bool raw_dump = false; - bool long_desc_flag = false; - bool deprecated = false; - char *pmu_name = NULL; + struct print_state ps = {}; + struct print_callbacks print_cb = { + .print_start = default_print_start, + .print_end = default_print_end, + .print_event = default_print_event, + .print_metric = default_print_metric, + }; const char *hybrid_name = NULL; const char *unit_name = NULL; struct option list_options[] = { - OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), - OPT_BOOLEAN('d', "desc", &desc_flag, + OPT_BOOLEAN(0, "raw-dump", &ps.name_only, "Dump raw events"), + OPT_BOOLEAN('d', "desc", &ps.desc, "Print extra event descriptions. --no-desc to not print."), - OPT_BOOLEAN('v', "long-desc", &long_desc_flag, + OPT_BOOLEAN('v', "long-desc", &ps.long_desc, "Print longer event descriptions."), - OPT_BOOLEAN(0, "details", &details_flag, + OPT_BOOLEAN(0, "details", &ps.detailed, "Print information on the perf event names and expressions used internally by events."), - OPT_BOOLEAN(0, "deprecated", &deprecated, + OPT_BOOLEAN(0, "deprecated", &ps.deprecated, "Print deprecated events."), OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), @@ -63,20 +272,28 @@ int cmd_list(int argc, const char **argv) setup_pager(); - if (!raw_dump && pager_in_use()) - printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); + if (!ps.name_only) + setup_pager(); + ps.desc = !ps.long_desc; + ps.last_topic = strdup(""); + assert(ps.last_topic); + ps.visited_metrics = strlist__new(NULL, NULL); + assert(ps.visited_metrics); if (unit_name) - pmu_name = strdup(unit_name); + ps.pmu_glob = strdup(unit_name); else if (hybrid_name) { - pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_name); - if (!pmu_name) + ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); + if (!ps.pmu_glob) pr_warning("WARNING: hybrid cputype is not supported!\n"); } + print_cb.print_start(&ps); + if (argc == 0) { - print_events(NULL, raw_dump, !desc_flag, long_desc_flag, - details_flag, deprecated, pmu_name); + ps.metrics = true; + ps.metricgroups = true; + print_events(&print_cb, &ps); goto out; } @@ -84,31 +301,35 @@ int cmd_list(int argc, const char **argv) char *sep, *s; if (strcmp(argv[i], "tracepoint") == 0) - print_tracepoint_events(NULL, NULL, raw_dump); + print_tracepoint_events(&print_cb, &ps); else if (strcmp(argv[i], "hw") == 0 || strcmp(argv[i], "hardware") == 0) - print_symbol_events(NULL, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump); + print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - print_symbol_events(NULL, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump); - print_tool_events(NULL, raw_dump); + print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + print_tool_events(&print_cb, &ps); } else if (strcmp(argv[i], "cache") == 0 || strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(NULL, raw_dump); + print_hwcache_events(&print_cb, &ps); else if (strcmp(argv[i], "pmu") == 0) - print_pmu_events(NULL, raw_dump, !desc_flag, - long_desc_flag, details_flag, - deprecated, pmu_name); + print_pmu_events(&print_cb, &ps); else if (strcmp(argv[i], "sdt") == 0) - print_sdt_events(NULL, NULL, raw_dump); - else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) - metricgroup__print(true, false, NULL, raw_dump, details_flag, pmu_name); - else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) - metricgroup__print(false, true, NULL, raw_dump, details_flag, pmu_name); - else if ((sep = strchr(argv[i], ':')) != NULL) { + print_sdt_events(&print_cb, &ps); + else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { + ps.metricgroups = false; + ps.metrics = true; + metricgroup__print(&print_cb, &ps); + } else if (strcmp(argv[i], "metricgroup") == 0 || + strcmp(argv[i], "metricgroups") == 0) { + ps.metricgroups = true; + ps.metrics = false; + metricgroup__print(&print_cb, &ps); + } else if ((sep = strchr(argv[i], ':')) != NULL) { int sep_idx; + char *old_pmu_glob = ps.pmu_glob; sep_idx = sep - argv[i]; s = strdup(argv[i]); @@ -118,34 +339,42 @@ int cmd_list(int argc, const char **argv) } s[sep_idx] = '\0'; - print_tracepoint_events(s, s + sep_idx + 1, raw_dump); - print_sdt_events(s, s + sep_idx + 1, raw_dump); - metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name); + ps.pmu_glob = s; + ps.event_glob = s + sep_idx + 1; + print_tracepoint_events(&print_cb, &ps); + print_sdt_events(&print_cb, &ps); + ps.metrics = true; + ps.metricgroups = true; + metricgroup__print(&print_cb, &ps); free(s); + ps.pmu_glob = old_pmu_glob; } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - print_symbol_events(s, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump); - print_symbol_events(s, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump); - print_tool_events(s, raw_dump); - print_hwcache_events(s, raw_dump); - print_pmu_events(s, raw_dump, !desc_flag, - long_desc_flag, - details_flag, - deprecated, - pmu_name); - print_tracepoint_events(NULL, s, raw_dump); - print_sdt_events(NULL, s, raw_dump); - metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name); + ps.event_glob = s; + print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); + print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + print_tool_events(&print_cb, &ps); + print_hwcache_events(&print_cb, &ps); + print_pmu_events(&print_cb, &ps); + print_tracepoint_events(&print_cb, &ps); + print_sdt_events(&print_cb, &ps); + ps.metrics = true; + ps.metricgroups = true; + metricgroup__print(&print_cb, &ps); free(s); } } out: - free(pmu_name); + print_cb.print_end(&ps); + free(ps.pmu_glob); + free(ps.last_topic); + free(ps.last_metricgroups); + strlist__delete(ps.visited_metrics); return ret; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index cf9e2452d3229..6eac7a60ed270 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -12,6 +12,7 @@ #include "strbuf.h" #include "pmu.h" #include "pmu-hybrid.h" +#include "print-events.h" #include "expr.h" #include "rblist.h" #include @@ -353,51 +354,65 @@ static bool match_pe_metric(const struct pmu_event *pe, const char *metric) match_metric(pe->metric_name, metric); } +/** struct mep - RB-tree node for building printing information. */ struct mep { + /** nd - RB-tree element. */ struct rb_node nd; - const char *name; - struct strlist *metrics; + /** @metric_group: Owned metric group name, separated others with ';'. */ + char *metric_group; + const char *metric_name; + const char *metric_desc; + const char *metric_long_desc; + const char *metric_expr; + const char *metric_unit; }; static int mep_cmp(struct rb_node *rb_node, const void *entry) { struct mep *a = container_of(rb_node, struct mep, nd); struct mep *b = (struct mep *)entry; + int ret; - return strcmp(a->name, b->name); + ret = strcmp(a->metric_group, b->metric_group); + if (ret) + return ret; + + return strcmp(a->metric_name, b->metric_name); } -static struct rb_node *mep_new(struct rblist *rl __maybe_unused, - const void *entry) +static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry) { struct mep *me = malloc(sizeof(struct mep)); if (!me) return NULL; + memcpy(me, entry, sizeof(struct mep)); - me->name = strdup(me->name); - if (!me->name) - goto out_me; - me->metrics = strlist__new(NULL, NULL); - if (!me->metrics) - goto out_name; return &me->nd; -out_name: - zfree(&me->name); -out_me: +} + +static void mep_delete(struct rblist *rl __maybe_unused, + struct rb_node *nd) +{ + struct mep *me = container_of(nd, struct mep, nd); + + zfree(&me->metric_group); free(me); - return NULL; } -static struct mep *mep_lookup(struct rblist *groups, const char *name) +static struct mep *mep_lookup(struct rblist *groups, const char *metric_group, + const char *metric_name) { struct rb_node *nd; struct mep me = { - .name = name + .metric_group = strdup(metric_group), + .metric_name = metric_name, }; nd = rblist__find(groups, &me); - if (nd) + if (nd) { + free(me.metric_group); return container_of(nd, struct mep, nd); + } rblist__add_node(groups, &me); nd = rblist__find(groups, &me); if (nd) @@ -405,107 +420,37 @@ static struct mep *mep_lookup(struct rblist *groups, const char *name) return NULL; } -static void mep_delete(struct rblist *rl __maybe_unused, - struct rb_node *nd) -{ - struct mep *me = container_of(nd, struct mep, nd); - - strlist__delete(me->metrics); - zfree(&me->name); - free(me); -} - -static void metricgroup__print_strlist(struct strlist *metrics, bool raw) -{ - struct str_node *sn; - int n = 0; - - strlist__for_each_entry (sn, metrics) { - if (raw) - printf("%s%s", n > 0 ? " " : "", sn->s); - else - printf(" %s\n", sn->s); - n++; - } - if (raw) - putchar('\n'); -} - -static int metricgroup__print_pmu_event(const struct pmu_event *pe, - bool metricgroups, char *filter, - bool raw, bool details, - struct rblist *groups, - struct strlist *metriclist) +static int metricgroup__add_to_mep_groups(const struct pmu_event *pe, + struct rblist *groups) { const char *g; char *omg, *mg; - g = pe->metric_group; - if (!g && pe->metric_name) { - if (pe->name) - return 0; - g = "No_group"; - } - - if (!g) - return 0; - - mg = strdup(g); - + mg = strdup(pe->metric_group ?: "No_group"); if (!mg) return -ENOMEM; omg = mg; while ((g = strsep(&mg, ";")) != NULL) { struct mep *me; - char *s; g = skip_spaces(g); - if (*g == 0) - g = "No_group"; - if (filter && !strstr(g, filter)) - continue; - if (raw) - s = (char *)pe->metric_name; - else { - if (asprintf(&s, "%s\n%*s%s]", - pe->metric_name, 8, "[", pe->desc) < 0) - return -1; - if (details) { - if (asprintf(&s, "%s\n%*s%s]", - s, 8, "[", pe->metric_expr) < 0) - return -1; - } - } - - if (!s) - continue; + if (strlen(g)) + me = mep_lookup(groups, g, pe->metric_name); + else + me = mep_lookup(groups, "No_group", pe->metric_name); - if (!metricgroups) { - strlist__add(metriclist, s); - } else { - me = mep_lookup(groups, g); - if (!me) - continue; - strlist__add(me->metrics, s); + if (me) { + me->metric_desc = pe->desc; + me->metric_long_desc = pe->long_desc; + me->metric_expr = pe->metric_expr; + me->metric_unit = pe->unit; } - - if (!raw) - free(s); } free(omg); return 0; } -struct metricgroup_print_sys_idata { - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - struct metricgroup_iter_data { pmu_event_iter_fn fn; void *data; @@ -528,61 +473,26 @@ static int metricgroup__sys_event_iter(const struct pmu_event *pe, return d->fn(pe, table, d->data); } - return 0; } -static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *data) -{ - struct metricgroup_print_sys_idata *d = data; - - return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw, - d->details, d->groups, d->metriclist); -} - -struct metricgroup_print_data { - const char *pmu_name; - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - -static int metricgroup__print_callback(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *vdata) +static int metricgroup__add_to_mep_groups_callback(const struct pmu_event *pe, + const struct pmu_events_table *table __maybe_unused, + void *vdata) { - struct metricgroup_print_data *data = vdata; - const char *pmu = pe->pmu ?: "cpu"; + struct rblist *groups = vdata; - if (!pe->metric_expr) - return 0; - - if (data->pmu_name && strcmp(data->pmu_name, pmu)) + if (!pe->metric_name) return 0; - return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, - data->raw, data->details, data->groups, - data->metriclist); + return metricgroup__add_to_mep_groups(pe, groups); } -void metricgroup__print(bool metrics, bool metricgroups, char *filter, - bool raw, bool details, const char *pmu_name) +void metricgroup__print(const struct print_callbacks *print_cb, void *print_state) { struct rblist groups; - struct rb_node *node, *next; - struct strlist *metriclist = NULL; const struct pmu_events_table *table; - - if (!metricgroups) { - metriclist = strlist__new(NULL, NULL); - if (!metriclist) - return; - } + struct rb_node *node, *next; rblist__init(&groups); groups.node_new = mep_new; @@ -590,56 +500,31 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter, groups.node_delete = mep_delete; table = pmu_events_table__find(); if (table) { - struct metricgroup_print_data data = { - .pmu_name = pmu_name, - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }; - pmu_events_table_for_each_event(table, - metricgroup__print_callback, - &data); + metricgroup__add_to_mep_groups_callback, + &groups); } { struct metricgroup_iter_data data = { - .fn = metricgroup__print_sys_event_iter, - .data = (void *) &(struct metricgroup_print_sys_idata){ - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }, + .fn = metricgroup__add_to_mep_groups_callback, + .data = &groups, }; - pmu_for_each_sys_event(metricgroup__sys_event_iter, &data); } - if (!filter || !rblist__empty(&groups)) { - if (metricgroups && !raw) - printf("\nMetric Groups:\n\n"); - else if (metrics && !raw) - printf("\nMetrics:\n\n"); - } - for (node = rb_first_cached(&groups.entries); node; node = next) { struct mep *me = container_of(node, struct mep, nd); - if (metricgroups) - printf("%s%s%s", me->name, metrics && !raw ? ":" : "", raw ? " " : "\n"); - if (metrics) - metricgroup__print_strlist(me->metrics, raw); + print_cb->print_metric(print_state, + me->metric_group, + me->metric_name, + me->metric_desc, + me->metric_long_desc, + me->metric_expr, + me->metric_unit); next = rb_next(node); rblist__remove_node(&groups, node); } - if (!metricgroups) - metricgroup__print_strlist(metriclist, raw); - strlist__delete(metriclist); } static const char *code_characters = ",-=@"; diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 732d3a0d33341..0013cf582173c 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -10,6 +10,7 @@ struct evlist; struct evsel; struct option; +struct print_callbacks; struct rblist; struct cgroup; @@ -78,8 +79,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist, bool metric_no_merge, struct rblist *metric_events); -void metricgroup__print(bool metrics, bool groups, char *filter, - bool raw, bool details, const char *pmu_name); +void metricgroup__print(const struct print_callbacks *print_cb, void *print_state); bool metricgroup__has_metric(const char *metric); int arch_get_runtimeparam(const struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 075c82dd1347f..e9a4f31926bf4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -23,6 +23,7 @@ #include "evsel.h" #include "pmu.h" #include "parse-events.h" +#include "print-events.h" #include "header.h" #include "string2.h" #include "strbuf.h" @@ -1579,13 +1580,6 @@ static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, return buf; } -static char *format_alias_or(char *buf, int len, const struct perf_pmu *pmu, - const struct perf_pmu_alias *alias) -{ - snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); - return buf; -} - /** Struct for ordering events as output in perf list. */ struct sevent { /** PMU for event. */ @@ -1629,7 +1623,7 @@ static int cmp_sevent(const void *a, const void *b) /* Order CPU core events to be first */ if (as->is_cpu != bs->is_cpu) - return bs->is_cpu - as->is_cpu; + return as->is_cpu ? -1 : 1; /* Order by PMU name. */ a_pmu_name = as->pmu->name ?: ""; @@ -1642,27 +1636,6 @@ static int cmp_sevent(const void *a, const void *b) return strcmp(a_name, b_name); } -static void wordwrap(char *s, int start, int max, int corr) -{ - int column = start; - int n; - - while (*s) { - int wlen = strcspn(s, " \t"); - - if (column + wlen >= max && column > start) { - printf("\n%*s", start, ""); - column = start + corr; - } - n = printf("%s%.*s", column > start ? " " : "", wlen, s); - if (n <= 0) - break; - s += wlen; - column += n; - s = skip_spaces(s); - } -} - bool is_pmu_core(const char *name) { return !strcmp(name, "cpu") || is_arm_pmu_core(name); @@ -1685,24 +1658,19 @@ static bool pmu_alias_is_duplicate(struct sevent *alias_a, return strcmp(a_pmu_name, b_pmu_name) == 0; } -void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name) +void print_pmu_events(const struct print_callbacks *print_cb, void *print_state) { struct perf_pmu *pmu; - struct perf_pmu_alias *alias; + struct perf_pmu_alias *event; char buf[1024]; int printed = 0; int len, j; struct sevent *aliases; - int numdesc = 0; - int columns = pager_get_columns(); - char *topic = NULL; pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - list_for_each_entry(alias, &pmu->aliases, list) + list_for_each_entry(event, &pmu->aliases, list) len++; if (pmu->selectable) len++; @@ -1715,32 +1683,15 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - bool is_cpu; + bool is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); - if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) - continue; - - is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); - - list_for_each_entry(alias, &pmu->aliases, list) { - if (alias->deprecated && !deprecated) - continue; - - if (event_glob != NULL && - !(strglobmatch_nocase(alias->name, event_glob) || - (!is_cpu && - strglobmatch_nocase(alias->name, event_glob)) || - (alias->topic && - strglobmatch_nocase(alias->topic, event_glob)))) - continue; - - aliases[j].event = alias; + list_for_each_entry(event, &pmu->aliases, list) { + aliases[j].event = event; aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; j++; } - if (pmu->selectable && - (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { + if (pmu->selectable) { aliases[j].event = NULL; aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; @@ -1750,7 +1701,12 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, len = j; qsort(aliases, len, sizeof(struct sevent), cmp_sevent); for (j = 0; j < len; j++) { - char *name, *desc; + const char *name, *alias = NULL, *scale_unit = NULL, + *desc = NULL, *long_desc = NULL, + *encoding_desc = NULL, *topic = NULL, + *metric_name = NULL, *metric_expr = NULL; + bool deprecated = false; + size_t buf_used; /* Skip duplicates */ if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) @@ -1758,48 +1714,51 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, if (!aliases[j].event) { /* A selectable event. */ - snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name); + buf_used = snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name) + 1; name = buf; - } else if (aliases[j].event->desc) { - name = aliases[j].event->name; } else { - if (!name_only && aliases[j].is_cpu) { - name = format_alias_or(buf, sizeof(buf), aliases[j].pmu, - aliases[j].event); + if (aliases[j].event->desc) { + name = aliases[j].event->name; + buf_used = 0; } else { name = format_alias(buf, sizeof(buf), aliases[j].pmu, aliases[j].event); + if (aliases[j].is_cpu) { + alias = name; + name = aliases[j].event->name; + } + buf_used = strlen(buf) + 1; } - } - if (name_only) { - printf("%s ", name); - continue; - } - printed++; - if (!aliases[j].event || !aliases[j].event->desc || quiet_flag) { - printf(" %-50s [Kernel PMU event]\n", name); - continue; - } - if (numdesc++ == 0) - printf("\n"); - if (aliases[j].event->topic && (!topic || - strcmp(topic, aliases[j].event->topic))) { - printf("%s%s:\n", topic ? "\n" : "", aliases[j].event->topic); + if (strlen(aliases[j].event->unit) || aliases[j].event->scale != 1.0) { + scale_unit = buf + buf_used; + buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%G%s", aliases[j].event->scale, + aliases[j].event->unit) + 1; + } + desc = aliases[j].event->desc; + long_desc = aliases[j].event->long_desc; topic = aliases[j].event->topic; + encoding_desc = buf + buf_used; + buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%s/%s/", aliases[j].pmu->name, + aliases[j].event->str) + 1; + metric_name = aliases[j].event->metric_name; + metric_expr = aliases[j].event->metric_expr; + deprecated = aliases[j].event->deprecated; } - printf(" %-50s\n", name); - printf("%*s", 8, "["); - desc = long_desc ? aliases[j].event->long_desc : aliases[j].event->desc; - wordwrap(desc, 8, columns, 0); - printf("]\n"); - if (details_flag) { - printf("%*s%s/%s/ ", 8, "", aliases[j].pmu->name, aliases[j].event->str); - if (aliases[j].event->metric_name) - printf(" MetricName: %s", aliases[j].event->metric_name); - if (aliases[j].event->metric_expr) - printf(" MetricExpr: %s", aliases[j].event->metric_expr); - putchar('\n'); - } + print_cb->print_event(print_state, + aliases[j].pmu->name, + topic, + name, + alias, + scale_unit, + deprecated, + "Kernel PMU event", + desc, + long_desc, + encoding_desc, + metric_name, + metric_expr); } if (printed && pager_in_use()) printf("\n"); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index ee02e1ef91878..69ca0004f94f6 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -12,6 +12,7 @@ struct evsel_config_term; struct perf_cpu_map; +struct print_callbacks; enum { PERF_PMU_FORMAT_VALUE_CONFIG, @@ -225,9 +226,7 @@ void perf_pmu__del_formats(struct list_head *formats); struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); bool is_pmu_core(const char *name); -void print_pmu_events(const char *event_glob, bool name_only, bool quiet, - bool long_desc, bool details_flag, - bool deprecated, const char *pmu_name); +void print_pmu_events(const struct print_callbacks *print_cb, void *print_state); bool pmu_have_event(const char *pname, const char *name); int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4); diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index d53dba033597b..2646ae18d9f9b 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -28,6 +28,7 @@ #define MAX_NAME_LEN 100 +/** Strings corresponding to enum perf_type_id. */ static const char * const event_type_descriptors[] = { "Hardware event", "Software event", @@ -55,11 +56,9 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { /* * Print the events from /tracing/events */ -void print_tracepoint_events(const char *subsys_glob, - const char *event_glob, bool name_only) +void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state) { struct dirent **sys_namelist = NULL; - bool printed = false; int sys_items = tracing_events__scandir_alphasort(&sys_namelist); for (int i = 0; i < sys_items; i++) { @@ -73,10 +72,6 @@ void print_tracepoint_events(const char *subsys_glob, !strcmp(sys_dirent->d_name, "..")) continue; - if (subsys_glob != NULL && - !strglobmatch(sys_dirent->d_name, subsys_glob)) - continue; - dir_path = get_events_file(sys_dirent->d_name); if (!dir_path) continue; @@ -94,41 +89,41 @@ void print_tracepoint_events(const char *subsys_glob, if (tp_event_has_id(dir_path, evt_dirent) != 0) continue; - if (event_glob != NULL && - !strglobmatch(evt_dirent->d_name, event_glob)) - continue; - snprintf(evt_path, MAXPATHLEN, "%s:%s", sys_dirent->d_name, evt_dirent->d_name); - if (name_only) - printf("%s ", evt_path); - else { - printf(" %-50s [%s]\n", evt_path, - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - } - printed = true; + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + evt_path, + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + "Tracepoint event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } free(dir_path); free(evt_namelist); } free(sys_namelist); - if (printed && pager_in_use()) - printf("\n"); } -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only) +void print_sdt_events(const struct print_callbacks *print_cb, void *print_state) { - struct probe_cache *pcache; - struct probe_cache_entry *ent; struct strlist *bidlist, *sdtlist; - struct strlist_config cfg = {.dont_dupstr = true}; - struct str_node *nd, *nd2; - char *buf, *path, *ptr = NULL; - bool show_detail = false; - int ret; - - sdtlist = strlist__new(NULL, &cfg); + struct str_node *bid_nd, *sdt_name, *next_sdt_name; + const char *last_sdt_name = NULL; + + /* + * The implicitly sorted sdtlist will hold the tracepoint name followed + * by @. If the tracepoint name is unique (determined by + * looking at the adjacent nodes) the @ is dropped otherwise + * the executable path and buildid are added to the name. + */ + sdtlist = strlist__new(NULL, NULL); if (!sdtlist) { pr_debug("Failed to allocate new strlist for SDT\n"); return; @@ -138,65 +133,78 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, pr_debug("Failed to get buildids: %d\n", errno); return; } - strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s, NULL); + strlist__for_each_entry(bid_nd, bidlist) { + struct probe_cache *pcache; + struct probe_cache_entry *ent; + + pcache = probe_cache__new(bid_nd->s, NULL); if (!pcache) continue; list_for_each_entry(ent, &pcache->entries, node) { - if (!ent->sdt) - continue; - if (subsys_glob && - !strglobmatch(ent->pev.group, subsys_glob)) - continue; - if (event_glob && - !strglobmatch(ent->pev.event, event_glob)) - continue; - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, - ent->pev.event, nd->s); - if (ret > 0) - strlist__add(sdtlist, buf); + char buf[1024]; + + snprintf(buf, sizeof(buf), "%s:%s@%s", + ent->pev.group, ent->pev.event, bid_nd->s); + strlist__add(sdtlist, buf); } probe_cache__delete(pcache); } strlist__delete(bidlist); - strlist__for_each_entry(nd, sdtlist) { - buf = strchr(nd->s, '@'); - if (buf) - *(buf++) = '\0'; - if (name_only) { - printf("%s ", nd->s); - continue; - } - nd2 = strlist__next(nd); - if (nd2) { - ptr = strchr(nd2->s, '@'); - if (ptr) - *ptr = '\0'; - if (strcmp(nd->s, nd2->s) == 0) - show_detail = true; + strlist__for_each_entry(sdt_name, sdtlist) { + bool show_detail = false; + char *bid = strchr(sdt_name->s, '@'); + char *evt_name = NULL; + + if (bid) + *(bid++) = '\0'; + + if (last_sdt_name && !strcmp(last_sdt_name, sdt_name->s)) { + show_detail = true; + } else { + next_sdt_name = strlist__next(sdt_name); + if (next_sdt_name) { + char *bid2 = strchr(next_sdt_name->s, '@'); + + if (bid2) + *bid2 = '\0'; + if (strcmp(sdt_name->s, next_sdt_name->s) == 0) + show_detail = true; + if (bid2) + *bid2 = '@'; + } } + last_sdt_name = sdt_name->s; + if (show_detail) { - path = build_id_cache__origname(buf); - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); - if (ret > 0) { - printf(" %-50s [%s]\n", buf, "SDT event"); - free(buf); + char *path = build_id_cache__origname(bid); + + if (path) { + if (asprintf(&evt_name, "%s@%s(%.12s)", sdt_name->s, path, bid) < 0) + evt_name = NULL; + free(path); } - free(path); - } else - printf(" %-50s [%s]\n", nd->s, "SDT event"); - if (nd2) { - if (strcmp(nd->s, nd2->s) != 0) - show_detail = false; - if (ptr) - *ptr = '@'; } + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + evt_name ?: sdt_name->s, + /*event_alias=*/NULL, + /*deprecated=*/false, + /*scale_unit=*/NULL, + "SDT event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + free(evt_name); } strlist__delete(sdtlist); } -int print_hwcache_events(const char *event_glob, bool name_only) +int print_hwcache_events(const struct print_callbacks *print_cb, void *print_state) { struct strlist *evt_name_list = strlist__new(NULL, NULL); struct str_node *nd; @@ -216,9 +224,6 @@ int print_hwcache_events(const char *event_glob, bool name_only) char name[64]; __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); - if (event_glob != NULL && !strglobmatch(name, event_glob)) - continue; - if (!perf_pmu__has_hybrid()) { if (is_event_supported(PERF_TYPE_HW_CACHE, type | (op << 8) | (i << 16))) @@ -240,55 +245,47 @@ int print_hwcache_events(const char *event_glob, bool name_only) } strlist__for_each_entry(nd, evt_name_list) { - if (name_only) { - printf("%s ", nd->s); - continue; - } - printf(" %-50s [%s]\n", nd->s, event_type_descriptors[PERF_TYPE_HW_CACHE]); + print_cb->print_event(print_state, + "cache", + /*pmu_name=*/NULL, + nd->s, + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_HW_CACHE], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } - if (!strlist__empty(evt_name_list) && pager_in_use()) - printf("\n"); - strlist__delete(evt_name_list); return 0; } -static void print_tool_event(const struct event_symbol *syms, const char *event_glob, - bool name_only) -{ - if (syms->symbol == NULL) - return; - - if (event_glob && !(strglobmatch(syms->symbol, event_glob) || - (syms->alias && strglobmatch(syms->alias, event_glob)))) - return; - - if (name_only) - printf("%s ", syms->symbol); - else { - char name[MAX_NAME_LEN]; - - if (syms->alias && strlen(syms->alias)) - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); - else - strlcpy(name, syms->symbol, MAX_NAME_LEN); - printf(" %-50s [%s]\n", name, "Tool event"); - } -} - -void print_tool_events(const char *event_glob, bool name_only) +void print_tool_events(const struct print_callbacks *print_cb, void *print_state) { // Start at 1 because the first enum entry means no tool event. - for (int i = 1; i < PERF_TOOL_MAX; ++i) - print_tool_event(event_symbols_tool + i, event_glob, name_only); - - if (pager_in_use()) - printf("\n"); + for (int i = 1; i < PERF_TOOL_MAX; ++i) { + print_cb->print_event(print_state, + "tool", + /*pmu_name=*/NULL, + event_symbols_tool[i].symbol, + event_symbols_tool[i].alias, + /*scale_unit=*/NULL, + /*deprecated=*/false, + "Tool event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + } } -void print_symbol_events(const char *event_glob, unsigned int type, - struct event_symbol *syms, unsigned int max, - bool name_only) +void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, + unsigned int type, const struct event_symbol *syms, + unsigned int max) { struct strlist *evt_name_list = strlist__new(NULL, NULL); struct str_node *nd; @@ -305,10 +302,6 @@ void print_symbol_events(const char *event_glob, unsigned int type, if (syms[i].symbol == NULL) continue; - if (event_glob != NULL && !(strglobmatch(syms[i].symbol, event_glob) || - (syms[i].alias && strglobmatch(syms[i].alias, event_glob)))) - continue; - if (!is_event_supported(type, i)) continue; @@ -322,63 +315,92 @@ void print_symbol_events(const char *event_glob, unsigned int type, } strlist__for_each_entry(nd, evt_name_list) { - if (name_only) { - printf("%s ", nd->s); - continue; + char *alias = strstr(nd->s, " OR "); + + if (alias) { + *alias = '\0'; + alias += 4; } - printf(" %-50s [%s]\n", nd->s, event_type_descriptors[type]); + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + nd->s, + alias, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[type], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } - if (!strlist__empty(evt_name_list) && pager_in_use()) - printf("\n"); - strlist__delete(evt_name_list); } /* * Print the help text for the event symbols: */ -void print_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name) +void print_events(const struct print_callbacks *print_cb, void *print_state) { - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, name_only); - - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, name_only); - print_tool_events(event_glob, name_only); - - print_hwcache_events(event_glob, name_only); - - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, - details_flag, deprecated, pmu_name); - - if (event_glob != NULL) - return; - - if (!name_only) { - printf(" %-50s [%s]\n", - "rNNN", - event_type_descriptors[PERF_TYPE_RAW]); - printf(" %-50s [%s]\n", - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", - event_type_descriptors[PERF_TYPE_RAW]); - if (pager_in_use()) - printf(" (see 'man perf-list' on how to encode it)\n\n"); - - printf(" %-50s [%s]\n", - "mem:[/len][:access]", - event_type_descriptors[PERF_TYPE_BREAKPOINT]); - if (pager_in_use()) - printf("\n"); - } - - print_tracepoint_events(NULL, NULL, name_only); - - print_sdt_events(NULL, NULL, name_only); - - metricgroup__print(true, true, NULL, name_only, details_flag, - pmu_name); - - print_libpfm_events(name_only, long_desc); + print_symbol_events(print_cb, print_state, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); + print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + + print_tool_events(print_cb, print_state); + + print_hwcache_events(print_cb, print_state); + + print_pmu_events(print_cb, print_state); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "rNNN", + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_RAW], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_RAW], + "(see 'man perf-list' on how to encode it)", + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "mem:[/len][:access]", + /*scale_unit=*/NULL, + /*event_alias=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_BREAKPOINT], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_tracepoint_events(print_cb, print_state); + + print_sdt_events(print_cb, print_state); + + metricgroup__print(print_cb, print_state); + + print_libpfm_events(print_cb, print_state); } diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h index 1da9910d83a60..c237e53c44870 100644 --- a/tools/perf/util/print-events.h +++ b/tools/perf/util/print-events.h @@ -2,21 +2,39 @@ #ifndef __PERF_PRINT_EVENTS_H #define __PERF_PRINT_EVENTS_H +#include #include struct event_symbol; -void print_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name); -int print_hwcache_events(const char *event_glob, bool name_only); -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only); -void print_symbol_events(const char *event_glob, unsigned int type, - struct event_symbol *syms, unsigned int max, - bool name_only); -void print_tool_events(const char *event_glob, bool name_only); -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, - bool name_only); +struct print_callbacks { + void (*print_start)(void *print_state); + void (*print_end)(void *print_state); + void (*print_event)(void *print_state, const char *topic, + const char *pmu_name, + const char *event_name, const char *event_alias, + const char *scale_unit, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr); + void (*print_metric)(void *print_state, + const char *group, + const char *name, + const char *desc, + const char *long_desc, + const char *expr, + const char *unit); +}; + +/** Print all events, the default when no options are specified. */ +void print_events(const struct print_callbacks *print_cb, void *print_state); +int print_hwcache_events(const struct print_callbacks *print_cb, void *print_state); +void print_sdt_events(const struct print_callbacks *print_cb, void *print_state); +void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, + unsigned int type, const struct event_symbol *syms, + unsigned int max); +void print_tool_events(const struct print_callbacks *print_cb, void *print_state); +void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state); #endif /* __PERF_PRINT_EVENTS_H */ -- GitLab From 6ed249441a7d3ead8e81cc926e68d5e7ae031032 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 17 Nov 2022 13:43:37 -0300 Subject: [PATCH 0684/1480] perf list: Add JSON output option Output events and metrics in a JSON format by overriding the print callbacks. Currently other command line options aren't supported and metrics are repeated once per metric group. Committer testing: $ perf list cache List of pre-defined events (to be used in -e or -M): L1-dcache-load-misses [Hardware cache event] L1-dcache-loads [Hardware cache event] L1-dcache-prefetches [Hardware cache event] L1-icache-load-misses [Hardware cache event] L1-icache-loads [Hardware cache event] branch-load-misses [Hardware cache event] branch-loads [Hardware cache event] dTLB-load-misses [Hardware cache event] dTLB-loads [Hardware cache event] iTLB-load-misses [Hardware cache event] iTLB-loads [Hardware cache event] $ perf list --json cache [ { "Unit": "cache", "EventName": "L1-dcache-load-misses", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "L1-dcache-loads", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "L1-dcache-prefetches", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "L1-icache-load-misses", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "L1-icache-loads", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "branch-load-misses", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "branch-loads", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "dTLB-load-misses", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "dTLB-loads", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "iTLB-load-misses", "EventType": "Hardware cache event" }, { "Unit": "cache", "EventName": "iTLB-loads", "EventType": "Hardware cache event" } ] $ Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/20221114210723.2749751-11-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-list.txt | 4 + tools/perf/builtin-list.c | 308 +++++++++++++++++++------ 2 files changed, 245 insertions(+), 67 deletions(-) diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 44a819af573de..c5a3cb0f57c7c 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt @@ -43,6 +43,10 @@ Print deprecated events. By default the deprecated events are hidden. Print PMU events and metrics limited to the specific PMU name. (e.g. --unit cpu, --unit msr, --unit cpu_core, --unit cpu_atom) +-j:: +--json:: +Output in JSON format. + [[EVENT_MODIFIERS]] EVENT MODIFIERS --------------- diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 0c84fdb3ad37c..84fa2d050eacb 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -19,6 +19,8 @@ #include "util/strlist.h" #include #include +#include +#include #include /** @@ -228,10 +230,176 @@ static void default_print_metric(void *ps, } } +struct json_print_state { + /** Should a separator be printed prior to the next item? */ + bool need_sep; +}; + +static void json_print_start(void *print_state __maybe_unused) +{ + printf("[\n"); +} + +static void json_print_end(void *ps) +{ + struct json_print_state *print_state = ps; + + printf("%s]\n", print_state->need_sep ? "\n" : ""); +} + +static void fix_escape_printf(const char *fmt, ...) +{ + va_list args; + char buf[2048]; + size_t buf_pos = 0; + + va_start(args, fmt); + for (size_t fmt_pos = 0; fmt_pos < strlen(fmt); fmt_pos++) { + switch (fmt[fmt_pos]) { + case '%': { + const char *s = va_arg(args, const char*); + + fmt_pos++; + assert(fmt[fmt_pos] == 's'); + for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) { + switch (s[s_pos]) { + case '\\': + __fallthrough; + case '\"': + buf[buf_pos++] = '\\'; + assert(buf_pos < sizeof(buf)); + __fallthrough; + default: + buf[buf_pos++] = s[s_pos]; + assert(buf_pos < sizeof(buf)); + break; + } + } + break; + } + default: + buf[buf_pos++] = fmt[fmt_pos]; + assert(buf_pos < sizeof(buf)); + break; + } + } + va_end(args); + buf[buf_pos] = '\0'; + fputs(buf, stdout); +} + +static void json_print_event(void *ps, const char *pmu_name, const char *topic, + const char *event_name, const char *event_alias, + const char *scale_unit, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr) +{ + struct json_print_state *print_state = ps; + bool need_sep = false; + + printf("%s{\n", print_state->need_sep ? ",\n" : ""); + print_state->need_sep = true; + if (pmu_name) { + fix_escape_printf("\t\"Unit\": \"%s\"", pmu_name); + need_sep = true; + } + if (topic) { + fix_escape_printf("%s\t\"Topic\": \"%s\"", need_sep ? ",\n" : "", topic); + need_sep = true; + } + if (event_name) { + fix_escape_printf("%s\t\"EventName\": \"%s\"", need_sep ? ",\n" : "", event_name); + need_sep = true; + } + if (event_alias && strlen(event_alias)) { + fix_escape_printf("%s\t\"EventAlias\": \"%s\"", need_sep ? ",\n" : "", event_alias); + need_sep = true; + } + if (scale_unit && strlen(scale_unit)) { + fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", + scale_unit); + need_sep = true; + } + if (event_type_desc) { + fix_escape_printf("%s\t\"EventType\": \"%s\"", need_sep ? ",\n" : "", + event_type_desc); + need_sep = true; + } + if (deprecated) { + fix_escape_printf("%s\t\"Deprecated\": \"%s\"", need_sep ? ",\n" : "", + deprecated ? "1" : "0"); + need_sep = true; + } + if (desc) { + fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + need_sep = true; + } + if (long_desc) { + fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + long_desc); + need_sep = true; + } + if (encoding_desc) { + fix_escape_printf("%s\t\"Encoding\": \"%s\"", need_sep ? ",\n" : "", encoding_desc); + need_sep = true; + } + if (metric_name) { + fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", metric_name); + need_sep = true; + } + if (metric_expr) { + fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", metric_expr); + need_sep = true; + } + printf("%s}", need_sep ? "\n" : ""); +} + +static void json_print_metric(void *ps __maybe_unused, const char *group, + const char *name, const char *desc, + const char *long_desc, const char *expr, + const char *unit) +{ + struct json_print_state *print_state = ps; + bool need_sep = false; + + printf("%s{\n", print_state->need_sep ? ",\n" : ""); + print_state->need_sep = true; + if (group) { + fix_escape_printf("\t\"MetricGroup\": \"%s\"", group); + need_sep = true; + } + if (name) { + fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", name); + need_sep = true; + } + if (expr) { + fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", expr); + need_sep = true; + } + if (unit) { + fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", unit); + need_sep = true; + } + if (desc) { + fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + need_sep = true; + } + if (long_desc) { + fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + long_desc); + need_sep = true; + } + printf("%s}", need_sep ? "\n" : ""); +} + int cmd_list(int argc, const char **argv) { int i, ret = 0; - struct print_state ps = {}; + struct print_state default_ps = {}; + struct print_state json_ps = {}; + void *ps = &default_ps; struct print_callbacks print_cb = { .print_start = default_print_start, .print_end = default_print_end, @@ -240,15 +408,17 @@ int cmd_list(int argc, const char **argv) }; const char *hybrid_name = NULL; const char *unit_name = NULL; + bool json = false; struct option list_options[] = { - OPT_BOOLEAN(0, "raw-dump", &ps.name_only, "Dump raw events"), - OPT_BOOLEAN('d', "desc", &ps.desc, + OPT_BOOLEAN(0, "raw-dump", &default_ps.name_only, "Dump raw events"), + OPT_BOOLEAN('j', "json", &json, "JSON encode events and metrics"), + OPT_BOOLEAN('d', "desc", &default_ps.desc, "Print extra event descriptions. --no-desc to not print."), - OPT_BOOLEAN('v', "long-desc", &ps.long_desc, + OPT_BOOLEAN('v', "long-desc", &default_ps.long_desc, "Print longer event descriptions."), - OPT_BOOLEAN(0, "details", &ps.detailed, + OPT_BOOLEAN(0, "details", &default_ps.detailed, "Print information on the perf event names and expressions used internally by events."), - OPT_BOOLEAN(0, "deprecated", &ps.deprecated, + OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated, "Print deprecated events."), OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), @@ -272,28 +442,37 @@ int cmd_list(int argc, const char **argv) setup_pager(); - if (!ps.name_only) + if (!default_ps.name_only) setup_pager(); - ps.desc = !ps.long_desc; - ps.last_topic = strdup(""); - assert(ps.last_topic); - ps.visited_metrics = strlist__new(NULL, NULL); - assert(ps.visited_metrics); - if (unit_name) - ps.pmu_glob = strdup(unit_name); - else if (hybrid_name) { - ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); - if (!ps.pmu_glob) - pr_warning("WARNING: hybrid cputype is not supported!\n"); + if (json) { + print_cb = (struct print_callbacks){ + .print_start = json_print_start, + .print_end = json_print_end, + .print_event = json_print_event, + .print_metric = json_print_metric, + }; + ps = &json_ps; + } else { + default_ps.desc = !default_ps.long_desc; + default_ps.last_topic = strdup(""); + assert(default_ps.last_topic); + default_ps.visited_metrics = strlist__new(NULL, NULL); + assert(default_ps.visited_metrics); + if (unit_name) + default_ps.pmu_glob = strdup(unit_name); + else if (hybrid_name) { + default_ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); + if (!default_ps.pmu_glob) + pr_warning("WARNING: hybrid cputype is not supported!\n"); + } } - - print_cb.print_start(&ps); + print_cb.print_start(ps); if (argc == 0) { - ps.metrics = true; - ps.metricgroups = true; - print_events(&print_cb, &ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + print_events(&print_cb, ps); goto out; } @@ -301,80 +480,75 @@ int cmd_list(int argc, const char **argv) char *sep, *s; if (strcmp(argv[i], "tracepoint") == 0) - print_tracepoint_events(&print_cb, &ps); + print_tracepoint_events(&print_cb, ps); else if (strcmp(argv[i], "hw") == 0 || strcmp(argv[i], "hardware") == 0) - print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, event_symbols_sw, PERF_COUNT_SW_MAX); - print_tool_events(&print_cb, &ps); + print_tool_events(&print_cb, ps); } else if (strcmp(argv[i], "cache") == 0 || strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(&print_cb, &ps); + print_hwcache_events(&print_cb, ps); else if (strcmp(argv[i], "pmu") == 0) - print_pmu_events(&print_cb, &ps); + print_pmu_events(&print_cb, ps); else if (strcmp(argv[i], "sdt") == 0) - print_sdt_events(&print_cb, &ps); + print_sdt_events(&print_cb, ps); else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { - ps.metricgroups = false; - ps.metrics = true; - metricgroup__print(&print_cb, &ps); + default_ps.metricgroups = false; + default_ps.metrics = true; + metricgroup__print(&print_cb, ps); } else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) { - ps.metricgroups = true; - ps.metrics = false; - metricgroup__print(&print_cb, &ps); + default_ps.metricgroups = true; + default_ps.metrics = false; + metricgroup__print(&print_cb, ps); } else if ((sep = strchr(argv[i], ':')) != NULL) { - int sep_idx; - char *old_pmu_glob = ps.pmu_glob; + char *old_pmu_glob = default_ps.pmu_glob; - sep_idx = sep - argv[i]; - s = strdup(argv[i]); - if (s == NULL) { + default_ps.event_glob = strdup(argv[i]); + if (!default_ps.event_glob) { ret = -1; goto out; } - s[sep_idx] = '\0'; - ps.pmu_glob = s; - ps.event_glob = s + sep_idx + 1; - print_tracepoint_events(&print_cb, &ps); - print_sdt_events(&print_cb, &ps); - ps.metrics = true; - ps.metricgroups = true; - metricgroup__print(&print_cb, &ps); - free(s); - ps.pmu_glob = old_pmu_glob; + print_tracepoint_events(&print_cb, ps); + print_sdt_events(&print_cb, ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + metricgroup__print(&print_cb, ps); + zfree(&default_ps.event_glob); + default_ps.pmu_glob = old_pmu_glob; } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - ps.event_glob = s; - print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + default_ps.event_glob = s; + print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); - print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, event_symbols_sw, PERF_COUNT_SW_MAX); - print_tool_events(&print_cb, &ps); - print_hwcache_events(&print_cb, &ps); - print_pmu_events(&print_cb, &ps); - print_tracepoint_events(&print_cb, &ps); - print_sdt_events(&print_cb, &ps); - ps.metrics = true; - ps.metricgroups = true; - metricgroup__print(&print_cb, &ps); + print_tool_events(&print_cb, ps); + print_hwcache_events(&print_cb, ps); + print_pmu_events(&print_cb, ps); + print_tracepoint_events(&print_cb, ps); + print_sdt_events(&print_cb, ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + metricgroup__print(&print_cb, ps); free(s); } } out: - print_cb.print_end(&ps); - free(ps.pmu_glob); - free(ps.last_topic); - free(ps.last_metricgroups); - strlist__delete(ps.visited_metrics); + print_cb.print_end(ps); + free(default_ps.pmu_glob); + free(default_ps.last_topic); + free(default_ps.last_metricgroups); + strlist__delete(default_ps.visited_metrics); return ret; } -- GitLab From eadcab4c7a66e1df03d32da0db55d89fd9343fcc Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 21 Nov 2022 07:52:33 +0000 Subject: [PATCH 0685/1480] perf trace: Use macro RAW_SYSCALL_ARGS_NUM to replace number This patch defines a macro RAW_SYSCALL_ARGS_NUM to replace the open coded number '6'. Signed-off-by: Leo Yan Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221121075237.127706-2-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3257da5cad231..22008a31684b6 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -88,6 +88,8 @@ # define F_LINUX_SPECIFIC_BASE 1024 #endif +#define RAW_SYSCALL_ARGS_NUM 6 + /* * strtoul: Go from a string to a value, i.e. for msr: MSR_FS_BASE to 0xc0000100 */ @@ -108,7 +110,7 @@ struct syscall_fmt { const char *sys_enter, *sys_exit; } bpf_prog_name; - struct syscall_arg_fmt arg[6]; + struct syscall_arg_fmt arg[RAW_SYSCALL_ARGS_NUM]; u8 nr_args; bool errpid; bool timeout; @@ -1229,7 +1231,7 @@ struct syscall { */ struct bpf_map_syscall_entry { bool enabled; - u16 string_args_len[6]; + u16 string_args_len[RAW_SYSCALL_ARGS_NUM]; }; /* @@ -1661,7 +1663,7 @@ static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args) { int idx; - if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0) + if (nr_args == RAW_SYSCALL_ARGS_NUM && sc->fmt && sc->fmt->nr_args != 0) nr_args = sc->fmt->nr_args; sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt)); @@ -1812,7 +1814,8 @@ static int trace__read_syscall_info(struct trace *trace, int id) sc->tp_format = trace_event__tp_format("syscalls", tp_name); } - if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields)) + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? + RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields)) return -ENOMEM; if (IS_ERR(sc->tp_format)) -- GitLab From d4223e1776c30b2ce8d0e6eaadcbf696e60fca3c Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 21 Nov 2022 07:52:34 +0000 Subject: [PATCH 0686/1480] perf trace: Return error if a system call doesn't exist When a system call is not detected, the reason is either because the system call ID is out of scope or failure to find the corresponding path in the sysfs, trace__read_syscall_info() returns zero. Finally, without returning an error value it introduces confusion for the caller. This patch lets the function trace__read_syscall_info() to return -EEXIST when a system call doesn't exist. Fixes: b8b1033fcaa091d8 ("perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages") Signed-off-by: Leo Yan Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: bpf@vger.kernel.org Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221121075237.127706-3-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 22008a31684b6..bd5513b15cde8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1796,11 +1796,11 @@ static int trace__read_syscall_info(struct trace *trace, int id) #endif sc = trace->syscalls.table + id; if (sc->nonexistent) - return 0; + return -EEXIST; if (name == NULL) { sc->nonexistent = true; - return 0; + return -EEXIST; } sc->name = name; -- GitLab From 03e9a5d8eb552a1bf692a9c8a5ecd50f4e428006 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 21 Nov 2022 07:52:35 +0000 Subject: [PATCH 0687/1480] perf trace: Handle failure when trace point folder is missed On Arm64 a case is perf tools fails to find the corresponding trace point folder for system calls listed in the table 'syscalltbl_arm64', e.g. the generated system call table contains "lookup_dcookie" but we cannot find out the matched trace point folder for it. We need to figure out if there have any issue for the generated system call table, on the other hand, we need to handle the case when trace point folder is missed under sysfs, this patch sets the flag syscall::nonexistent as true and returns the error from trace__read_syscall_info(). Another problem is for trace__syscall_info(), it returns two different values if a system call doesn't exist: at the first time calling trace__syscall_info() it returns NULL when the system call doesn't exist, later if call trace__syscall_info() again for the same missed system call, it returns pointer of syscall. trace__syscall_info() checks the condition 'syscalls.table[id].name == NULL', but the name will be assigned in the first invoking even the system call is not found. So checking system call's name in trace__syscall_info() is not the right thing to do, this patch simply checks flag syscall::nonexistent to make decision if a system call exists or not, finally trace__syscall_info() returns the consistent result (NULL) if a system call doesn't existed. Fixes: b8b1033fcaa091d8 ("perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages") Signed-off-by: Leo Yan Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: bpf@vger.kernel.org Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221121075237.127706-4-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bd5513b15cde8..071e7598391f1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1814,13 +1814,19 @@ static int trace__read_syscall_info(struct trace *trace, int id) sc->tp_format = trace_event__tp_format("syscalls", tp_name); } + /* + * Fails to read trace point format via sysfs node, so the trace point + * doesn't exist. Set the 'nonexistent' flag as true. + */ + if (IS_ERR(sc->tp_format)) { + sc->nonexistent = true; + return PTR_ERR(sc->tp_format); + } + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields)) return -ENOMEM; - if (IS_ERR(sc->tp_format)) - return PTR_ERR(sc->tp_format); - sc->args = sc->tp_format->format.fields; /* * We need to check and discard the first variable '__syscall_nr' @@ -2137,11 +2143,8 @@ static struct syscall *trace__syscall_info(struct trace *trace, (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; - if (trace->syscalls.table[id].name == NULL) { - if (trace->syscalls.table[id].nonexistent) - return NULL; + if (trace->syscalls.table && trace->syscalls.table[id].nonexistent) goto out_cant_read; - } return &trace->syscalls.table[id]; -- GitLab From 9bc427a0613da358f56fe499c690d97ce5d1af26 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 21 Nov 2022 07:52:36 +0000 Subject: [PATCH 0688/1480] perf augmented_raw_syscalls: Remove unused variable 'syscall' The local variable 'syscall' is not used anymore, remove it. Signed-off-by: Leo Yan Tested-by: Arnaldo Carvalho de Melo Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221121075237.127706-5-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 7dc24c9173a75..4203f92c063bf 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -389,7 +389,6 @@ int sys_enter(struct syscall_enter_args *args) * initial, non-augmented raw_syscalls:sys_enter payload. */ unsigned int len = sizeof(augmented_args->args); - struct syscall *syscall; if (pid_filter__has(&pids_filtered, getpid())) return 0; -- GitLab From 8daf87f5922730468c98ae588573386042bc2992 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 21 Nov 2022 07:52:37 +0000 Subject: [PATCH 0689/1480] perf trace: Remove unused bpf map 'syscalls' augmented_raw_syscalls.c defines the bpf map 'syscalls' which is initialized by perf tool in user space to indicate which system calls are enabled for tracing, on the other flip eBPF program relies on the map to filter out the trace events which are not enabled. The map also includes a field 'string_args_len[6]' which presents the string length if the corresponding argument is a string type. Now the map 'syscalls' is not used, bpf program doesn't use it as filter anymore, this is replaced by using the function bpf_tail_call() and PROG_ARRAY syscalls map. And we don't need to explicitly set the string length anymore, bpf_probe_read_str() is smart to copy the string and return string length. Therefore, it's safe to remove the bpf map 'syscalls'. To consolidate the code, this patch removes the definition of map 'syscalls' from augmented_raw_syscalls.c and drops code for using the map in the perf trace. Note, since function trace__set_ev_qualifier_bpf_filter() is removed, calling trace__init_syscall_bpf_progs() from it is also removed. We don't need to worry it because trace__init_syscall_bpf_progs() is still invoked from trace__init_syscalls_bpf_prog_array_maps() for initialization the system call's bpf program callback. After: # perf trace -e examples/bpf/augmented_raw_syscalls.c,open* --max-events 10 perf stat --quiet sleep 0.001 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libelf.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libdw.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libunwind.so.8", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libunwind-aarch64.so.8", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libcrypto.so.3", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libslang.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libperl.so.5.34", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 # perf trace -e examples/bpf/augmented_raw_syscalls.c --max-events 10 perf stat --quiet sleep 0.001 ... [continued]: execve()) = 0 brk(NULL) = 0xaaaab1d28000 faccessat(-100, "/etc/ld.so.preload", 4) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 close(3) = 0 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, 0xfffff33f70d0, 832) = 832 munmap(0xffffb5519000, 28672) = 0 munmap(0xffffb55b7000, 32880) = 0 mprotect(0xffffb55a6000, 61440, PROT_NONE) = 0 Signed-off-by: Leo Yan Tested-by: Arnaldo Carvalho de Melo Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221121075237.127706-6-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 101 ------------------ .../examples/bpf/augmented_raw_syscalls.c | 17 --- 2 files changed, 118 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 071e7598391f1..543c379d2a57a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -122,7 +122,6 @@ struct trace { struct syscalltbl *sctbl; struct { struct syscall *table; - struct bpf_map *map; struct { // per syscall BPF_MAP_TYPE_PROG_ARRAY struct bpf_map *sys_enter, *sys_exit; @@ -1224,16 +1223,6 @@ struct syscall { struct syscall_arg_fmt *arg_fmt; }; -/* - * Must match what is in the BPF program: - * - * tools/perf/examples/bpf/augmented_raw_syscalls.c - */ -struct bpf_map_syscall_entry { - bool enabled; - u16 string_args_len[RAW_SYSCALL_ARGS_NUM]; -}; - /* * We need to have this 'calculated' boolean because in some cases we really * don't know what is the duration of a syscall, for instance, when we start @@ -3259,7 +3248,6 @@ static void trace__set_bpf_map_filtered_pids(struct trace *trace) static void trace__set_bpf_map_syscalls(struct trace *trace) { - trace->syscalls.map = trace__find_bpf_map_by_name(trace, "syscalls"); trace->syscalls.prog_array.sys_enter = trace__find_bpf_map_by_name(trace, "syscalls_sys_enter"); trace->syscalls.prog_array.sys_exit = trace__find_bpf_map_by_name(trace, "syscalls_sys_exit"); } @@ -3339,80 +3327,6 @@ static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id) return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->syscalls.unaugmented_prog); } -static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) -{ - struct syscall *sc = trace__syscall_info(trace, NULL, id); - int arg = 0; - - if (sc == NULL) - goto out; - - for (; arg < sc->nr_args; ++arg) { - entry->string_args_len[arg] = 0; - if (sc->arg_fmt[arg].scnprintf == SCA_FILENAME) { - /* Should be set like strace -s strsize */ - entry->string_args_len[arg] = PATH_MAX; - } - } -out: - for (; arg < 6; ++arg) - entry->string_args_len[arg] = 0; -} -static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) -{ - int fd = bpf_map__fd(trace->syscalls.map); - struct bpf_map_syscall_entry value = { - .enabled = !trace->not_ev_qualifier, - }; - int err = 0; - size_t i; - - for (i = 0; i < trace->ev_qualifier_ids.nr; ++i) { - int key = trace->ev_qualifier_ids.entries[i]; - - if (value.enabled) { - trace__init_bpf_map_syscall_args(trace, key, &value); - trace__init_syscall_bpf_progs(trace, key); - } - - err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); - if (err) - break; - } - - return err; -} - -static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) -{ - int fd = bpf_map__fd(trace->syscalls.map); - struct bpf_map_syscall_entry value = { - .enabled = enabled, - }; - int err = 0, key; - - for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { - if (enabled) - trace__init_bpf_map_syscall_args(trace, key, &value); - - err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); - if (err) - break; - } - - return err; -} - -static int trace__init_syscalls_bpf_map(struct trace *trace) -{ - bool enabled = true; - - if (trace->ev_qualifier_ids.nr) - enabled = trace->not_ev_qualifier; - - return __trace__init_syscalls_bpf_map(trace, enabled); -} - static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace, struct syscall *sc) { struct tep_format_field *field, *candidate_field; @@ -3627,16 +3541,6 @@ static void trace__set_bpf_map_syscalls(struct trace *trace __maybe_unused) { } -static int trace__set_ev_qualifier_bpf_filter(struct trace *trace __maybe_unused) -{ - return 0; -} - -static int trace__init_syscalls_bpf_map(struct trace *trace __maybe_unused) -{ - return 0; -} - static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused, const char *name __maybe_unused) { @@ -3670,8 +3574,6 @@ static bool trace__only_augmented_syscalls_evsels(struct trace *trace) static int trace__set_ev_qualifier_filter(struct trace *trace) { - if (trace->syscalls.map) - return trace__set_ev_qualifier_bpf_filter(trace); if (trace->syscalls.events.sys_enter) return trace__set_ev_qualifier_tp_filter(trace); return 0; @@ -4045,9 +3947,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_mem; - if (trace->syscalls.map) - trace__init_syscalls_bpf_map(trace); - if (trace->syscalls.prog_array.sys_enter) trace__init_syscalls_bpf_prog_array_maps(trace); diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 4203f92c063bf..9a03189d33d38 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -37,23 +37,6 @@ struct __augmented_syscalls__ { __uint(max_entries, __NR_CPUS__); } __augmented_syscalls__ SEC(".maps"); -/* - * string_args_len: one per syscall arg, 0 means not a string or don't copy it, - * PATH_MAX for copying everything, any other value to limit - * it a la 'strace -s strsize'. - */ -struct syscall { - bool enabled; - __u16 string_args_len[6]; -}; - -struct syscalls { - __uint(type, BPF_MAP_TYPE_ARRAY); - __type(key, int); - __type(value, struct syscall); - __uint(max_entries, 512); -} syscalls SEC(".maps"); - /* * What to augment at entry? * -- GitLab From 7d54a4acd8c1de3ea70d31424757dcdb7f0a231a Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Mon, 21 Nov 2022 15:57:47 +0530 Subject: [PATCH 0690/1480] perf test: Skip watchpoint tests if no watchpoints available On IBM Power9, perf watchpoint tests fail since no hardware breakpoints are available. Detect this by checking the error returned by perf_event_open() and skip the tests in that case. Reported-by: Disha Goel Signed-off-by: Naveen N. Rao Acked-by: Ian Rogers Reviewed-by: Kajol Jain Tested-by: Kajol Jain Link: https://lore.kernel.org/r/20221121102747.208289-1-naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo Cc: Ravi Bangoria Cc: Arnaldo Carvalho de Melo Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Cc: linux-perf-users@vger.kernel.org --- tools/perf/tests/wp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 56455da30341b..cc8719609b19e 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -59,8 +59,10 @@ static int __event(int wp_type, void *wp_addr, unsigned long wp_len) get__perf_event_attr(&attr, wp_type, wp_addr, wp_len); fd = sys_perf_event_open(&attr, 0, -1, -1, perf_event_open_cloexec_flag()); - if (fd < 0) + if (fd < 0) { + fd = -errno; pr_debug("failed opening event %x\n", attr.bp_type); + } return fd; } @@ -77,7 +79,7 @@ static int test__wp_ro(struct test_suite *test __maybe_unused, fd = __event(HW_BREAKPOINT_R, (void *)&data1, sizeof(data1)); if (fd < 0) - return -1; + return fd == -ENODEV ? TEST_SKIP : -1; tmp = data1; WP_TEST_ASSERT_VAL(fd, "RO watchpoint", 1); @@ -101,7 +103,7 @@ static int test__wp_wo(struct test_suite *test __maybe_unused, fd = __event(HW_BREAKPOINT_W, (void *)&data1, sizeof(data1)); if (fd < 0) - return -1; + return fd == -ENODEV ? TEST_SKIP : -1; tmp = data1; WP_TEST_ASSERT_VAL(fd, "WO watchpoint", 0); @@ -126,7 +128,7 @@ static int test__wp_rw(struct test_suite *test __maybe_unused, fd = __event(HW_BREAKPOINT_R | HW_BREAKPOINT_W, (void *)&data1, sizeof(data1)); if (fd < 0) - return -1; + return fd == -ENODEV ? TEST_SKIP : -1; tmp = data1; WP_TEST_ASSERT_VAL(fd, "RW watchpoint", 1); @@ -150,7 +152,7 @@ static int test__wp_modify(struct test_suite *test __maybe_unused, int subtest _ fd = __event(HW_BREAKPOINT_W, (void *)&data1, sizeof(data1)); if (fd < 0) - return -1; + return fd == -ENODEV ? TEST_SKIP : -1; data1 = tmp; WP_TEST_ASSERT_VAL(fd, "Modify watchpoint", 1); -- GitLab From 19030564ab116757e3270a567fd9d5b20b411d74 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 18 Nov 2022 16:27:50 -0800 Subject: [PATCH 0691/1480] perf inject: Set PERF_RECORD_MISC_BUILD_ID_SIZE With perf inject -b, it synthesizes build-id event for DSOs. But it missed to set the size and resulted in having trailing zeros. As perf record sets the size in write_build_id(), let's set the size here as well. Signed-off-by: Namhyung Kim Acked-by: Adrian Hunter Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221119002750.1568027-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/synthetic-events.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index cccd293b53124..0645795ff0806 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2218,8 +2218,9 @@ int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 len = pos->long_name_len + 1; len = PERF_ALIGN(len, NAME_ALIGN); memcpy(&ev.build_id.build_id, pos->bid.data, sizeof(pos->bid.data)); + ev.build_id.size = pos->bid.size; ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; - ev.build_id.header.misc = misc; + ev.build_id.header.misc = misc | PERF_RECORD_MISC_BUILD_ID_SIZE; ev.build_id.pid = machine->pid; ev.build_id.header.size = sizeof(ev.build_id) + len; memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); -- GitLab From 2e9f5bda2f036aa38312fbeb99ff7e19c0221578 Mon Sep 17 00:00:00 2001 From: Michael Petlan Date: Tue, 22 Nov 2022 09:31:21 +0100 Subject: [PATCH 0692/1480] perf test: Fix record test on KVM guests Using precise flag with br_inst_retired.near_call causes the test fail on KVM guests, even when the guests have PMU forwarding enabled and the event itself is supported. Remove the precise flag in order to make the test work on KVM guests. Signed-off-by: Michael Petlan Acked-by: Ian Rogers Link: https://lore.kernel.org/r/20221122083121.6012-1-mpetlan@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 4dff89e3a3fd5..4fbc74805d526 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -83,7 +83,7 @@ test_register_capture() { echo "Register capture test [Skipped missing registers]" return fi - if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \ + if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call \ -c 1000 --per-thread ${testprog} 2> /dev/null \ | perf script -F ip,sym,iregs -i - 2> /dev/null \ | grep -q "DI:" -- GitLab From 7b7c22ccdf275018f715af95b7d052e8d4c6c690 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 21 Nov 2022 11:30:18 +0000 Subject: [PATCH 0693/1480] MAINTAINERS: Update John Garry's email address for arm64 perf tooling Update my address. Signed-off-by: John Garry Acked-by: Will Deacon Cc: Ian Rogers Link: https://lore.kernel.org/r/20221121113018.1899426-1-john.g.garry@oracle.com Signed-off-by: Arnaldo Carvalho de Melo --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2585e7edc3358..170f1763557a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16200,7 +16200,7 @@ F: tools/lib/perf/ F: tools/perf/ PERFORMANCE EVENTS TOOLING ARM64 -R: John Garry +R: John Garry R: Will Deacon R: James Clark R: Mike Leach -- GitLab From c66a36af7ba3a628453da1d91f42ee64fb36ea5a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 18 Nov 2022 11:01:09 -0800 Subject: [PATCH 0694/1480] perf lock contention: Do not use BPF task local storage It caused some troubles when a lock inside kmalloc is contended because task local storage would allocate memory using kmalloc. It'd create a recusion and even crash in my system. There could be a couple of workarounds but I think the simplest one is to use a pre-allocated hash map. We could fix the task local storage to use the safe BPF allocator, but it takes time so let's change this until it happens actually. Signed-off-by: Namhyung Kim Acked-by: Martin KaFai Lau Cc: Adrian Hunter Cc: Blake Jones Cc: Chris Li Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221118190109.1512674-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_lock_contention.c | 1 + .../perf/util/bpf_skel/lock_contention.bpf.c | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 0deec1178778e..4db9ad3d50c41 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -39,6 +39,7 @@ int lock_contention_prepare(struct lock_contention *con) bpf_map__set_value_size(skel->maps.stacks, con->max_stack * sizeof(u64)); bpf_map__set_max_entries(skel->maps.stacks, con->map_nr_entries); bpf_map__set_max_entries(skel->maps.lock_stat, con->map_nr_entries); + bpf_map__set_max_entries(skel->maps.tstamp, con->map_nr_entries); if (target__has_cpu(target)) ncpus = perf_cpu_map__nr(evlist->core.user_requested_cpus); diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c index 1bb8628e7c9f0..9681cb59b0df4 100644 --- a/tools/perf/util/bpf_skel/lock_contention.bpf.c +++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c @@ -40,10 +40,10 @@ struct { /* maintain timestamp at the beginning of contention */ struct { - __uint(type, BPF_MAP_TYPE_TASK_STORAGE); - __uint(map_flags, BPF_F_NO_PREALLOC); + __uint(type, BPF_MAP_TYPE_HASH); __type(key, int); __type(value, struct tstamp_data); + __uint(max_entries, MAX_ENTRIES); } tstamp SEC(".maps"); /* actual lock contention statistics */ @@ -103,18 +103,28 @@ static inline int can_record(void) SEC("tp_btf/contention_begin") int contention_begin(u64 *ctx) { - struct task_struct *curr; + __u32 pid; struct tstamp_data *pelem; if (!enabled || !can_record()) return 0; - curr = bpf_get_current_task_btf(); - pelem = bpf_task_storage_get(&tstamp, curr, NULL, - BPF_LOCAL_STORAGE_GET_F_CREATE); - if (!pelem || pelem->lock) + pid = bpf_get_current_pid_tgid(); + pelem = bpf_map_lookup_elem(&tstamp, &pid); + if (pelem && pelem->lock) return 0; + if (pelem == NULL) { + struct tstamp_data zero = {}; + + bpf_map_update_elem(&tstamp, &pid, &zero, BPF_ANY); + pelem = bpf_map_lookup_elem(&tstamp, &pid); + if (pelem == NULL) { + lost++; + return 0; + } + } + pelem->timestamp = bpf_ktime_get_ns(); pelem->lock = (__u64)ctx[0]; pelem->flags = (__u32)ctx[1]; @@ -128,7 +138,7 @@ int contention_begin(u64 *ctx) SEC("tp_btf/contention_end") int contention_end(u64 *ctx) { - struct task_struct *curr; + __u32 pid; struct tstamp_data *pelem; struct contention_key key; struct contention_data *data; @@ -137,8 +147,8 @@ int contention_end(u64 *ctx) if (!enabled) return 0; - curr = bpf_get_current_task_btf(); - pelem = bpf_task_storage_get(&tstamp, curr, NULL, 0); + pid = bpf_get_current_pid_tgid(); + pelem = bpf_map_lookup_elem(&tstamp, &pid); if (!pelem || pelem->lock != ctx[0]) return 0; @@ -156,7 +166,7 @@ int contention_end(u64 *ctx) }; bpf_map_update_elem(&lock_stat, &key, &first, BPF_NOEXIST); - pelem->lock = 0; + bpf_map_delete_elem(&tstamp, &pid); return 0; } @@ -169,7 +179,7 @@ int contention_end(u64 *ctx) if (data->min_time > duration) data->min_time = duration; - pelem->lock = 0; + bpf_map_delete_elem(&tstamp, &pid); return 0; } -- GitLab From 8749c27895a369a99e4a21709b3e3bec4785778f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 23 Sep 2022 22:39:13 +0800 Subject: [PATCH 0695/1480] habanalabs: fix return value check in hl_fw_get_sec_attest_data() If hl_cpu_accessible_dma_pool_alloc() fails, we should check 'req_cpu_addr', fix it. Fixes: 0c88760f8f5e ("habanalabs/gaudi2: add secured attestation info uapi") Signed-off-by: Yang Yingliang Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index 2de6a9bd564de..f18e53bbba6bb 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -2983,7 +2983,7 @@ static int hl_fw_get_sec_attest_data(struct hl_device *hdev, u32 packet_id, void int rc; req_cpu_addr = hl_cpu_accessible_dma_pool_alloc(hdev, size, &req_dma_addr); - if (!data) { + if (!req_cpu_addr) { dev_err(hdev->dev, "Failed to allocate DMA memory for CPU-CP packet %u\n", packet_id); return -ENOMEM; -- GitLab From a925d90b365aa38565191857bddc3c12d80fda96 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Tue, 23 Aug 2022 15:14:14 +0300 Subject: [PATCH 0696/1480] habanalabs: allow control device open during reset Monitoring apps would like to query device state at any time so we should allow it also during reset because it doesn't involve accessing the h/w. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 22 +++++++++++++++++++ drivers/misc/habanalabs/common/habanalabs.h | 2 ++ .../misc/habanalabs/common/habanalabs_drv.c | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 233d8b46c831f..1aaaa2004e345 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -355,6 +355,28 @@ bool hl_device_operational(struct hl_device *hdev, } } +bool hl_ctrl_device_operational(struct hl_device *hdev, + enum hl_device_status *status) +{ + enum hl_device_status current_status; + + current_status = hl_device_status(hdev); + if (status) + *status = current_status; + + switch (current_status) { + case HL_DEVICE_STATUS_MALFUNCTION: + return false; + case HL_DEVICE_STATUS_IN_RESET: + case HL_DEVICE_STATUS_IN_RESET_AFTER_DEVICE_RELEASE: + case HL_DEVICE_STATUS_NEEDS_RESET: + case HL_DEVICE_STATUS_OPERATIONAL: + case HL_DEVICE_STATUS_IN_DEVICE_CREATION: + default: + return true; + } +} + static void hpriv_release(struct kref *ref) { u64 idle_mask[HL_BUSY_ENGINES_MASK_EXT_SIZE] = {0}; diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 58c95b13be69a..2ffb8378f5657 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -3496,6 +3496,8 @@ int hl_device_open(struct inode *inode, struct file *filp); int hl_device_open_ctrl(struct inode *inode, struct file *filp); bool hl_device_operational(struct hl_device *hdev, enum hl_device_status *status); +bool hl_ctrl_device_operational(struct hl_device *hdev, + enum hl_device_status *status); enum hl_device_status hl_device_status(struct hl_device *hdev); int hl_device_set_debug_mode(struct hl_device *hdev, struct hl_ctx *ctx, bool enable); int hl_hw_queues_create(struct hl_device *hdev); diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index 112632afe7d53..3ee44ea58d5cc 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -270,9 +270,9 @@ int hl_device_open_ctrl(struct inode *inode, struct file *filp) mutex_lock(&hdev->fpriv_ctrl_list_lock); - if (!hl_device_operational(hdev, NULL)) { + if (!hl_ctrl_device_operational(hdev, NULL)) { dev_dbg_ratelimited(hdev->dev_ctrl, - "Can't open %s because it is disabled or in reset\n", + "Can't open %s because it is disabled\n", dev_name(hdev->dev_ctrl)); rc = -EPERM; goto out_err; -- GitLab From ea73ef14ddf93b8b1ae6ce1963846f43a81bb510 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 22 Sep 2022 12:30:32 +0300 Subject: [PATCH 0697/1480] habanalabs: Use simplified API for p2p dist calc Use the simplified API that calculates distance between two devices. Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index ef28f3b37b932..99b1d6ce26aef 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -1689,7 +1689,7 @@ static int hl_dmabuf_attach(struct dma_buf *dmabuf, hl_dmabuf = dmabuf->priv; hdev = hl_dmabuf->ctx->hdev; - rc = pci_p2pdma_distance_many(hdev->pdev, &attachment->dev, 1, true); + rc = pci_p2pdma_distance(hdev->pdev, attachment->dev, true); if (rc < 0) attachment->peer2peer = false; -- GitLab From 52d5e5469526216bcc418f26a2796d5af6226023 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Mon, 19 Sep 2022 18:51:59 +0300 Subject: [PATCH 0698/1480] habanalabs: refactor razwi event notification This event notification was compatible only with gaudi, where razwi and page fault happens together. To make it compatible with all ASICs, this refactor contains: 1. Razwi notification will only notify about razwi info. New notification will be added in future patch, to retrieve data about page fault error. 2. Changed razwi info structure to support all ASICs. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 22 +++++++ drivers/misc/habanalabs/common/habanalabs.h | 31 ++------- .../misc/habanalabs/common/habanalabs_drv.c | 2 +- .../misc/habanalabs/common/habanalabs_ioctl.c | 12 +--- drivers/misc/habanalabs/gaudi/gaudi.c | 64 +++++++++---------- include/uapi/misc/habanalabs.h | 45 ++++++++----- 6 files changed, 90 insertions(+), 86 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 1aaaa2004e345..30ddaaae67e51 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2253,3 +2253,25 @@ inline void hl_wreg(struct hl_device *hdev, u32 reg, u32 val) { writel(val, hdev->rmmio + reg); } + +void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, + u8 flags) +{ + if (num_of_engines > HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR) { + dev_err(hdev->dev, + "Number of possible razwi initiators (%u) exceeded limit (%u)\n", + num_of_engines, HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR); + return; + } + + /* In case it's the first razwi since the device was opened, capture its parameters */ + if (atomic_cmpxchg(&hdev->captured_err_info.razwi_info_recorded, 0, 1)) + return; + + hdev->captured_err_info.razwi.timestamp = ktime_to_ns(ktime_get()); + hdev->captured_err_info.razwi.addr = addr; + hdev->captured_err_info.razwi.num_of_possible_engines = num_of_engines; + memcpy(&hdev->captured_err_info.razwi.engine_id[0], &engine_id[0], + num_of_engines * sizeof(u16)); + hdev->captured_err_info.razwi.flags = flags; +} diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 2ffb8378f5657..cdc50c2c4de8a 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2925,30 +2925,6 @@ struct cs_timeout_info { u64 seq; }; -/** - * struct razwi_info - info about last razwi error occurred. - * @timestamp: razwi timestamp. - * @write_enable: if set writing to razwi parameters in the structure is enabled. - * otherwise - disabled, so the first (root cause) razwi will not be overwritten. - * @addr: address that caused razwi. - * @engine_id_1: engine id of the razwi initiator, if it was initiated by engine that does - * not have engine id it will be set to U16_MAX. - * @engine_id_2: second engine id of razwi initiator. Might happen that razwi have 2 possible - * engines which one them caused the razwi. In that case, it will contain the - * second possible engine id, otherwise it will be set to U16_MAX. - * @non_engine_initiator: in case the initiator of the razwi does not have engine id. - * @type: cause of razwi, page fault or access error, otherwise it will be set to U8_MAX. - */ -struct razwi_info { - ktime_t timestamp; - atomic_t write_enable; - u64 addr; - u16 engine_id_1; - u16 engine_id_2; - u8 non_engine_initiator; - u8 type; -}; - #define MAX_QMAN_STREAMS_INFO 4 #define OPCODE_INFO_MAX_ADDR_SIZE 8 /** @@ -2985,11 +2961,14 @@ struct undefined_opcode_info { * struct hl_error_info - holds information collected during an error. * @cs_timeout: CS timeout error information. * @razwi: razwi information. + * @razwi_info_recorded: if set writing to razwi information is enabled. + * otherwise - disabled, so the first (root cause) razwi will not be overwritten. * @undef_opcode: undefined opcode information */ struct hl_error_info { struct cs_timeout_info cs_timeout; - struct razwi_info razwi; + struct hl_info_razwi_event razwi; + atomic_t razwi_info_recorded; struct undefined_opcode_info undef_opcode; }; @@ -3800,6 +3779,8 @@ hl_mmap_mem_buf_alloc(struct hl_mem_mgr *mmg, struct hl_mmap_mem_buf_behavior *behavior, gfp_t gfp, void *args); __printf(2, 3) void hl_engine_data_sprintf(struct engines_data *e, const char *fmt, ...); +void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, + u8 flags); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index 3ee44ea58d5cc..d87434b9bc164 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -212,7 +212,7 @@ int hl_device_open(struct inode *inode, struct file *filp) hl_debugfs_add_file(hpriv); atomic_set(&hdev->captured_err_info.cs_timeout.write_enable, 1); - atomic_set(&hdev->captured_err_info.razwi.write_enable, 1); + atomic_set(&hdev->captured_err_info.razwi_info_recorded, 0); hdev->captured_err_info.undef_opcode.write_enable = true; hdev->open_counter++; diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 43afe40966e50..6aef4e24d122d 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -603,20 +603,14 @@ static int razwi_info(struct hl_fpriv *hpriv, struct hl_info_args *args) { struct hl_device *hdev = hpriv->hdev; u32 max_size = args->return_size; - struct hl_info_razwi_event info = {0}; + struct hl_info_razwi_event *info = &hdev->captured_err_info.razwi; void __user *out = (void __user *) (uintptr_t) args->return_pointer; if ((!max_size) || (!out)) return -EINVAL; - info.timestamp = ktime_to_ns(hdev->captured_err_info.razwi.timestamp); - info.addr = hdev->captured_err_info.razwi.addr; - info.engine_id_1 = hdev->captured_err_info.razwi.engine_id_1; - info.engine_id_2 = hdev->captured_err_info.razwi.engine_id_2; - info.no_engine_id = hdev->captured_err_info.razwi.non_engine_initiator; - info.error_type = hdev->captured_err_info.razwi.type; - - return copy_to_user(out, &info, min_t(size_t, max_size, sizeof(info))) ? -EFAULT : 0; + return copy_to_user(out, info, min_t(size_t, max_size, sizeof(struct hl_info_razwi_event))) + ? -EFAULT : 0; } static int undefined_opcode_info(struct hl_fpriv *hpriv, struct hl_info_args *args) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 92560414e8433..f856ac51fde1c 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -6505,8 +6505,8 @@ event_not_supported: } static const char *gaudi_get_razwi_initiator_dma_name(struct hl_device *hdev, u32 x_y, - bool is_write, s32 *engine_id_1, - s32 *engine_id_2) + bool is_write, u16 *engine_id_1, + u16 *engine_id_2) { u32 dma_id[2], dma_offset, err_cause[2], mask, i; @@ -6603,7 +6603,7 @@ unknown_initiator: } static const char *gaudi_get_razwi_initiator_name(struct hl_device *hdev, bool is_write, - u32 *engine_id_1, u32 *engine_id_2) + u16 *engine_id_1, u16 *engine_id_2) { u32 val, x_y, axi_id; @@ -6719,8 +6719,8 @@ static const char *gaudi_get_razwi_initiator_name(struct hl_device *hdev, bool i return "unknown initiator"; } -static void gaudi_print_and_get_razwi_info(struct hl_device *hdev, u32 *engine_id_1, - u32 *engine_id_2) +static void gaudi_print_and_get_razwi_info(struct hl_device *hdev, u16 *engine_id_1, + u16 *engine_id_2, bool *is_read, bool *is_write) { if (RREG32(mmMMU_UP_RAZWI_WRITE_VLD)) { @@ -6728,6 +6728,7 @@ static void gaudi_print_and_get_razwi_info(struct hl_device *hdev, u32 *engine_i "RAZWI event caused by illegal write of %s\n", gaudi_get_razwi_initiator_name(hdev, true, engine_id_1, engine_id_2)); WREG32(mmMMU_UP_RAZWI_WRITE_VLD, 0); + *is_write = true; } if (RREG32(mmMMU_UP_RAZWI_READ_VLD)) { @@ -6735,10 +6736,11 @@ static void gaudi_print_and_get_razwi_info(struct hl_device *hdev, u32 *engine_i "RAZWI event caused by illegal read of %s\n", gaudi_get_razwi_initiator_name(hdev, false, engine_id_1, engine_id_2)); WREG32(mmMMU_UP_RAZWI_READ_VLD, 0); + *is_read = true; } } -static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr, u8 *type) +static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr) { struct gaudi_device *gaudi = hdev->asic_specific; u32 val; @@ -6753,8 +6755,6 @@ static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr *addr |= RREG32(mmMMU_UP_PAGE_ERROR_CAPTURE_VA); dev_err_ratelimited(hdev->dev, "MMU page fault on va 0x%llx\n", *addr); - *type = HL_RAZWI_PAGE_FAULT; - WREG32(mmMMU_UP_PAGE_ERROR_CAPTURE, 0); } @@ -6765,7 +6765,6 @@ static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr *addr |= RREG32(mmMMU_UP_ACCESS_ERROR_CAPTURE_VA); dev_err_ratelimited(hdev->dev, "MMU access error on va 0x%llx\n", *addr); - *type = HL_RAZWI_MMU_ACCESS_ERROR; WREG32(mmMMU_UP_ACCESS_ERROR_CAPTURE, 0); } @@ -7302,46 +7301,41 @@ static void gaudi_handle_qman_err(struct hl_device *hdev, u16 event_type, u64 *e static void gaudi_print_irq_info(struct hl_device *hdev, u16 event_type, bool razwi) { - u32 engine_id_1, engine_id_2; + bool is_read = false, is_write = false; + u16 engine_id[2], num_of_razwi_eng = 0; char desc[64] = ""; u64 razwi_addr = 0; - u8 razwi_type; - int rc; + u8 razwi_flags = 0; /* * Init engine id by default as not valid and only if razwi initiated from engine with * engine id it will get valid value. - * Init razwi type to default, will be changed only if razwi caused by page fault of - * MMU access error */ - engine_id_1 = U16_MAX; - engine_id_2 = U16_MAX; - razwi_type = U8_MAX; + engine_id[0] = HL_RAZWI_NA_ENG_ID; + engine_id[1] = HL_RAZWI_NA_ENG_ID; gaudi_get_event_desc(event_type, desc, sizeof(desc)); dev_err_ratelimited(hdev->dev, "Received H/W interrupt %d [\"%s\"]\n", event_type, desc); if (razwi) { - gaudi_print_and_get_razwi_info(hdev, &engine_id_1, &engine_id_2); - gaudi_print_and_get_mmu_error_info(hdev, &razwi_addr, &razwi_type); - - /* In case it's the first razwi, save its parameters*/ - rc = atomic_cmpxchg(&hdev->captured_err_info.razwi.write_enable, 1, 0); - if (rc) { - hdev->captured_err_info.razwi.timestamp = ktime_get(); - hdev->captured_err_info.razwi.addr = razwi_addr; - hdev->captured_err_info.razwi.engine_id_1 = engine_id_1; - hdev->captured_err_info.razwi.engine_id_2 = engine_id_2; - /* - * If first engine id holds non valid value the razwi initiator - * does not have engine id - */ - hdev->captured_err_info.razwi.non_engine_initiator = - (engine_id_1 == U16_MAX); - hdev->captured_err_info.razwi.type = razwi_type; - + gaudi_print_and_get_razwi_info(hdev, &engine_id[0], &engine_id[1], &is_read, + &is_write); + gaudi_print_and_get_mmu_error_info(hdev, &razwi_addr); + + if (is_read) + razwi_flags |= HL_RAZWI_READ; + if (is_write) + razwi_flags |= HL_RAZWI_WRITE; + + if (engine_id[0] != HL_RAZWI_NA_ENG_ID) { + if (engine_id[1] != HL_RAZWI_NA_ENG_ID) + num_of_razwi_eng = 2; + else + num_of_razwi_eng = 1; } + + hl_capture_razwi(hdev, razwi_addr, engine_id, num_of_razwi_eng, razwi_flags); } } diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index e00ebe05097d7..d6f84cb35e3d8 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -1071,31 +1071,44 @@ struct hl_info_cs_timeout_event { __u64 seq; }; -#define HL_RAZWI_PAGE_FAULT 0 -#define HL_RAZWI_MMU_ACCESS_ERROR 1 +#define HL_RAZWI_NA_ENG_ID U16_MAX +#define HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR 128 +#define HL_RAZWI_READ BIT(0) +#define HL_RAZWI_WRITE BIT(1) +#define HL_RAZWI_LBW BIT(2) +#define HL_RAZWI_HBW BIT(3) +#define HL_RAZWI_RR BIT(4) +#define HL_RAZWI_ADDR_DEC BIT(5) /** * struct hl_info_razwi_event - razwi information. * @timestamp: timestamp of razwi. * @addr: address which accessing it caused razwi. - * @engine_id_1: engine id of the razwi initiator, if it was initiated by engine that does not - * have engine id it will be set to U16_MAX. - * @engine_id_2: second engine id of razwi initiator. Might happen that razwi have 2 possible - * engines which one them caused the razwi. In that case, it will contain the - * second possible engine id, otherwise it will be set to U16_MAX. - * @no_engine_id: if razwi initiator does not have engine id, this field will be set to 1, - * otherwise 0. - * @error_type: cause of razwi, page fault or access error, otherwise it will be set to U8_MAX. - * @pad: padding to 64 bit. + * @engine_id: engine id of the razwi initiator, if it was initiated by engine that does not + * have engine id it will be set to HL_RAZWI_NA_ENG_ID. If there are several possible + * engines which caused the razwi, it will hold all of them. + * @num_of_possible_engines: contains number of possible engine ids. In some asics, razwi indication + * might be common for several engines and there is no way to get the + * exact engine. In this way, engine_id array will be filled with all + * possible engines caused this razwi. Also, there might be possibility + * in gaudi, where we don't indication on specific engine, in that case + * the value of this parameter will be zero. + * @flags: bitmask for additional data: HL_RAZWI_READ - razwi caused by read operation + * HL_RAZWI_WRITE - razwi caused by write operation + * HL_RAZWI_LBW - razwi caused by lbw fabric transaction + * HL_RAZWI_HBW - razwi caused by hbw fabric transaction + * HL_RAZWI_RR - razwi caused by range register + * HL_RAZWI_ADDR_DEC - razwi caused by address decode error + * Note: this data is not supported by all asics, in that case the relevant bits will not + * be set. */ struct hl_info_razwi_event { __s64 timestamp; __u64 addr; - __u16 engine_id_1; - __u16 engine_id_2; - __u8 no_engine_id; - __u8 error_type; - __u8 pad[2]; + __u16 engine_id[HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR]; + __u16 num_of_possible_engines; + __u8 flags; + __u8 pad[5]; }; #define MAX_QMAN_STREAMS_INFO 4 -- GitLab From 0502df9bbea0bd0e77c4a283e4cc34801038899a Mon Sep 17 00:00:00 2001 From: Bharat Jauhari Date: Tue, 27 Sep 2022 14:38:38 +0300 Subject: [PATCH 0699/1480] habanalabs: use lower_32_bits() This fixes sparse warning on doing cast to 32-bits Signed-off-by: Bharat Jauhari Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index cdc50c2c4de8a..f4b3fa4b09767 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2528,7 +2528,7 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); break; \ (val) = __elbi_read; \ } else {\ - (val) = RREG32((u32)(addr)); \ + (val) = RREG32(lower_32_bits(addr)); \ } \ if (cond) \ break; \ @@ -2539,7 +2539,7 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); break; \ (val) = __elbi_read; \ } else {\ - (val) = RREG32((u32)(addr)); \ + (val) = RREG32(lower_32_bits(addr)); \ } \ break; \ } \ @@ -2594,7 +2594,7 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); if (__rc) \ break; \ } else { \ - __read_val = RREG32((u32)(addr_arr)[__arr_idx]); \ + __read_val = RREG32(lower_32_bits(addr_arr[__arr_idx])); \ } \ if (__read_val == (expected_val)) \ __elem_bitmask &= ~BIT_ULL(__arr_idx); \ -- GitLab From 6d1c567f2ac66391edf5423247f27c82f6b82d86 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 22 Sep 2022 15:25:46 +0300 Subject: [PATCH 0700/1480] habanalabs/gaudi2: fix module ID for RAZWI handling RAZWI is optionally handled as part of the generic QM SEI error handling, but it always uses PDMA as the module ID. Fix it to use the suitable module ID according to the specific event. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 65e6cae6100a4..b3685978f6aea 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -7602,6 +7602,7 @@ static void _gaudi2_handle_qm_sei_err(struct hl_device *hdev, u64 qman_base) static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, struct hl_eq_razwi_info *razwi_info) { + enum razwi_event_sources module; u64 qman_base; u8 index; @@ -7611,9 +7612,11 @@ static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, qman_base = mmDCORE0_TPC0_QM_BASE + (index / NUM_OF_TPC_PER_DCORE) * DCORE_OFFSET + (index % NUM_OF_TPC_PER_DCORE) * DCORE_TPC_OFFSET; + module = RAZWI_TPC; break; case GAUDI2_EVENT_TPC24_AXI_ERR_RSP: qman_base = mmDCORE0_TPC6_QM_BASE; + module = RAZWI_TPC; break; case GAUDI2_EVENT_MME0_CTRL_AXI_ERROR_RESPONSE: case GAUDI2_EVENT_MME1_CTRL_AXI_ERROR_RESPONSE: @@ -7623,16 +7626,19 @@ static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, (GAUDI2_EVENT_MME1_CTRL_AXI_ERROR_RESPONSE - GAUDI2_EVENT_MME0_CTRL_AXI_ERROR_RESPONSE); qman_base = mmDCORE0_MME_QM_BASE + index * DCORE_OFFSET; + module = RAZWI_MME; break; case GAUDI2_EVENT_PDMA_CH0_AXI_ERR_RSP: case GAUDI2_EVENT_PDMA_CH1_AXI_ERR_RSP: index = event_type - GAUDI2_EVENT_PDMA_CH0_AXI_ERR_RSP; qman_base = mmPDMA0_QM_BASE + index * PDMA_OFFSET; + module = RAZWI_PDMA; break; case GAUDI2_EVENT_ROTATOR0_AXI_ERROR_RESPONSE: case GAUDI2_EVENT_ROTATOR1_AXI_ERROR_RESPONSE: index = event_type - GAUDI2_EVENT_ROTATOR0_AXI_ERROR_RESPONSE; qman_base = mmROT0_QM_BASE + index * ROT_OFFSET; + module = RAZWI_ROT; break; default: return; @@ -7647,7 +7653,7 @@ static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, /* check if RAZWI happened */ if (razwi_info) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_PDMA, 0, 0, razwi_info); + gaudi2_ack_module_razwi_event_handler(hdev, module, 0, 0, razwi_info); } static void gaudi2_handle_qman_err(struct hl_device *hdev, u16 event_type) -- GitLab From dd600db47ba60c3c69d4d24c73c43133c6040118 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Sun, 18 Sep 2022 21:37:31 +0300 Subject: [PATCH 0701/1480] habanalabs: add page fault info uapi Only the first page fault will be saved. Besides the address which caused the page fault, the driver captures all of the mmu user mappings. User can retrieve this data via the new uapi (new opcode in INFO ioctl). Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 58 +++++++++++++++++++ drivers/misc/habanalabs/common/habanalabs.h | 22 ++++++- .../misc/habanalabs/common/habanalabs_drv.c | 1 + .../misc/habanalabs/common/habanalabs_ioctl.c | 42 ++++++++++++++ drivers/misc/habanalabs/gaudi/gaudi.c | 2 + include/uapi/misc/habanalabs.h | 31 ++++++++++ 6 files changed, 155 insertions(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 30ddaaae67e51..5dc6c77b47211 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -12,6 +12,7 @@ #include #include +#include #include @@ -2199,6 +2200,8 @@ void hl_device_fini(struct hl_device *hdev) hl_mmu_fini(hdev); + vfree(hdev->captured_err_info.pgf_info.user_mappings); + hl_eq_fini(hdev, &hdev->event_queue); kfree(hdev->shadow_cs_queue); @@ -2275,3 +2278,58 @@ void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_ num_of_engines * sizeof(u16)); hdev->captured_err_info.razwi.flags = flags; } +static void hl_capture_user_mappings(struct hl_device *hdev) +{ + struct page_fault_info *pgf_info = &hdev->captured_err_info.pgf_info; + struct hl_vm_hash_node *hnode; + struct hl_userptr *userptr; + struct hl_ctx *ctx; + u32 map_idx = 0; + int i; + + ctx = hl_get_compute_ctx(hdev); + if (!ctx) { + dev_err(hdev->dev, "Can't get user context for user mappings\n"); + return; + } + + mutex_lock(&ctx->mem_hash_lock); + hash_for_each(ctx->mem_hash, i, hnode, node) + pgf_info->num_of_user_mappings++; + + if (!pgf_info->num_of_user_mappings) + goto finish; + + /* In case we already allocated in previous session, need to release it before + * allocating new buffer. + */ + vfree(pgf_info->user_mappings); + pgf_info->user_mappings = + vmalloc(pgf_info->num_of_user_mappings * sizeof(struct hl_user_mapping)); + if (!pgf_info->user_mappings) { + pgf_info->num_of_user_mappings = 0; + goto finish; + } + + hash_for_each(ctx->mem_hash, i, hnode, node) { + userptr = hnode->ptr; + pgf_info->user_mappings[map_idx].dev_va = hnode->vaddr; + pgf_info->user_mappings[map_idx].size = userptr->size; + map_idx++; + } +finish: + mutex_unlock(&ctx->mem_hash_lock); + hl_ctx_put(ctx); +} + +void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu) +{ + /* Capture only the first page fault */ + if (atomic_cmpxchg(&hdev->captured_err_info.pgf_info_recorded, 0, 1)) + return; + + hdev->captured_err_info.pgf_info.pgf.timestamp = ktime_to_ns(ktime_get()); + hdev->captured_err_info.pgf_info.pgf.addr = addr; + hdev->captured_err_info.pgf_info.pgf.engine_id = eng_id; + hl_capture_user_mappings(hdev); +} diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index f4b3fa4b09767..1489240d5a3ad 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2957,19 +2957,38 @@ struct undefined_opcode_info { bool write_enable; }; +/** + * struct page_fault_info - info about page fault + * @pgf_info: page fault information. + * @user_mappings: buffer containing user mappings. + * @num_of_user_mappings: number of user mappings. + */ +struct page_fault_info { + struct hl_page_fault_info pgf; + struct hl_user_mapping *user_mappings; + u64 num_of_user_mappings; +}; + /** * struct hl_error_info - holds information collected during an error. * @cs_timeout: CS timeout error information. * @razwi: razwi information. * @razwi_info_recorded: if set writing to razwi information is enabled. - * otherwise - disabled, so the first (root cause) razwi will not be overwritten. + * otherwise - disabled, so the first (root cause) razwi will not be + * overwritten. * @undef_opcode: undefined opcode information + * @pgf_info: page fault information. + * @pgf_info_recorded: if set writing to page fault information is enabled. + * otherwise - disabled, so the first (root cause) page fault will not be + * overwritten. */ struct hl_error_info { struct cs_timeout_info cs_timeout; struct hl_info_razwi_event razwi; atomic_t razwi_info_recorded; struct undefined_opcode_info undef_opcode; + struct page_fault_info pgf_info; + atomic_t pgf_info_recorded; }; /** @@ -3781,6 +3800,7 @@ hl_mmap_mem_buf_alloc(struct hl_mem_mgr *mmg, __printf(2, 3) void hl_engine_data_sprintf(struct engines_data *e, const char *fmt, ...); void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, u8 flags); +void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index d87434b9bc164..714994725224f 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -213,6 +213,7 @@ int hl_device_open(struct inode *inode, struct file *filp) atomic_set(&hdev->captured_err_info.cs_timeout.write_enable, 1); atomic_set(&hdev->captured_err_info.razwi_info_recorded, 0); + atomic_set(&hdev->captured_err_info.pgf_info_recorded, 0); hdev->captured_err_info.undef_opcode.write_enable = true; hdev->open_counter++; diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 6aef4e24d122d..cac2c7fb14f1b 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -778,6 +778,42 @@ static int engine_status_info(struct hl_fpriv *hpriv, struct hl_info_args *args) return rc; } +static int page_fault_info(struct hl_fpriv *hpriv, struct hl_info_args *args) +{ + struct hl_device *hdev = hpriv->hdev; + u32 max_size = args->return_size; + struct hl_page_fault_info *info = &hdev->captured_err_info.pgf_info.pgf; + void __user *out = (void __user *) (uintptr_t) args->return_pointer; + + if ((!max_size) || (!out)) + return -EINVAL; + + return copy_to_user(out, info, min_t(size_t, max_size, sizeof(struct hl_page_fault_info))) + ? -EFAULT : 0; +} + +static int user_mappings_info(struct hl_fpriv *hpriv, struct hl_info_args *args) +{ + void __user *out = (void __user *) (uintptr_t) args->return_pointer; + u32 user_buf_size = args->return_size; + struct hl_device *hdev = hpriv->hdev; + struct page_fault_info *pgf_info; + u64 actual_size; + + pgf_info = &hdev->captured_err_info.pgf_info; + args->array_size = pgf_info->num_of_user_mappings; + + if (!out) + return -EINVAL; + + actual_size = pgf_info->num_of_user_mappings * sizeof(struct hl_user_mapping); + if (user_buf_size < actual_size) + return -ENOMEM; + + return copy_to_user(out, pgf_info->user_mappings, min_t(size_t, user_buf_size, actual_size)) + ? -EFAULT : 0; +} + static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, struct device *dev) { @@ -837,6 +873,12 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, case HL_INFO_GET_EVENTS: return events_info(hpriv, args); + case HL_INFO_PAGE_FAULT_EVENT: + return page_fault_info(hpriv, args); + + case HL_INFO_USER_MAPPINGS: + return user_mappings_info(hpriv, args); + default: break; } diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index f856ac51fde1c..1a99f7be8b609 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -6755,6 +6755,8 @@ static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr *addr |= RREG32(mmMMU_UP_PAGE_ERROR_CAPTURE_VA); dev_err_ratelimited(hdev->dev, "MMU page fault on va 0x%llx\n", *addr); + hl_capture_page_fault(hdev, *addr, 0, true); + WREG32(mmMMU_UP_PAGE_ERROR_CAPTURE, 0); } diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index d6f84cb35e3d8..2b794f54e2ed3 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -778,6 +778,9 @@ enum hl_server_type { * HL_INFO_UNREGISTER_EVENTFD - Unregister eventfd * HL_INFO_GET_EVENTS - Retrieve the last occurred events * HL_INFO_UNDEFINED_OPCODE_EVENT - Retrieve last undefined opcode error information. + * HL_INFO_ENGINE_STATUS - Retrieve the status of all the h/w engines in the asic. + * HL_INFO_PAGE_FAULT_EVENT - Retrieve parameters of captured page fault. + * HL_INFO_USER_MAPPINGS - Retrieve user mappings, captured after page fault event. */ #define HL_INFO_HW_IP_INFO 0 #define HL_INFO_HW_EVENTS 1 @@ -809,6 +812,8 @@ enum hl_server_type { #define HL_INFO_GET_EVENTS 30 #define HL_INFO_UNDEFINED_OPCODE_EVENT 31 #define HL_INFO_ENGINE_STATUS 32 +#define HL_INFO_PAGE_FAULT_EVENT 33 +#define HL_INFO_USER_MAPPINGS 34 #define HL_INFO_VERSION_MAX_LEN 128 #define HL_INFO_CARD_NAME_MAX_LEN 16 @@ -1187,6 +1192,29 @@ struct hl_info_sec_attest { __u8 pad0[2]; }; +/** + * struct hl_page_fault_info - page fault information. + * @timestamp: timestamp of page fault. + * @addr: address which accessing it caused page fault. + * @engine_id: engine id which caused the page fault, supported only in gaudi3. + */ +struct hl_page_fault_info { + __s64 timestamp; + __u64 addr; + __u16 engine_id; + __u8 pad[6]; +}; + +/** + * struct hl_user_mapping - user mapping information. + * @dev_va: device virtual address. + * @size: virtual address mapping size. + */ +struct hl_user_mapping { + __u64 dev_va; + __u64 size; +}; + enum gaudi_dcores { HL_GAUDI_WS_DCORE, HL_GAUDI_WN_DCORE, @@ -1213,6 +1241,8 @@ enum gaudi_dcores { * needed, hence updating this variable so user will know the exact amount * of bytes copied by the kernel to the buffer. * @sec_attest_nonce: Nonce number used for attestation report. + * @array_size: Number of array members copied to user buffer. + * Relevant for HL_INFO_USER_MAPPINGS info ioctl. * @pad: Padding to 64 bit. */ struct hl_info_args { @@ -1228,6 +1258,7 @@ struct hl_info_args { __u32 eventfd; __u32 user_buffer_actual_size; __u32 sec_attest_nonce; + __u32 array_size; }; __u32 pad; -- GitLab From 189b203ebbea181d678b4d8bf3547eb78c8ae44a Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Wed, 28 Sep 2022 11:38:00 +0300 Subject: [PATCH 0702/1480] habanalabs: replace 'pf' to 'prefetch' pf was an abbreviation for prefetch but because pf already stands for 'physical function', we decided to change it to 'prefetch'. Signed-off-by: Dafna Hirschfeld Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 14 ++++++------- drivers/misc/habanalabs/common/habanalabs.h | 8 ++++---- drivers/misc/habanalabs/common/mmu/mmu.c | 22 ++++++++++----------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 5dc6c77b47211..bf675cf39f717 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -783,8 +783,8 @@ static int device_early_init(struct hl_device *hdev) goto free_cs_cmplt_wq; } - hdev->pf_wq = alloc_workqueue("hl-prefetch", WQ_UNBOUND, 0); - if (!hdev->pf_wq) { + hdev->prefetch_wq = alloc_workqueue("hl-prefetch", WQ_UNBOUND, 0); + if (!hdev->prefetch_wq) { dev_err(hdev->dev, "Failed to allocate MMU prefetch workqueue\n"); rc = -ENOMEM; goto free_ts_free_wq; @@ -794,7 +794,7 @@ static int device_early_init(struct hl_device *hdev) GFP_KERNEL); if (!hdev->hl_chip_info) { rc = -ENOMEM; - goto free_pf_wq; + goto free_prefetch_wq; } rc = hl_mmu_if_set_funcs(hdev); @@ -833,8 +833,8 @@ free_cb_mgr: hl_mem_mgr_fini(&hdev->kernel_mem_mgr); free_chip_info: kfree(hdev->hl_chip_info); -free_pf_wq: - destroy_workqueue(hdev->pf_wq); +free_prefetch_wq: + destroy_workqueue(hdev->prefetch_wq); free_ts_free_wq: destroy_workqueue(hdev->ts_free_obj_wq); free_cs_cmplt_wq: @@ -877,7 +877,7 @@ static void device_early_fini(struct hl_device *hdev) kfree(hdev->hl_chip_info); - destroy_workqueue(hdev->pf_wq); + destroy_workqueue(hdev->prefetch_wq); destroy_workqueue(hdev->ts_free_obj_wq); destroy_workqueue(hdev->cs_cmplt_wq); destroy_workqueue(hdev->eq_wq); @@ -1076,7 +1076,7 @@ static void cleanup_resources(struct hl_device *hdev, bool hard_reset, bool fw_r hl_cs_rollback_all(hdev, skip_wq_flush); /* flush the MMU prefetch workqueue */ - flush_workqueue(hdev->pf_wq); + flush_workqueue(hdev->prefetch_wq); /* Release all pending user interrupts, each pending user interrupt * holds a reference to user context diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 1489240d5a3ad..6d8ce4a1dbb15 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2811,7 +2811,7 @@ struct hl_mmu_funcs { /** * struct hl_prefetch_work - prefetch work structure handler - * @pf_work: actual work struct. + * @prefetch_work: actual work struct. * @ctx: compute context. * @va: virtual address to pre-fetch. * @size: pre-fetch size. @@ -2819,7 +2819,7 @@ struct hl_mmu_funcs { * @asid: ASID for maintenance operation. */ struct hl_prefetch_work { - struct work_struct pf_work; + struct work_struct prefetch_work; struct hl_ctx *ctx; u64 va; u64 size; @@ -3060,7 +3060,7 @@ struct hl_reset_info { * @cs_cmplt_wq: work queue of CS completions for executing work in process * context. * @ts_free_obj_wq: work queue for timestamp registration objects release. - * @pf_wq: work queue for MMU pre-fetch operations. + * @prefetch_wq: work queue for MMU pre-fetch operations. * @kernel_ctx: Kernel driver context structure. * @kernel_queues: array of hl_hw_queue. * @cs_mirror_list: CS mirror list for TDR. @@ -3231,7 +3231,7 @@ struct hl_device { struct workqueue_struct *eq_wq; struct workqueue_struct *cs_cmplt_wq; struct workqueue_struct *ts_free_obj_wq; - struct workqueue_struct *pf_wq; + struct workqueue_struct *prefetch_wq; struct hl_ctx *kernel_ctx; struct hl_hw_queue *kernel_queues; struct list_head cs_mirror_list; diff --git a/drivers/misc/habanalabs/common/mmu/mmu.c b/drivers/misc/habanalabs/common/mmu/mmu.c index cf8946266615c..589179f8cd41b 100644 --- a/drivers/misc/habanalabs/common/mmu/mmu.c +++ b/drivers/misc/habanalabs/common/mmu/mmu.c @@ -699,7 +699,7 @@ int hl_mmu_invalidate_cache_range(struct hl_device *hdev, bool is_hard, static void hl_mmu_prefetch_work_function(struct work_struct *work) { - struct hl_prefetch_work *pfw = container_of(work, struct hl_prefetch_work, pf_work); + struct hl_prefetch_work *pfw = container_of(work, struct hl_prefetch_work, prefetch_work); struct hl_ctx *ctx = pfw->ctx; struct hl_device *hdev = ctx->hdev; @@ -723,25 +723,25 @@ put_ctx: int hl_mmu_prefetch_cache_range(struct hl_ctx *ctx, u32 flags, u32 asid, u64 va, u64 size) { - struct hl_prefetch_work *handle_pf_work; + struct hl_prefetch_work *handle_prefetch_work; - handle_pf_work = kmalloc(sizeof(*handle_pf_work), GFP_KERNEL); - if (!handle_pf_work) + handle_prefetch_work = kmalloc(sizeof(*handle_prefetch_work), GFP_KERNEL); + if (!handle_prefetch_work) return -ENOMEM; - INIT_WORK(&handle_pf_work->pf_work, hl_mmu_prefetch_work_function); - handle_pf_work->ctx = ctx; - handle_pf_work->va = va; - handle_pf_work->size = size; - handle_pf_work->flags = flags; - handle_pf_work->asid = asid; + INIT_WORK(&handle_prefetch_work->prefetch_work, hl_mmu_prefetch_work_function); + handle_prefetch_work->ctx = ctx; + handle_prefetch_work->va = va; + handle_prefetch_work->size = size; + handle_prefetch_work->flags = flags; + handle_prefetch_work->asid = asid; /* * as actual prefetch is done in a WQ we must get the context (and put it * at the end of the work function) */ hl_ctx_get(ctx); - queue_work(ctx->hdev->pf_wq, &handle_pf_work->pf_work); + queue_work(ctx->hdev->prefetch_wq, &handle_prefetch_work->prefetch_work); return 0; } -- GitLab From 16448d644404351e685466ab14e7e043ad67673c Mon Sep 17 00:00:00 2001 From: Koby Elbaz Date: Wed, 28 Sep 2022 15:56:13 +0300 Subject: [PATCH 0703/1480] habanalabs/gaudi2: remove privileged MME clock configuration Privileged MME clock configuration is removed as it is done by the f/w. Signed-off-by: Koby Elbaz Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index b3685978f6aea..cb048920ffc8a 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -4535,7 +4535,7 @@ static void gaudi2_init_mme_acc(struct hl_device *hdev, u32 reg_base) static void gaudi2_init_dcore_mme(struct hl_device *hdev, int dcore_id, bool config_qman_only) { - u32 queue_id_base, reg_base, clk_en_addr = 0; + u32 queue_id_base, reg_base; switch (dcore_id) { case 0: @@ -4543,23 +4543,18 @@ static void gaudi2_init_dcore_mme(struct hl_device *hdev, int dcore_id, break; case 1: queue_id_base = GAUDI2_QUEUE_ID_DCORE1_MME_0_0; - clk_en_addr = mmDCORE1_MME_CTRL_LO_QM_SLV_CLK_EN; break; case 2: queue_id_base = GAUDI2_QUEUE_ID_DCORE2_MME_0_0; break; case 3: queue_id_base = GAUDI2_QUEUE_ID_DCORE3_MME_0_0; - clk_en_addr = mmDCORE3_MME_CTRL_LO_QM_SLV_CLK_EN; break; default: dev_err(hdev->dev, "Invalid dcore id %u\n", dcore_id); return; } - if (clk_en_addr && !(hdev->fw_components & FW_TYPE_BOOT_CPU)) - WREG32(clk_en_addr, 0x1); - if (!config_qman_only) { reg_base = gaudi2_mme_acc_blocks_bases[dcore_id]; gaudi2_init_mme_acc(hdev, reg_base); -- GitLab From 5731b6e6f08a4a3adf944fd0436f77f3e9ce1725 Mon Sep 17 00:00:00 2001 From: Tal Cohen Date: Wed, 28 Sep 2022 18:33:19 +0300 Subject: [PATCH 0704/1480] habanalabs/gaudi2: add device unavailable notification Device unavailable notifies the user that there isn't an option to retrieve debug information from the device. When a critical device error occurs and the f/w performs the device reset, a device unavailable notification shall be sent to the user process. Signed-off-by: Tal Cohen Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index cb048920ffc8a..e9c4ec429baee 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8576,7 +8576,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent { u32 ctl, reset_flags = HL_DRV_RESET_HARD | HL_DRV_RESET_DELAY; struct gaudi2_device *gaudi2 = hdev->asic_specific; - bool reset_required = false, skip_reset = false; + bool reset_required = false, skip_reset = false, is_critical = false; int index, sbte_index; u64 event_mask = 0; u16 event_type; @@ -8602,6 +8602,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent reset_flags |= HL_DRV_RESET_FW_FATAL_ERR; event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; reset_required = gaudi2_handle_ecc_event(hdev, event_type, &eq_entry->ecc_data); + is_critical = eq_entry->ecc_data.is_critical; break; case GAUDI2_EVENT_TPC0_QM ... GAUDI2_EVENT_PDMA1_QM: @@ -8976,9 +8977,16 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent return; reset_device: - if (hdev->hard_reset_on_fw_events) { + if (hdev->asic_prop.fw_security_enabled && is_critical) { + reset_flags = HL_DRV_RESET_HARD | HL_DRV_RESET_BYPASS_REQ_TO_FW; + + /* notify on device unavailable while the reset triggered by fw */ + event_mask |= (HL_NOTIFIER_EVENT_DEVICE_RESET | + HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE); hl_device_reset(hdev, reset_flags); + } else if (hdev->hard_reset_on_fw_events) { event_mask |= HL_NOTIFIER_EVENT_DEVICE_RESET; + hl_device_reset(hdev, reset_flags); } else { if (!gaudi2_irq_map_table[event_type].msg) hl_fw_unmask_irq(hdev, event_type); -- GitLab From 3a83ebc521b2e57af070b5667c60ac2d50347658 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 14:09:32 +0300 Subject: [PATCH 0705/1480] habanalabs: skip idle status check if reset on device release If reset upon device release is enabled, there is no need to check the device idle status in hpriv_release(), because device is going to be reset in any case. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index bf675cf39f717..e60ed0c8a9db4 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -398,16 +398,14 @@ static void hpriv_release(struct kref *ref) mutex_destroy(&hpriv->ctx_lock); mutex_destroy(&hpriv->restore_phase_mutex); - if ((!hdev->pldm) && (hdev->pdev) && - (!hdev->asic_funcs->is_device_idle(hdev, - idle_mask, - HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL))) { - dev_err(hdev->dev, - "device not idle after user context is closed (0x%llx_%llx)\n", - idle_mask[1], idle_mask[0]); + /* No need for idle status check if device is going to be reset in any case */ + if (!hdev->reset_upon_device_release && hdev->pdev && !hdev->pldm) + device_is_idle = hdev->asic_funcs->is_device_idle(hdev, idle_mask, + HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL); - device_is_idle = false; - } + if (!device_is_idle) + dev_err(hdev->dev, "device not idle after user context is closed (0x%llx_%llx)\n", + idle_mask[1], idle_mask[0]); /* We need to remove the user from the list to make sure the reset process won't * try to kill the user process. Because, if we got here, it means there are no -- GitLab From 51236cd95e7bcea41e57fb2cf238312be21dcf58 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 14:19:21 +0300 Subject: [PATCH 0706/1480] habanalabs: allow unregistering eventfd when device non-operational Unregistering eventfd is for releasing host resources and doesn't involve an access to the device. As such, there is no reason to disallow it when device isn't operational. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs_ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index cac2c7fb14f1b..5ce5c42e27313 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -879,6 +879,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, case HL_INFO_USER_MAPPINGS: return user_mappings_info(hpriv, args); + case HL_INFO_UNREGISTER_EVENTFD: + return eventfd_unregister(hpriv, args); + default: break; } @@ -935,9 +938,6 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, case HL_INFO_REGISTER_EVENTFD: return eventfd_register(hpriv, args); - case HL_INFO_UNREGISTER_EVENTFD: - return eventfd_unregister(hpriv, args); - case HL_INFO_ENGINE_STATUS: return engine_status_info(hpriv, args); -- GitLab From 1eebb259290b1be5398fec953bdd7923a5cbf33e Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 14:36:27 +0300 Subject: [PATCH 0707/1480] habanalabs: move reset workqueue to be under hl_device 'struct hl_device_reset_work' is used as a wrapper for the reset work and its parameters, including the reset workqueue on which it runs. In a future commit, another reset related work with similar parameters is going to be added, but it won't use the reset workqueue. As in any case there is a single reset workqueue, and to allow the resue of this structure, move the reset workqueue to 'struct hl_device'. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 15 ++++++--------- drivers/misc/habanalabs/common/habanalabs.h | 12 ++++++------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index e60ed0c8a9db4..e9b373a8cdade 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -684,9 +684,8 @@ static void device_hard_reset_pending(struct work_struct *work) "Could not reset device. will try again in %u seconds", HL_PENDING_RESET_PER_SEC); - queue_delayed_work(device_reset_work->wq, - &device_reset_work->reset_work, - msecs_to_jiffies(HL_PENDING_RESET_PER_SEC * 1000)); + queue_delayed_work(hdev->reset_wq, &device_reset_work->reset_work, + msecs_to_jiffies(HL_PENDING_RESET_PER_SEC * 1000)); } } @@ -801,9 +800,8 @@ static int device_early_init(struct hl_device *hdev) hl_mem_mgr_init(hdev->dev, &hdev->kernel_mem_mgr); - hdev->device_reset_work.wq = - create_singlethread_workqueue("hl_device_reset"); - if (!hdev->device_reset_work.wq) { + hdev->reset_wq = create_singlethread_workqueue("hl_device_reset"); + if (!hdev->reset_wq) { rc = -ENOMEM; dev_err(hdev->dev, "Failed to create device reset WQ\n"); goto free_cb_mgr; @@ -879,7 +877,7 @@ static void device_early_fini(struct hl_device *hdev) destroy_workqueue(hdev->ts_free_obj_wq); destroy_workqueue(hdev->cs_cmplt_wq); destroy_workqueue(hdev->eq_wq); - destroy_workqueue(hdev->device_reset_work.wq); + destroy_workqueue(hdev->reset_wq); for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) destroy_workqueue(hdev->cq_wq[i]); @@ -1460,8 +1458,7 @@ again: * Because the reset function can't run from heartbeat work, * we need to call the reset function from a dedicated work. */ - queue_delayed_work(hdev->device_reset_work.wq, - &hdev->device_reset_work.reset_work, 0); + queue_delayed_work(hdev->reset_wq, &hdev->device_reset_work.reset_work, 0); return 0; } diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 6d8ce4a1dbb15..4913197c433e6 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2682,17 +2682,15 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); struct hwmon_chip_info; /** - * struct hl_device_reset_work - reset workqueue task wrapper. - * @wq: work queue for device reset procedure. + * struct hl_device_reset_work - reset work wrapper. * @reset_work: reset work to be done. * @hdev: habanalabs device structure. * @flags: reset flags. */ struct hl_device_reset_work { - struct workqueue_struct *wq; - struct delayed_work reset_work; - struct hl_device *hdev; - u32 flags; + struct delayed_work reset_work; + struct hl_device *hdev; + u32 flags; }; /** @@ -3061,6 +3059,7 @@ struct hl_reset_info { * context. * @ts_free_obj_wq: work queue for timestamp registration objects release. * @prefetch_wq: work queue for MMU pre-fetch operations. + * @reset_wq: work queue for device reset procedure. * @kernel_ctx: Kernel driver context structure. * @kernel_queues: array of hl_hw_queue. * @cs_mirror_list: CS mirror list for TDR. @@ -3232,6 +3231,7 @@ struct hl_device { struct workqueue_struct *cs_cmplt_wq; struct workqueue_struct *ts_free_obj_wq; struct workqueue_struct *prefetch_wq; + struct workqueue_struct *reset_wq; struct hl_ctx *kernel_ctx; struct hl_hw_queue *kernel_queues; struct list_head cs_mirror_list; -- GitLab From 17f3f42af2bcddc38ff08b355e007f3b6d5ce70c Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Thu, 29 Sep 2022 10:21:28 +0300 Subject: [PATCH 0708/1480] habanalabs: handle HBM MMU when capturing page fault data In case of HBM MMU page fault, capture its relevant mappings. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 29 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index e9b373a8cdade..b8b32285720de 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2273,15 +2273,20 @@ void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_ num_of_engines * sizeof(u16)); hdev->captured_err_info.razwi.flags = flags; } -static void hl_capture_user_mappings(struct hl_device *hdev) +static void hl_capture_user_mappings(struct hl_device *hdev, bool is_pmmu) { struct page_fault_info *pgf_info = &hdev->captured_err_info.pgf_info; + struct hl_vm_phys_pg_pack *phys_pg_pack = NULL; struct hl_vm_hash_node *hnode; struct hl_userptr *userptr; + enum vm_type *vm_type; struct hl_ctx *ctx; u32 map_idx = 0; int i; + /* Reset previous session count*/ + pgf_info->num_of_user_mappings = 0; + ctx = hl_get_compute_ctx(hdev); if (!ctx) { dev_err(hdev->dev, "Can't get user context for user mappings\n"); @@ -2290,7 +2295,7 @@ static void hl_capture_user_mappings(struct hl_device *hdev) mutex_lock(&ctx->mem_hash_lock); hash_for_each(ctx->mem_hash, i, hnode, node) - pgf_info->num_of_user_mappings++; + pgf_info->num_of_user_mappings++; if (!pgf_info->num_of_user_mappings) goto finish; @@ -2300,17 +2305,25 @@ static void hl_capture_user_mappings(struct hl_device *hdev) */ vfree(pgf_info->user_mappings); pgf_info->user_mappings = - vmalloc(pgf_info->num_of_user_mappings * sizeof(struct hl_user_mapping)); + vzalloc(pgf_info->num_of_user_mappings * sizeof(struct hl_user_mapping)); if (!pgf_info->user_mappings) { pgf_info->num_of_user_mappings = 0; goto finish; } hash_for_each(ctx->mem_hash, i, hnode, node) { - userptr = hnode->ptr; - pgf_info->user_mappings[map_idx].dev_va = hnode->vaddr; - pgf_info->user_mappings[map_idx].size = userptr->size; - map_idx++; + vm_type = hnode->ptr; + if ((*vm_type == VM_TYPE_USERPTR) && (is_pmmu)) { + userptr = hnode->ptr; + pgf_info->user_mappings[map_idx].dev_va = hnode->vaddr; + pgf_info->user_mappings[map_idx].size = userptr->size; + map_idx++; + } else if ((*vm_type == VM_TYPE_PHYS_PACK) && (!is_pmmu)) { + phys_pg_pack = hnode->ptr; + pgf_info->user_mappings[map_idx].dev_va = hnode->vaddr; + pgf_info->user_mappings[map_idx].size = phys_pg_pack->total_size; + map_idx++; + } } finish: mutex_unlock(&ctx->mem_hash_lock); @@ -2326,5 +2339,5 @@ void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is hdev->captured_err_info.pgf_info.pgf.timestamp = ktime_to_ns(ktime_get()); hdev->captured_err_info.pgf_info.pgf.addr = addr; hdev->captured_err_info.pgf_info.pgf.engine_id = eng_id; - hl_capture_user_mappings(hdev); + hl_capture_user_mappings(hdev, is_pmmu); } -- GitLab From 15ac503cdc0d9a1275d82a926c673359cf69ebef Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Wed, 28 Sep 2022 22:14:55 +0300 Subject: [PATCH 0709/1480] habanalabs/gaudi2: capture RAZWI information Added function to calculate possible engines which caused RAZWI (read-only zero, write ignored), from a given router id or module index. When getting RAZWI via PSOC IP, first the router id is calculated and then the possible engines that caused the RAZWI are calculated. There is a possibility that the RAZWI initiator is not an engine. In that case, it will not be included in possible engines as it doesn't have an engine id. RAZWI information is captured when receiving event from engine or via PSOC IP. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 255 ++++++++++++++++++++++-- include/uapi/misc/habanalabs.h | 4 + 2 files changed, 242 insertions(+), 17 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index e9c4ec429baee..1058c8a0e644a 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -128,6 +128,8 @@ #define GAUDI2_VDEC_MSIX_ENTRIES (GAUDI2_IRQ_NUM_SHARED_DEC1_ABNRM - \ GAUDI2_IRQ_NUM_DCORE0_DEC0_NRM + 1) +#define ENGINE_ID_DCORE_OFFSET (GAUDI2_DCORE1_ENGINE_ID_EDMA_0 - GAUDI2_DCORE0_ENGINE_ID_EDMA_0) + enum hl_pmmu_fatal_cause { LATENCY_RD_OUT_FIFO_OVERRUN, LATENCY_WR_OUT_FIFO_OVERRUN, @@ -7092,9 +7094,12 @@ static void gaudi2_handle_qman_err_generic(struct hl_device *hdev, const char *q static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, u64 rtr_mstr_if_base_addr, bool is_write, char *name, - bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info) + bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info, + enum gaudi2_engine_id id) { u32 razwi_hi, razwi_lo, razwi_xy; + u16 eng_id = id; + u8 rd_wr_flag; if (is_write) { if (read_razwi_regs) { @@ -7106,6 +7111,7 @@ static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, razwi_lo = le32_to_cpu(razwi_info->hbw.rr_aw_razwi_lo_reg); razwi_xy = le32_to_cpu(razwi_info->hbw.rr_aw_razwi_id_reg); } + rd_wr_flag = HL_RAZWI_WRITE; } else { if (read_razwi_regs) { razwi_hi = RREG32(rtr_mstr_if_base_addr + RR_SHRD_HBW_AR_RAZWI_HI); @@ -7116,8 +7122,12 @@ static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, razwi_lo = le32_to_cpu(razwi_info->hbw.rr_ar_razwi_lo_reg); razwi_xy = le32_to_cpu(razwi_info->hbw.rr_ar_razwi_id_reg); } + rd_wr_flag = HL_RAZWI_READ; } + hl_capture_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &eng_id, 1, + rd_wr_flag | HL_RAZWI_HBW); + dev_err_ratelimited(hdev->dev, "%s-RAZWI SHARED RR HBW %s error, address %#llx, Initiator coordinates 0x%x\n", name, is_write ? "WR" : "RD", (u64)razwi_hi << 32 | razwi_lo, razwi_xy); @@ -7125,9 +7135,12 @@ static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, static void gaudi2_razwi_rr_lbw_shared_printf_info(struct hl_device *hdev, u64 rtr_mstr_if_base_addr, bool is_write, char *name, - bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info) + bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info, + enum gaudi2_engine_id id) { u32 razwi_addr, razwi_xy; + u16 eng_id = id; + u8 rd_wr_flag; if (is_write) { if (read_razwi_regs) { @@ -7138,9 +7151,7 @@ static void gaudi2_razwi_rr_lbw_shared_printf_info(struct hl_device *hdev, razwi_xy = le32_to_cpu(razwi_info->lbw.rr_aw_razwi_id_reg); } - dev_err_ratelimited(hdev->dev, - "%s-RAZWI SHARED RR LBW WR error, mstr_if 0x%llx, captured address 0x%x, Initiator coordinates 0x%x\n", - name, rtr_mstr_if_base_addr, razwi_addr, razwi_xy); + rd_wr_flag = HL_RAZWI_WRITE; } else { if (read_razwi_regs) { razwi_addr = RREG32(rtr_mstr_if_base_addr + RR_SHRD_LBW_AR_RAZWI); @@ -7150,9 +7161,57 @@ static void gaudi2_razwi_rr_lbw_shared_printf_info(struct hl_device *hdev, razwi_xy = le32_to_cpu(razwi_info->lbw.rr_ar_razwi_id_reg); } - dev_err_ratelimited(hdev->dev, - "%s-RAZWI SHARED RR LBW AR error, mstr_if 0x%llx, captured address 0x%x Initiator coordinates 0x%x\n", - name, rtr_mstr_if_base_addr, razwi_addr, razwi_xy); + rd_wr_flag = HL_RAZWI_READ; + } + + hl_capture_razwi(hdev, razwi_addr, &eng_id, 1, rd_wr_flag | HL_RAZWI_LBW); + dev_err_ratelimited(hdev->dev, + "%s-RAZWI SHARED RR LBW %s error, mstr_if 0x%llx, captured address 0x%x Initiator coordinates 0x%x\n", + name, is_write ? "WR" : "RD", rtr_mstr_if_base_addr, razwi_addr, + razwi_xy); +} + +static enum gaudi2_engine_id gaudi2_razwi_calc_engine_id(struct hl_device *hdev, + enum razwi_event_sources module, u8 module_idx) +{ + switch (module) { + case RAZWI_TPC: + if (module_idx == (NUM_OF_TPC_PER_DCORE * NUM_OF_DCORES)) + return GAUDI2_DCORE0_ENGINE_ID_TPC_6; + return (((module_idx / NUM_OF_TPC_PER_DCORE) * ENGINE_ID_DCORE_OFFSET) + + (module_idx % NUM_OF_TPC_PER_DCORE) + + (GAUDI2_DCORE0_ENGINE_ID_TPC_0 - GAUDI2_DCORE0_ENGINE_ID_EDMA_0)); + + case RAZWI_MME: + return ((GAUDI2_DCORE0_ENGINE_ID_MME - GAUDI2_DCORE0_ENGINE_ID_EDMA_0) + + (module_idx * ENGINE_ID_DCORE_OFFSET)); + + case RAZWI_EDMA: + return (((module_idx / NUM_OF_EDMA_PER_DCORE) * ENGINE_ID_DCORE_OFFSET) + + (module_idx % NUM_OF_EDMA_PER_DCORE)); + + case RAZWI_PDMA: + return (GAUDI2_ENGINE_ID_PDMA_0 + module_idx); + + case RAZWI_NIC: + return (GAUDI2_ENGINE_ID_NIC0_0 + (NIC_NUMBER_OF_QM_PER_MACRO * module_idx)); + + case RAZWI_DEC: + if (module_idx == 8) + return GAUDI2_PCIE_ENGINE_ID_DEC_0; + + if (module_idx == 9) + return GAUDI2_PCIE_ENGINE_ID_DEC_1; + ; + return (((module_idx / NUM_OF_DEC_PER_DCORE) * ENGINE_ID_DCORE_OFFSET) + + (module_idx % NUM_OF_DEC_PER_DCORE) + + (GAUDI2_DCORE0_ENGINE_ID_DEC_0 - GAUDI2_DCORE0_ENGINE_ID_EDMA_0)); + + case RAZWI_ROT: + return GAUDI2_ENGINE_ID_ROT_0 + module_idx; + + default: + return GAUDI2_ENGINE_ID_SIZE; } } @@ -7165,7 +7224,7 @@ static void gaudi2_ack_module_razwi_event_handler(struct hl_device *hdev, u8 module_sub_idx, struct hl_eq_razwi_info *razwi_info) { bool via_sft = false, read_razwi_regs = false; - u32 rtr_id, dcore_id, dcore_rtr_id, sft_id; + u32 rtr_id, dcore_id, dcore_rtr_id, sft_id, eng_id; u64 rtr_mstr_if_base_addr; u32 hbw_shrd_aw = 0, hbw_shrd_ar = 0; u32 lbw_shrd_aw = 0, lbw_shrd_ar = 0; @@ -7299,9 +7358,11 @@ dump_info: if (!hbw_shrd_aw && !hbw_shrd_ar && !lbw_shrd_aw && !lbw_shrd_ar) return; + eng_id = gaudi2_razwi_calc_engine_id(hdev, module, module_idx); if (hbw_shrd_aw) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, true, - initiator_name, read_razwi_regs, razwi_info); + initiator_name, read_razwi_regs, razwi_info, + eng_id); /* Clear event indication */ if (read_razwi_regs) @@ -7310,7 +7371,8 @@ dump_info: if (hbw_shrd_ar) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, false, - initiator_name, read_razwi_regs, razwi_info); + initiator_name, read_razwi_regs, razwi_info, + eng_id); /* Clear event indication */ if (read_razwi_regs) @@ -7319,7 +7381,8 @@ dump_info: if (lbw_shrd_aw) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, true, - initiator_name, read_razwi_regs, razwi_info); + initiator_name, read_razwi_regs, razwi_info, + eng_id); /* Clear event indication */ if (read_razwi_regs) @@ -7328,7 +7391,8 @@ dump_info: if (lbw_shrd_ar) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, false, - initiator_name, read_razwi_regs, razwi_info); + initiator_name, read_razwi_regs, razwi_info, + eng_id); /* Clear event indication */ if (read_razwi_regs) @@ -7450,25 +7514,175 @@ static const char *gaudi2_get_initiators_name(u32 rtr_id) } } +static u16 gaudi2_get_razwi_initiators(u32 rtr_id, u16 *engines) +{ + switch (rtr_id) { + case DCORE0_RTR0: + engines[0] = GAUDI2_DCORE0_ENGINE_ID_DEC_0; + engines[1] = GAUDI2_DCORE0_ENGINE_ID_DEC_1; + engines[2] = GAUDI2_PCIE_ENGINE_ID_DEC_0; + engines[3] = GAUDI2_PCIE_ENGINE_ID_DEC_1; + engines[4] = GAUDI2_DCORE0_ENGINE_ID_TPC_6; + engines[5] = GAUDI2_ENGINE_ID_PDMA_0; + engines[6] = GAUDI2_ENGINE_ID_PDMA_1; + engines[7] = GAUDI2_ENGINE_ID_PCIE; + engines[8] = GAUDI2_DCORE0_ENGINE_ID_EDMA_0; + engines[9] = GAUDI2_DCORE1_ENGINE_ID_EDMA_0; + engines[10] = GAUDI2_ENGINE_ID_PSOC; + return 11; + + case DCORE0_RTR1: + engines[0] = GAUDI2_DCORE0_ENGINE_ID_TPC_0; + engines[1] = GAUDI2_DCORE0_ENGINE_ID_TPC_1; + return 2; + + case DCORE0_RTR2: + engines[0] = GAUDI2_DCORE0_ENGINE_ID_TPC_2; + engines[1] = GAUDI2_DCORE0_ENGINE_ID_TPC_3; + return 2; + + case DCORE0_RTR3: + engines[0] = GAUDI2_DCORE0_ENGINE_ID_TPC_4; + engines[1] = GAUDI2_DCORE0_ENGINE_ID_TPC_5; + return 2; + + case DCORE0_RTR4: + case DCORE0_RTR5: + case DCORE0_RTR6: + case DCORE0_RTR7: + engines[0] = GAUDI2_DCORE0_ENGINE_ID_MME; + return 1; + + case DCORE1_RTR0: + case DCORE1_RTR1: + case DCORE1_RTR2: + case DCORE1_RTR3: + engines[0] = GAUDI2_DCORE1_ENGINE_ID_MME; + return 1; + + case DCORE1_RTR4: + engines[0] = GAUDI2_DCORE1_ENGINE_ID_TPC_4; + engines[1] = GAUDI2_DCORE1_ENGINE_ID_TPC_5; + return 2; + + case DCORE1_RTR5: + engines[0] = GAUDI2_DCORE1_ENGINE_ID_TPC_2; + engines[1] = GAUDI2_DCORE1_ENGINE_ID_TPC_3; + return 2; + + case DCORE1_RTR6: + engines[0] = GAUDI2_DCORE1_ENGINE_ID_TPC_0; + engines[1] = GAUDI2_DCORE1_ENGINE_ID_TPC_1; + return 2; + + case DCORE1_RTR7: + engines[0] = GAUDI2_DCORE1_ENGINE_ID_DEC_0; + engines[1] = GAUDI2_DCORE1_ENGINE_ID_DEC_1; + engines[2] = GAUDI2_ENGINE_ID_NIC0_0; + engines[3] = GAUDI2_ENGINE_ID_NIC1_0; + engines[4] = GAUDI2_ENGINE_ID_NIC2_0; + engines[5] = GAUDI2_ENGINE_ID_NIC3_0; + engines[6] = GAUDI2_ENGINE_ID_NIC4_0; + engines[7] = GAUDI2_ENGINE_ID_ARC_FARM; + engines[8] = GAUDI2_ENGINE_ID_KDMA; + engines[9] = GAUDI2_DCORE0_ENGINE_ID_EDMA_1; + engines[10] = GAUDI2_DCORE1_ENGINE_ID_EDMA_1; + return 11; + + case DCORE2_RTR0: + engines[0] = GAUDI2_DCORE2_ENGINE_ID_DEC_0; + engines[1] = GAUDI2_DCORE2_ENGINE_ID_DEC_1; + engines[2] = GAUDI2_ENGINE_ID_NIC5_0; + engines[3] = GAUDI2_ENGINE_ID_NIC6_0; + engines[4] = GAUDI2_ENGINE_ID_NIC7_0; + engines[5] = GAUDI2_ENGINE_ID_NIC8_0; + engines[6] = GAUDI2_DCORE2_ENGINE_ID_EDMA_0; + engines[7] = GAUDI2_DCORE3_ENGINE_ID_EDMA_0; + engines[8] = GAUDI2_ENGINE_ID_ROT_0; + return 9; + + case DCORE2_RTR1: + engines[0] = GAUDI2_DCORE2_ENGINE_ID_TPC_4; + engines[1] = GAUDI2_DCORE2_ENGINE_ID_TPC_5; + return 2; + + case DCORE2_RTR2: + engines[0] = GAUDI2_DCORE2_ENGINE_ID_TPC_2; + engines[1] = GAUDI2_DCORE2_ENGINE_ID_TPC_3; + return 2; + + case DCORE2_RTR3: + engines[0] = GAUDI2_DCORE2_ENGINE_ID_TPC_0; + engines[1] = GAUDI2_DCORE2_ENGINE_ID_TPC_1; + return 2; + + case DCORE2_RTR4: + case DCORE2_RTR5: + case DCORE2_RTR6: + case DCORE2_RTR7: + engines[0] = GAUDI2_DCORE2_ENGINE_ID_MME; + return 1; + case DCORE3_RTR0: + case DCORE3_RTR1: + case DCORE3_RTR2: + case DCORE3_RTR3: + engines[0] = GAUDI2_DCORE3_ENGINE_ID_MME; + return 1; + case DCORE3_RTR4: + engines[0] = GAUDI2_DCORE3_ENGINE_ID_TPC_0; + engines[1] = GAUDI2_DCORE3_ENGINE_ID_TPC_1; + return 2; + case DCORE3_RTR5: + engines[0] = GAUDI2_DCORE3_ENGINE_ID_TPC_2; + engines[1] = GAUDI2_DCORE3_ENGINE_ID_TPC_3; + return 2; + case DCORE3_RTR6: + engines[0] = GAUDI2_DCORE3_ENGINE_ID_TPC_4; + engines[1] = GAUDI2_DCORE3_ENGINE_ID_TPC_5; + return 2; + case DCORE3_RTR7: + engines[0] = GAUDI2_DCORE3_ENGINE_ID_DEC_0; + engines[1] = GAUDI2_DCORE3_ENGINE_ID_DEC_1; + engines[2] = GAUDI2_ENGINE_ID_NIC9_0; + engines[3] = GAUDI2_ENGINE_ID_NIC10_0; + engines[4] = GAUDI2_ENGINE_ID_NIC11_0; + engines[5] = GAUDI2_DCORE2_ENGINE_ID_EDMA_1; + engines[6] = GAUDI2_DCORE3_ENGINE_ID_EDMA_1; + engines[7] = GAUDI2_ENGINE_ID_ROT_1; + engines[8] = GAUDI2_ENGINE_ID_ROT_0; + return 9; + default: + return 0; + } +} + static void gaudi2_razwi_unmapped_addr_hbw_printf_info(struct hl_device *hdev, u32 rtr_id, u64 rtr_ctrl_base_addr, bool is_write) { + u16 engines[HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR], num_of_eng; u32 razwi_hi, razwi_lo; + u8 rd_wr_flag; + + num_of_eng = gaudi2_get_razwi_initiators(rtr_id, &engines[0]); if (is_write) { razwi_hi = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AW_ADDR_HI); razwi_lo = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AW_ADDR_LO); + rd_wr_flag = HL_RAZWI_WRITE; /* Clear set indication */ WREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AW_SET, 0x1); } else { razwi_hi = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AR_ADDR_HI); razwi_lo = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AR_ADDR_LO); + rd_wr_flag = HL_RAZWI_READ; /* Clear set indication */ WREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AR_SET, 0x1); } + hl_capture_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &engines[0], num_of_eng, + rd_wr_flag | HL_RAZWI_HBW); dev_err_ratelimited(hdev->dev, "RAZWI PSOC unmapped HBW %s error, rtr id %u, address %#llx\n", is_write ? "WR" : "RD", rtr_id, (u64)razwi_hi << 32 | razwi_lo); @@ -7480,20 +7694,27 @@ static void gaudi2_razwi_unmapped_addr_hbw_printf_info(struct hl_device *hdev, u static void gaudi2_razwi_unmapped_addr_lbw_printf_info(struct hl_device *hdev, u32 rtr_id, u64 rtr_ctrl_base_addr, bool is_write) { + u16 engines[HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR], num_of_eng; u32 razwi_addr; + u8 rd_wr_flag; + + num_of_eng = gaudi2_get_razwi_initiators(rtr_id, &engines[0]); if (is_write) { razwi_addr = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_LBW_AW_ADDR); + rd_wr_flag = HL_RAZWI_WRITE; /* Clear set indication */ WREG32(rtr_ctrl_base_addr + DEC_RAZWI_LBW_AW_SET, 0x1); } else { razwi_addr = RREG32(rtr_ctrl_base_addr + DEC_RAZWI_LBW_AR_ADDR); + rd_wr_flag = HL_RAZWI_READ; /* Clear set indication */ WREG32(rtr_ctrl_base_addr + DEC_RAZWI_LBW_AR_SET, 0x1); } + hl_capture_razwi(hdev, razwi_addr, &engines[0], num_of_eng, rd_wr_flag | HL_RAZWI_LBW); dev_err_ratelimited(hdev->dev, "RAZWI PSOC unmapped LBW %s error, rtr id %u, address %#x\n", is_write ? "WR" : "RD", rtr_id, razwi_addr); @@ -7974,28 +8195,28 @@ static void gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(struct hl_device *hdev) razwi_happened_addr = mstr_if_base_addr + RR_SHRD_HBW_AW_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, mstr_if_base_addr, true, "PCIE", true, - NULL); + NULL, GAUDI2_ENGINE_ID_PCIE); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_HBW_AR_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, mstr_if_base_addr, false, "PCIE", true, - NULL); + NULL, GAUDI2_ENGINE_ID_PCIE); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_LBW_AW_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, mstr_if_base_addr, true, "PCIE", true, - NULL); + NULL, GAUDI2_ENGINE_ID_PCIE); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_LBW_AR_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, mstr_if_base_addr, false, "PCIE", true, - NULL); + NULL, GAUDI2_ENGINE_ID_PCIE); WREG32(razwi_happened_addr, 0x1); } } diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index 2b794f54e2ed3..a4ceee6818986 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -597,6 +597,10 @@ enum gaudi2_engine_id { GAUDI2_ENGINE_ID_NIC10_1, GAUDI2_ENGINE_ID_NIC11_0, GAUDI2_ENGINE_ID_NIC11_1, + GAUDI2_ENGINE_ID_PCIE, + GAUDI2_ENGINE_ID_PSOC, + GAUDI2_ENGINE_ID_ARC_FARM, + GAUDI2_ENGINE_ID_KDMA, GAUDI2_ENGINE_ID_SIZE }; -- GitLab From 4f11694f27582fa0875c4be7d133e0ae88ad36f8 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Thu, 29 Sep 2022 10:28:36 +0300 Subject: [PATCH 0710/1480] habanalabs/gaudi2: capture page fault data Capture page fault data when it happens. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 1058c8a0e644a..a4e3586f1a125 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8286,6 +8286,7 @@ static void gaudi2_handle_page_error(struct hl_device *hdev, u64 mmu_base, bool dev_err_ratelimited(hdev->dev, "%s page fault on va 0x%llx\n", is_pmmu ? "PMMU" : "HMMU", addr); + hl_capture_page_fault(hdev, addr, 0, is_pmmu); WREG32(mmu_base + MMU_OFFSET(mmDCORE0_HMMU0_MMU_PAGE_ERROR_CAPTURE), 0); } -- GitLab From 27cd39afde454ca8f9a438cfc84d676e96b36bd7 Mon Sep 17 00:00:00 2001 From: Tal Cohen Date: Mon, 3 Oct 2022 13:55:50 +0300 Subject: [PATCH 0711/1480] habanalabs: verify no zero event is sent The event notifier mechanism should not raise an empty event (event equals zero). Signed-off-by: Tal Cohen Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 5 +++++ drivers/misc/habanalabs/gaudi/gaudi.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index b8b32285720de..9b54d1df53022 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1746,6 +1746,11 @@ void hl_notifier_event_send_all(struct hl_device *hdev, u64 event_mask) { struct hl_fpriv *hpriv; + if (!event_mask) { + dev_warn(hdev->dev, "Skip sending zero event"); + return; + } + mutex_lock(&hdev->fpriv_list_lock); list_for_each_entry(hpriv, &hdev->fpriv_list, dev_node) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 1a99f7be8b609..337123f735014 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7945,7 +7945,9 @@ reset_device: /* despite reset doesn't execute. a notification on * occurred event needs to be sent here */ - hl_notifier_event_send_all(hdev, event_mask); + if (event_mask) + hl_notifier_event_send_all(hdev, event_mask); + if (reset_required) hl_device_reset(hdev, flags); else -- GitLab From dc8d243caea8056bd2580b0f1703fe019d3b4419 Mon Sep 17 00:00:00 2001 From: Dilip Puri Date: Wed, 12 Oct 2022 11:06:48 +0300 Subject: [PATCH 0712/1480] habanalabs/gaudi2: unsecure CBU_EARLY_BRESP registers NIC ARCs need to have access to CBU_EARLY_BRESP, hence we unsecure those registers. Signed-off-by: Dilip Puri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2_security.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2_security.c b/drivers/misc/habanalabs/gaudi2/gaudi2_security.c index c6906fb142290..768c2f3dc9003 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2_security.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2_security.c @@ -1764,6 +1764,7 @@ static const struct range gaudi2_pb_nic0_qm_arc_aux0_unsecured_regs[] = { {mmNIC0_QM_ARC_AUX0_CLUSTER_NUM, mmNIC0_QM_ARC_AUX0_WAKE_UP_EVENT}, {mmNIC0_QM_ARC_AUX0_ARC_RST_REQ, mmNIC0_QM_ARC_AUX0_CID_OFFSET_7}, {mmNIC0_QM_ARC_AUX0_SCRATCHPAD_0, mmNIC0_QM_ARC_AUX0_INFLIGHT_LBU_RD_CNT}, + {mmNIC0_QM_ARC_AUX0_CBU_EARLY_BRESP_EN, mmNIC0_QM_ARC_AUX0_CBU_EARLY_BRESP_EN}, {mmNIC0_QM_ARC_AUX0_LBU_EARLY_BRESP_EN, mmNIC0_QM_ARC_AUX0_LBU_EARLY_BRESP_EN}, {mmNIC0_QM_ARC_AUX0_DCCM_QUEUE_BASE_ADDR_0, mmNIC0_QM_ARC_AUX0_DCCM_QUEUE_ALERT_MSG}, {mmNIC0_QM_ARC_AUX0_DCCM_Q_PUSH_FIFO_CNT, mmNIC0_QM_ARC_AUX0_QMAN_ARC_CQ_SHADOW_CI}, -- GitLab From 24fdfb359cadd222de8ba9d2d6a3f4dfc514878a Mon Sep 17 00:00:00 2001 From: Ohad Sharabi Date: Tue, 18 Oct 2022 08:51:33 +0300 Subject: [PATCH 0713/1480] habanalabs: fix using freed pointer The code uses the pointer for trace purpose (without actually dereference it) but still get static analysis warning. This patch eliminate the warning. Signed-off-by: Ohad Sharabi Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 9b54d1df53022..dd01be5c4ba3e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -135,6 +135,9 @@ static void hl_asic_dma_free_common(struct hl_device *hdev, size_t size, void *c dma_addr_t dma_handle, enum dma_alloc_type alloc_type, const char *caller) { + /* this is needed to avoid warning on using freed pointer */ + u64 store_cpu_addr = (u64) (uintptr_t) cpu_addr; + switch (alloc_type) { case DMA_ALLOC_COHERENT: hdev->asic_funcs->asic_dma_free_coherent(hdev, size, cpu_addr, dma_handle); @@ -147,7 +150,7 @@ static void hl_asic_dma_free_common(struct hl_device *hdev, size_t size, void *c break; } - trace_habanalabs_dma_free(hdev->dev, (u64) (uintptr_t) cpu_addr, dma_handle, size, caller); + trace_habanalabs_dma_free(hdev->dev, store_cpu_addr, dma_handle, size, caller); } void *hl_asic_dma_alloc_coherent_caller(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle, -- GitLab From e325d5dbf34500fd42d5847d5b8c4e097f8030af Mon Sep 17 00:00:00 2001 From: Ohad Sharabi Date: Wed, 14 Sep 2022 08:53:29 +0300 Subject: [PATCH 0714/1480] habanalabs: allow setting HBM BAR to other regions Up until now the use-case in the driver was that the HBM is accessed using the HBM BAR, yet the BAR sometimes cannot cover the whole HBM and so we needed to set the BAR to other HBM offset. Now we are facing the need to access other PCI memory regions that can be covered by the HBM BAR. To answer that we are allowing the caller to determine if the HBM BAR need to be set or not regardless of the PCI memory region. Signed-off-by: Ohad Sharabi Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 29 ++++++++++++--------- drivers/misc/habanalabs/common/habanalabs.h | 2 ++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index dd01be5c4ba3e..0026fe42b3d2c 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -32,6 +32,7 @@ enum dma_alloc_type { * @hdev: pointer to habanalabs device structure. * @addr: the address the caller wants to access. * @region: the PCI region. + * @new_bar_region_base: the new BAR region base address. * * @return: the old BAR base address on success, U64_MAX for failure. * The caller should set it back to the old address after use. @@ -41,7 +42,8 @@ enum dma_alloc_type { * This function can be called also if the bar doesn't need to be set, * in that case it just won't change the base. */ -static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_region *region) +static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_region *region, + u64 *new_bar_region_base) { struct asic_fixed_properties *prop = &hdev->asic_prop; u64 bar_base_addr, old_base; @@ -55,27 +57,28 @@ static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_regi old_base = hdev->asic_funcs->set_dram_bar_base(hdev, bar_base_addr); /* in case of success we need to update the new BAR base */ - if (old_base != U64_MAX) - region->region_base = bar_base_addr; + if ((old_base != U64_MAX) && new_bar_region_base) + *new_bar_region_base = bar_base_addr; return old_base; } -static int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val, - enum debugfs_access_type acc_type, enum pci_region region_type) +int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val, + enum debugfs_access_type acc_type, enum pci_region region_type, bool set_dram_bar) { struct pci_mem_region *region = &hdev->pci_mem_region[region_type]; + u64 old_base = 0, rc, new_bar_region_base = 0; void __iomem *acc_addr; - u64 old_base = 0, rc; - if (region_type == PCI_REGION_DRAM) { - old_base = hl_set_dram_bar(hdev, addr, region); + if (set_dram_bar) { + old_base = hl_set_dram_bar(hdev, addr, region, &new_bar_region_base); if (old_base == U64_MAX) return -EIO; } - acc_addr = hdev->pcie_bar[region->bar_id] + addr - region->region_base + - region->offset_in_bar; + acc_addr = hdev->pcie_bar[region->bar_id] + region->offset_in_bar + + (addr - new_bar_region_base); + switch (acc_type) { case DEBUGFS_READ8: *val = readb(acc_addr); @@ -97,8 +100,8 @@ static int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val break; } - if (region_type == PCI_REGION_DRAM) { - rc = hl_set_dram_bar(hdev, old_base, region); + if (set_dram_bar) { + rc = hl_set_dram_bar(hdev, old_base, region, NULL); if (rc == U64_MAX) return -EIO; } @@ -283,7 +286,7 @@ int hl_access_dev_mem(struct hl_device *hdev, enum pci_region region_type, case PCI_REGION_SRAM: case PCI_REGION_DRAM: return hl_access_sram_dram_region(hdev, addr, val, acc_type, - region_type); + region_type, (region_type == PCI_REGION_DRAM)); default: return -EFAULT; } diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 4913197c433e6..c8347eac09ed0 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -3486,6 +3486,8 @@ void hl_asic_dma_pool_free_caller(struct hl_device *hdev, void *vaddr, dma_addr_ int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir); void hl_dma_unmap_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir); +int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val, + enum debugfs_access_type acc_type, enum pci_region region_type, bool set_dram_bar); int hl_access_cfg_region(struct hl_device *hdev, u64 addr, u64 *val, enum debugfs_access_type acc_type); int hl_access_dev_mem(struct hl_device *hdev, enum pci_region region_type, -- GitLab From 5ad06bb1d2c073c8b071016226fb9ebe2163e660 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 20 Oct 2022 11:29:03 +0300 Subject: [PATCH 0715/1480] habanalabs/gaudi2: remove configurations to access the MSI-X doorbell The virtual MSI-X doorbell is supported now in F/W, so all configurations to access the PCIE_DBI MSI-X doorbell can be removed. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 34 +++---------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index a4e3586f1a125..9208f69dd7f81 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -4473,23 +4473,9 @@ static void gaudi2_init_sm(struct hl_device *hdev) reg_val = FIELD_PREP(DCORE0_SYNC_MNGR_OBJS_MON_CONFIG_CQ_EN_MASK, 1); WREG32(mmDCORE0_SYNC_MNGR_OBJS_MON_CONFIG_0 + (4 * i), reg_val); - /* Init CQ0 DB */ - /* Configure the monitor to trigger MSI-X interrupt */ - /* TODO: - * Remove the if statement when virtual MSI-X doorbell is supported in simulator (SW-93022) - * and in F/W (SW-93024). - */ - if (!hdev->pdev || hdev->asic_prop.fw_security_enabled) { - u64 msix_db_reg = CFG_BASE + mmPCIE_DBI_MSIX_DOORBELL_OFF; - - WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_L_0, lower_32_bits(msix_db_reg)); - WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_H_0, upper_32_bits(msix_db_reg)); - } else { - WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_L_0, - lower_32_bits(gaudi2->virt_msix_db_dma_addr)); - WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_H_0, - upper_32_bits(gaudi2->virt_msix_db_dma_addr)); - } + /* Init CQ0 DB - configure the monitor to trigger MSI-X interrupt */ + WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_L_0, lower_32_bits(gaudi2->virt_msix_db_dma_addr)); + WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_H_0, upper_32_bits(gaudi2->virt_msix_db_dma_addr)); WREG32(mmDCORE0_SYNC_MNGR_GLBL_LBW_DATA_0, GAUDI2_IRQ_NUM_COMPLETION); for (i = 0 ; i < GAUDI2_RESERVED_CQ_NUMBER ; i++) { @@ -4657,20 +4643,6 @@ static void gaudi2_init_vdec_brdg_ctrl(struct hl_device *hdev, u64 base_addr, u3 { u32 sob_id; - /* TODO: - * Remove when virtual MSI-X doorbell is supported in simulator (SW-93022) and in F/W - * (SW-93024). - */ - if (!hdev->pdev || hdev->asic_prop.fw_security_enabled) { - u32 interrupt_id = GAUDI2_IRQ_NUM_DCORE0_DEC0_NRM + 2 * decoder_id; - - WREG32(base_addr + BRDG_CTRL_NRM_MSIX_LBW_AWADDR, mmPCIE_DBI_MSIX_DOORBELL_OFF); - WREG32(base_addr + BRDG_CTRL_NRM_MSIX_LBW_WDATA, interrupt_id); - WREG32(base_addr + BRDG_CTRL_ABNRM_MSIX_LBW_AWADDR, mmPCIE_DBI_MSIX_DOORBELL_OFF); - WREG32(base_addr + BRDG_CTRL_ABNRM_MSIX_LBW_WDATA, interrupt_id + 1); - return; - } - /* VCMD normal interrupt */ sob_id = GAUDI2_RESERVED_SOB_DEC_NRM_FIRST + decoder_id; WREG32(base_addr + BRDG_CTRL_NRM_MSIX_LBW_AWADDR, -- GitLab From 6bcb2d05a59b3534821a194f8642808ae56f2d10 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Wed, 19 Oct 2022 20:24:55 +0300 Subject: [PATCH 0716/1480] habanalabs: fix user mappings calculation in case of page fault As there are 2 types of user mappings, pmmu and hmmu, calculate only the relevant mappings for the requested type. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 0026fe42b3d2c..0e88396744a1e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2305,8 +2305,13 @@ static void hl_capture_user_mappings(struct hl_device *hdev, bool is_pmmu) } mutex_lock(&ctx->mem_hash_lock); - hash_for_each(ctx->mem_hash, i, hnode, node) - pgf_info->num_of_user_mappings++; + hash_for_each(ctx->mem_hash, i, hnode, node) { + vm_type = hnode->ptr; + if (((*vm_type == VM_TYPE_USERPTR) && is_pmmu) || + ((*vm_type == VM_TYPE_PHYS_PACK) && !is_pmmu)) + pgf_info->num_of_user_mappings++; + + } if (!pgf_info->num_of_user_mappings) goto finish; -- GitLab From d1e0ac37ed41e581c030a8fffe4ad1d0bb987872 Mon Sep 17 00:00:00 2001 From: Ohad Sharabi Date: Sun, 23 Oct 2022 14:46:08 +0300 Subject: [PATCH 0717/1480] habanalabs: avoid divide by zero in device utilization Currently there is no verification whether the divisor is legal. Signed-off-by: Ohad Sharabi Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 0e88396744a1e..b71303ba11d0e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -987,11 +987,16 @@ static void device_late_fini(struct hl_device *hdev) int hl_device_utilization(struct hl_device *hdev, u32 *utilization) { - u64 max_power, curr_power, dc_power, dividend; + u64 max_power, curr_power, dc_power, dividend, divisor; int rc; max_power = hdev->max_power; dc_power = hdev->asic_prop.dc_power_default; + divisor = max_power - dc_power; + if (!divisor) { + dev_warn(hdev->dev, "device utilization is not supported\n"); + return -EOPNOTSUPP; + } rc = hl_fw_cpucp_power_get(hdev, &curr_power); if (rc) @@ -1000,7 +1005,7 @@ int hl_device_utilization(struct hl_device *hdev, u32 *utilization) curr_power = clamp(curr_power, dc_power, max_power); dividend = (curr_power - dc_power) * 100; - *utilization = (u32) div_u64(dividend, (max_power - dc_power)); + *utilization = (u32) div_u64(dividend, divisor); return 0; } -- GitLab From a88a6f5f5cdfce21aaf988370287e0e78970c8ad Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 15:08:13 +0300 Subject: [PATCH 0718/1480] habanalabs: add support for graceful hard reset Calling hl_device_reset() for a hard reset will lead to a quite immediate device reset and to killing user process. For resets that follow errors, it disables the option to debug the errors on both the device side and the user application side. This patch adds a 'graceful hard reset' option and a new hl_device_cond_reset() function. Under some conditions, mainly if there is no user process or if he is not registered to driver notifications, this function will execute hard reset as usual. Otherwise, the reset will be postponed and a notification will be sent to user, to let him perform post-error actions and then to release the device, after which reset will take place. If device is not released by user in some defined time, a watchdog work will execute the reset in any case. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 141 ++++++++++++++++++-- drivers/misc/habanalabs/common/habanalabs.h | 14 +- 2 files changed, 140 insertions(+), 15 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index b71303ba11d0e..bcd9599249714 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -16,7 +16,9 @@ #include -#define HL_RESET_DELAY_USEC 10000 /* 10ms */ +#define HL_RESET_DELAY_USEC 10000 /* 10ms */ + +#define HL_DEVICE_RELEASE_WATCHDOG_TIMEOUT_SEC 5 enum dma_alloc_type { DMA_ALLOC_COHERENT, @@ -387,7 +389,7 @@ bool hl_ctrl_device_operational(struct hl_device *hdev, static void hpriv_release(struct kref *ref) { u64 idle_mask[HL_BUSY_ENGINES_MASK_EXT_SIZE] = {0}; - bool device_is_idle = true; + bool reset_device, device_is_idle = true; struct hl_fpriv *hpriv; struct hl_device *hdev; @@ -404,14 +406,20 @@ static void hpriv_release(struct kref *ref) mutex_destroy(&hpriv->ctx_lock); mutex_destroy(&hpriv->restore_phase_mutex); - /* No need for idle status check if device is going to be reset in any case */ - if (!hdev->reset_upon_device_release && hdev->pdev && !hdev->pldm) + /* Device should be reset if reset-upon-device-release is enabled, or if there is a pending + * reset that waits for device release. + */ + reset_device = hdev->reset_upon_device_release || hdev->reset_info.watchdog_active; + + /* Unless device is reset in any case, check idle status and reset if device is not idle */ + if (!reset_device && hdev->pdev && !hdev->pldm) device_is_idle = hdev->asic_funcs->is_device_idle(hdev, idle_mask, HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL); - - if (!device_is_idle) + if (!device_is_idle) { dev_err(hdev->dev, "device not idle after user context is closed (0x%llx_%llx)\n", idle_mask[1], idle_mask[0]); + reset_device = true; + } /* We need to remove the user from the list to make sure the reset process won't * try to kill the user process. Because, if we got here, it means there are no @@ -426,9 +434,10 @@ static void hpriv_release(struct kref *ref) list_del(&hpriv->dev_node); mutex_unlock(&hdev->fpriv_list_lock); - if (!device_is_idle || hdev->reset_upon_device_release) { + if (reset_device) { hl_device_reset(hdev, HL_DRV_RESET_DEV_RELEASE); } else { + /* Scrubbing is handled within hl_device_reset(), so here need to do it directly */ int rc = hdev->asic_funcs->scrub_device_mem(hdev); if (rc) @@ -695,6 +704,20 @@ static void device_hard_reset_pending(struct work_struct *work) } } +static void device_release_watchdog_func(struct work_struct *work) +{ + struct hl_device_reset_work *device_release_watchdog_work = + container_of(work, struct hl_device_reset_work, reset_work.work); + struct hl_device *hdev = device_release_watchdog_work->hdev; + u32 flags; + + dev_dbg(hdev->dev, "Device wasn't released in time. Initiate device reset.\n"); + + flags = device_release_watchdog_work->flags | HL_DRV_RESET_FROM_WD_THR; + + hl_device_reset(hdev, flags); +} + /* * device_early_init - do some early initialization for the habanalabs device * @@ -813,11 +836,14 @@ static int device_early_init(struct hl_device *hdev) goto free_cb_mgr; } - INIT_DELAYED_WORK(&hdev->device_reset_work.reset_work, - device_hard_reset_pending); + INIT_DELAYED_WORK(&hdev->device_reset_work.reset_work, device_hard_reset_pending); hdev->device_reset_work.hdev = hdev; hdev->device_fini_pending = 0; + INIT_DELAYED_WORK(&hdev->device_release_watchdog_work.reset_work, + device_release_watchdog_func); + hdev->device_release_watchdog_work.hdev = hdev; + mutex_init(&hdev->send_cpu_message_lock); mutex_init(&hdev->debug_lock); INIT_LIST_HEAD(&hdev->cs_mirror_list); @@ -1367,8 +1393,8 @@ static void handle_reset_trigger(struct hl_device *hdev, u32 flags) int hl_device_reset(struct hl_device *hdev, u32 flags) { bool hard_reset, from_hard_reset_thread, fw_reset, hard_instead_soft = false, - reset_upon_device_release = false, schedule_hard_reset = false, - skip_wq_flush, delay_reset; + reset_upon_device_release = false, schedule_hard_reset = false, delay_reset, + from_dev_release, from_watchdog_thread; u64 idle_mask[HL_BUSY_ENGINES_MASK_EXT_SIZE] = {0}; struct hl_ctx *ctx; int i, rc; @@ -1381,8 +1407,9 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) hard_reset = !!(flags & HL_DRV_RESET_HARD); from_hard_reset_thread = !!(flags & HL_DRV_RESET_FROM_RESET_THR); fw_reset = !!(flags & HL_DRV_RESET_BYPASS_REQ_TO_FW); - skip_wq_flush = !!(flags & HL_DRV_RESET_DEV_RELEASE); + from_dev_release = !!(flags & HL_DRV_RESET_DEV_RELEASE); delay_reset = !!(flags & HL_DRV_RESET_DELAY); + from_watchdog_thread = !!(flags & HL_DRV_RESET_FROM_WD_THR); if (!hard_reset && !hdev->asic_prop.supports_compute_reset) { hard_instead_soft = true; @@ -1439,6 +1466,23 @@ do_reset: spin_unlock(&hdev->reset_info.lock); + /* Cancel the device release watchdog work if required. + * In case of reset-upon-device-release while the release watchdog work is + * scheduled, do hard-reset instead of compute-reset. + */ + if ((hard_reset || from_dev_release) && hdev->reset_info.watchdog_active) { + hdev->reset_info.watchdog_active = 0; + if (!from_watchdog_thread) + cancel_delayed_work_sync( + &hdev->device_release_watchdog_work.reset_work); + + if (from_dev_release) { + flags |= HL_DRV_RESET_HARD; + flags &= ~HL_DRV_RESET_DEV_RELEASE; + hard_reset = true; + } + } + if (delay_reset) usleep_range(HL_RESET_DELAY_USEC, HL_RESET_DELAY_USEC << 1); @@ -1474,7 +1518,7 @@ again: return 0; } - cleanup_resources(hdev, hard_reset, fw_reset, skip_wq_flush); + cleanup_resources(hdev, hard_reset, fw_reset, from_dev_release); kill_processes: if (hard_reset) { @@ -1735,6 +1779,73 @@ out_err: return rc; } +/* + * hl_device_cond_reset() - conditionally reset the device. + * @hdev: pointer to habanalabs device structure. + * @reset_flags: reset flags. + * @event_mask: events to notify user about. + * + * Conditionally reset the device, or alternatively schedule a watchdog work to reset the device + * unless another reset precedes it. + */ +int hl_device_cond_reset(struct hl_device *hdev, u32 flags, u64 event_mask) +{ + struct hl_ctx *ctx = NULL; + + /* Device release watchdog is only for hard reset */ + if (!(flags & HL_DRV_RESET_HARD) && hdev->asic_prop.allow_inference_soft_reset) + goto device_reset; + + /* F/W reset cannot be postponed */ + if (flags & HL_DRV_RESET_BYPASS_REQ_TO_FW) + goto device_reset; + + /* Device release watchdog is relevant only if user exists and gets a reset notification */ + if (!(event_mask & HL_NOTIFIER_EVENT_DEVICE_RESET)) { + dev_err(hdev->dev, "Resetting device without a reset indication to user\n"); + goto device_reset; + } + + ctx = hl_get_compute_ctx(hdev); + if (!ctx || !ctx->hpriv->notifier_event.eventfd) + goto device_reset; + + /* Schedule the device release watchdog work unless reset is already in progress or if the + * work is already scheduled. + */ + spin_lock(&hdev->reset_info.lock); + if (hdev->reset_info.in_reset) { + spin_unlock(&hdev->reset_info.lock); + goto device_reset; + } + + if (hdev->reset_info.watchdog_active) + goto out; + + hdev->device_release_watchdog_work.flags = flags; + dev_dbg(hdev->dev, "Device is going to be reset in %u sec unless being released\n", + hdev->device_release_watchdog_timeout_sec); + schedule_delayed_work(&hdev->device_release_watchdog_work.reset_work, + msecs_to_jiffies(hdev->device_release_watchdog_timeout_sec * 1000)); + hdev->reset_info.watchdog_active = 1; +out: + spin_unlock(&hdev->reset_info.lock); + + hl_notifier_event_send_all(hdev, event_mask); + + hl_ctx_put(ctx); + + return 0; + +device_reset: + if (event_mask) + hl_notifier_event_send_all(hdev, event_mask); + if (ctx) + hl_ctx_put(ctx); + + return hl_device_reset(hdev, flags); +} + static void hl_notifier_event_send(struct hl_notifier_event *notifier_event, u64 event_mask) { mutex_lock(¬ifier_event->lock); @@ -1932,6 +2043,8 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) hdev->asic_funcs->state_dump_init(hdev); + hdev->device_release_watchdog_timeout_sec = HL_DEVICE_RELEASE_WATCHDOG_TIMEOUT_SEC; + hdev->memory_scrub_val = MEM_SCRUB_DEFAULT_VAL; hl_debugfs_add_device(hdev); @@ -2152,6 +2265,8 @@ void hl_device_fini(struct hl_device *hdev) } } + cancel_delayed_work_sync(&hdev->device_release_watchdog_work.reset_work); + /* Disable PCI access from device F/W so it won't send us additional * interrupts. We disable MSI/MSI-X at the halt_engines function and we * can't have the F/W sending us interrupts after that. We need to diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index c8347eac09ed0..bfaaa9daa7501 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -191,6 +191,9 @@ enum hl_mmu_enablement { * * - HL_DRV_RESET_DELAY * Set if a delay should be added before the reset + * + * - HL_DRV_RESET_FROM_WD_THR + * Set if the caller is the device release watchdog thread */ #define HL_DRV_RESET_HARD (1 << 0) @@ -201,6 +204,7 @@ enum hl_mmu_enablement { #define HL_DRV_RESET_BYPASS_REQ_TO_FW (1 << 5) #define HL_DRV_RESET_FW_FATAL_ERR (1 << 6) #define HL_DRV_RESET_DELAY (1 << 7) +#define HL_DRV_RESET_FROM_WD_THR (1 << 8) /* * Security @@ -3009,6 +3013,7 @@ struct hl_error_info { * same cause. * @skip_reset_on_timeout: Skip device reset if CS has timed out, wait for it to * complete instead. + * @watchdog_active: true if a device release watchdog work is scheduled. */ struct hl_reset_info { spinlock_t lock; @@ -3019,12 +3024,11 @@ struct hl_reset_info { u8 in_compute_reset; u8 needs_reset; u8 hard_reset_pending; - u8 curr_reset_cause; u8 prev_reset_trigger; u8 reset_trigger_repeated; - u8 skip_reset_on_timeout; + u8 watchdog_active; }; /** @@ -3040,6 +3044,8 @@ struct hl_reset_info { * @dev_ctrl: related kernel device structure for the control device * @work_heartbeat: delayed work for CPU-CP is-alive check. * @device_reset_work: delayed work which performs hard reset + * @device_release_watchdog_work: watchdog work that performs hard reset if user doesn't release + * device upon certain error cases. * @asic_name: ASIC specific name. * @asic_type: ASIC specific type. * @completion_queue: array of hl_cq. @@ -3149,6 +3155,7 @@ struct hl_reset_info { * indicates which decoder engines are binned-out * @edma_binning: contains mask of edma engines that is received from the f/w which * indicates which edma engines are binned-out + * @device_release_watchdog_timeout_sec: device release watchdog timeout value in seconds. * @id: device minor. * @id_control: minor of the control device. * @cdev_idx: char device index. Used for setting its name. @@ -3218,6 +3225,7 @@ struct hl_device { struct device *dev_ctrl; struct delayed_work work_heartbeat; struct hl_device_reset_work device_reset_work; + struct hl_device_reset_work device_release_watchdog_work; char asic_name[HL_STR_MAX]; char status[HL_DEV_STS_MAX][HL_STR_MAX]; enum hl_asic_type asic_type; @@ -3312,6 +3320,7 @@ struct hl_device { u32 high_pll; u32 decoder_binning; u32 edma_binning; + u32 device_release_watchdog_timeout_sec; u16 id; u16 id_control; u16 cdev_idx; @@ -3551,6 +3560,7 @@ void hl_device_fini(struct hl_device *hdev); int hl_device_suspend(struct hl_device *hdev); int hl_device_resume(struct hl_device *hdev); int hl_device_reset(struct hl_device *hdev, u32 flags); +int hl_device_cond_reset(struct hl_device *hdev, u32 flags, u64 event_mask); void hl_hpriv_get(struct hl_fpriv *hpriv); int hl_hpriv_put(struct hl_fpriv *hpriv); int hl_device_utilization(struct hl_device *hdev, u32 *utilization); -- GitLab From 11669b58fa1cee8442ae31ad4ba71398729727b5 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 16:37:41 +0300 Subject: [PATCH 0719/1480] habanalabs: add an option to control watchdog timeout via debugfs Add an option to control the timeout value for the driver's watchdog of the reset process. The timeout represents the amount of the user has to close his process once he gets a device reset notification from the driver. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- Documentation/ABI/testing/debugfs-driver-habanalabs | 7 +++++++ drivers/misc/habanalabs/common/debugfs.c | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/ABI/testing/debugfs-driver-habanalabs b/Documentation/ABI/testing/debugfs-driver-habanalabs index c915bf17b2932..85f6d04f528b6 100644 --- a/Documentation/ABI/testing/debugfs-driver-habanalabs +++ b/Documentation/ABI/testing/debugfs-driver-habanalabs @@ -91,6 +91,13 @@ Description: Enables the root user to set the device to specific state. Valid values are "disable", "enable", "suspend", "resume". User can read this property to see the valid values +What: /sys/kernel/debug/habanalabs/hl/device_release_watchdog_timeout +Date: Oct 2022 +KernelVersion: 6.2 +Contact: ttayar@habana.ai +Description: The watchdog timeout value in seconds for a device relese upon + certain error cases, after which the device is reset. + What: /sys/kernel/debug/habanalabs/hl/dma_size Date: Apr 2021 KernelVersion: 5.13 diff --git a/drivers/misc/habanalabs/common/debugfs.c b/drivers/misc/habanalabs/common/debugfs.c index 48d3ec8b5c825..945c0e6758caa 100644 --- a/drivers/misc/habanalabs/common/debugfs.c +++ b/drivers/misc/habanalabs/common/debugfs.c @@ -1769,6 +1769,11 @@ void hl_debugfs_add_device(struct hl_device *hdev) dev_entry, &hl_timeout_locked_fops); + debugfs_create_u32("device_release_watchdog_timeout", + 0644, + dev_entry->root, + &hdev->device_release_watchdog_timeout_sec); + for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { debugfs_create_file(hl_debugfs_list[i].name, 0444, -- GitLab From 5b8873b39c5d4ee93e382389b199d553b38b19f3 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 16:43:47 +0300 Subject: [PATCH 0720/1480] habanalabs/gaudi: use graceful hard reset for F/W events Use graceful hard reset for F/W events on Gaudi device that require a device reset. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi/gaudi.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 337123f735014..3dfb9ecf7db37 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7942,16 +7942,14 @@ reset_device: reset_required = false; } - /* despite reset doesn't execute. a notification on - * occurred event needs to be sent here - */ - if (event_mask) - hl_notifier_event_send_all(hdev, event_mask); - - if (reset_required) - hl_device_reset(hdev, flags); - else + if (reset_required) { + hl_device_cond_reset(hdev, flags, event_mask); + } else { hl_fw_unmask_irq(hdev, event_type); + /* Notification on occurred event needs to be sent although reset is not executed */ + if (event_mask) + hl_notifier_event_send_all(hdev, event_mask); + } } static void *gaudi_get_events_stat(struct hl_device *hdev, bool aggregate, u32 *size) -- GitLab From d1ce7e5ea140bb01d8c6faded09b9264bb83f722 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 16:57:54 +0300 Subject: [PATCH 0721/1480] habanalabs/gaudi2: use graceful hard reset for F/W events Use graceful hard reset for F/W events on Gaudi2 device that require a device reset. While at it, do a small refactor of the checks and function calls, to simplify it and to avoid code duplication. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 27 +++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 9208f69dd7f81..22f5445fe71c2 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8768,9 +8768,9 @@ static void hl_arc_event_handle(struct hl_device *hdev, static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entry) { - u32 ctl, reset_flags = HL_DRV_RESET_HARD | HL_DRV_RESET_DELAY; - struct gaudi2_device *gaudi2 = hdev->asic_specific; bool reset_required = false, skip_reset = false, is_critical = false; + struct gaudi2_device *gaudi2 = hdev->asic_specific; + u32 ctl, reset_flags = HL_DRV_RESET_HARD; int index, sbte_index; u64 event_mask = 0; u16 event_type; @@ -9158,7 +9158,9 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent event_type); } - if ((gaudi2_irq_map_table[event_type].reset || reset_required) && !skip_reset) + if ((gaudi2_irq_map_table[event_type].reset || reset_required) && !skip_reset && + (hdev->hard_reset_on_fw_events || + (hdev->asic_prop.fw_security_enabled && is_critical))) goto reset_device; /* Send unmask irq only for interrupts not classified as MSG */ @@ -9172,22 +9174,13 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent reset_device: if (hdev->asic_prop.fw_security_enabled && is_critical) { - reset_flags = HL_DRV_RESET_HARD | HL_DRV_RESET_BYPASS_REQ_TO_FW; - - /* notify on device unavailable while the reset triggered by fw */ - event_mask |= (HL_NOTIFIER_EVENT_DEVICE_RESET | - HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE); - hl_device_reset(hdev, reset_flags); - } else if (hdev->hard_reset_on_fw_events) { - event_mask |= HL_NOTIFIER_EVENT_DEVICE_RESET; - hl_device_reset(hdev, reset_flags); + reset_flags |= HL_DRV_RESET_BYPASS_REQ_TO_FW; + event_mask |= HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE; } else { - if (!gaudi2_irq_map_table[event_type].msg) - hl_fw_unmask_irq(hdev, event_type); + reset_flags |= HL_DRV_RESET_DELAY; } - - if (event_mask) - hl_notifier_event_send_all(hdev, event_mask); + event_mask |= HL_NOTIFIER_EVENT_DEVICE_RESET; + hl_device_cond_reset(hdev, reset_flags, event_mask); } static int gaudi2_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, u64 val) -- GitLab From 1b363adc7fbe37c4b6c18864c1f7043d85b4af6e Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 30 Sep 2022 17:02:19 +0300 Subject: [PATCH 0722/1480] habanalabs: use graceful hard reset for CS timeouts Use graceful hard reset when detecting a CS timeout that requires a device reset. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../misc/habanalabs/common/command_submission.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/misc/habanalabs/common/command_submission.c b/drivers/misc/habanalabs/common/command_submission.c index fa05770865c65..f1c69c8ed74a6 100644 --- a/drivers/misc/habanalabs/common/command_submission.c +++ b/drivers/misc/habanalabs/common/command_submission.c @@ -798,7 +798,7 @@ out: static void cs_timedout(struct work_struct *work) { struct hl_device *hdev; - u64 event_mask; + u64 event_mask = 0x0; int rc; struct hl_cs *cs = container_of(work, struct hl_cs, work_tdr.work); @@ -830,11 +830,7 @@ static void cs_timedout(struct work_struct *work) if (rc) { hdev->captured_err_info.cs_timeout.timestamp = ktime_get(); hdev->captured_err_info.cs_timeout.seq = cs->sequence; - - event_mask = device_reset ? (HL_NOTIFIER_EVENT_CS_TIMEOUT | - HL_NOTIFIER_EVENT_DEVICE_RESET) : HL_NOTIFIER_EVENT_CS_TIMEOUT; - - hl_notifier_event_send_all(hdev, event_mask); + event_mask |= HL_NOTIFIER_EVENT_CS_TIMEOUT; } switch (cs->type) { @@ -869,8 +865,12 @@ static void cs_timedout(struct work_struct *work) cs_put(cs); - if (device_reset) - hl_device_reset(hdev, HL_DRV_RESET_TDR); + if (device_reset) { + event_mask |= HL_NOTIFIER_EVENT_DEVICE_RESET; + hl_device_cond_reset(hdev, HL_DRV_RESET_TDR, event_mask); + } else if (event_mask) { + hl_notifier_event_send_all(hdev, event_mask); + } } static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, -- GitLab From 4a9c6e2cdf2b4128f5204b9cf14e3a788a8511df Mon Sep 17 00:00:00 2001 From: Tal Cohen Date: Tue, 18 Oct 2022 17:35:06 +0300 Subject: [PATCH 0723/1480] habanalabs: no consecutive err when user context is enabled Consecutive error protects a device reset loop from being triggered due to h/w issues and enters the device into an unavailable state. When user may cause the error, an unavailable state will prevent the user from running its workloads. The commit prevents entering consecutive state when a user context is enabled. Signed-off-by: Tal Cohen Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index bcd9599249714..61ddcb1ce5089 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1320,6 +1320,10 @@ static void handle_reset_trigger(struct hl_device *hdev, u32 flags) { u32 cur_reset_trigger = HL_RESET_TRIGGER_DEFAULT; + /* No consecutive mechanism when user context exists */ + if (hdev->is_compute_ctx_active) + return; + /* * 'reset cause' is being updated here, because getting here * means that it's the 1st time and the last time we're here -- GitLab From 679e968908a4997d02c2a7df294e97b066f9149f Mon Sep 17 00:00:00 2001 From: farah kassabri Date: Tue, 20 Sep 2022 11:48:40 +0300 Subject: [PATCH 0724/1480] habanalabs: zero ts registration buff when allocated To avoid memory corruption in kernel memory while using timestamp registration nodes, zero the kernel buff memory when its allocated. Signed-off-by: farah kassabri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index 99b1d6ce26aef..541e1b6a2176d 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -2109,7 +2109,7 @@ static int hl_ts_alloc_buf(struct hl_mmap_mem_buf *buf, gfp_t gfp, void *args) /* Allocate the internal kernel buffer */ size = num_elements * sizeof(struct hl_user_pending_interrupt); - p = vmalloc(size); + p = vzalloc(size); if (!p) goto free_user_buff; -- GitLab From fc69aa8640f8baf9c1246c17ca858bab9aea98b0 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Mon, 24 Oct 2022 01:14:18 +0300 Subject: [PATCH 0725/1480] habanalabs: fix PCIe access to SRAM via debugfs hl_access_sram_dram_region() uses a region base which is set within the hl_set_dram_bar() function. However, for SRAM access this function is not called, and we end up with a wrong value of region base and with a bad calculated address. Fix it by initializing the region base value independently of whether hl_set_dram_bar() is called or not. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 61ddcb1ce5089..cb8ecc17bba14 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -69,17 +69,17 @@ int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val, enum debugfs_access_type acc_type, enum pci_region region_type, bool set_dram_bar) { struct pci_mem_region *region = &hdev->pci_mem_region[region_type]; - u64 old_base = 0, rc, new_bar_region_base = 0; + u64 old_base = 0, rc, bar_region_base = region->region_base; void __iomem *acc_addr; if (set_dram_bar) { - old_base = hl_set_dram_bar(hdev, addr, region, &new_bar_region_base); + old_base = hl_set_dram_bar(hdev, addr, region, &bar_region_base); if (old_base == U64_MAX) return -EIO; } acc_addr = hdev->pcie_bar[region->bar_id] + region->offset_in_bar + - (addr - new_bar_region_base); + (addr - bar_region_base); switch (acc_type) { case DEBUGFS_READ8: -- GitLab From bdfef91e7c9c2bae083ce1965f53115d88329773 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Wed, 19 Oct 2022 14:05:18 +0300 Subject: [PATCH 0726/1480] habanalabs: add warning print upon a PCI error In order to know if driver catches PCI errors correctly, we need to print a warning per each error. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs_drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index 714994725224f..e82af89897009 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -595,15 +595,16 @@ hl_pci_err_detected(struct pci_dev *pdev, pci_channel_state_t state) switch (state) { case pci_channel_io_normal: + dev_warn(hdev->dev, "PCI normal state error detected\n"); return PCI_ERS_RESULT_CAN_RECOVER; case pci_channel_io_frozen: - dev_warn(hdev->dev, "frozen state error detected\n"); + dev_warn(hdev->dev, "PCI frozen state error detected\n"); result = PCI_ERS_RESULT_NEED_RESET; break; case pci_channel_io_perm_failure: - dev_warn(hdev->dev, "failure state error detected\n"); + dev_warn(hdev->dev, "PCI failure state error detected\n"); result = PCI_ERS_RESULT_DISCONNECT; break; @@ -639,6 +640,10 @@ static void hl_pci_err_resume(struct pci_dev *pdev) */ static pci_ers_result_t hl_pci_err_slot_reset(struct pci_dev *pdev) { + struct hl_device *hdev = pci_get_drvdata(pdev); + + dev_warn(hdev->dev, "PCI slot reset detected\n"); + return PCI_ERS_RESULT_RECOVERED; } -- GitLab From 306206985a4bcfc12b45596d56c7bd8ba6f0f6b1 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Wed, 26 Oct 2022 18:20:49 +0300 Subject: [PATCH 0727/1480] habanalabs: remove redundant gaudi2_sec asic type As Gaudi2 has a single PCI id, the secured asic type is redundant. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 3 --- drivers/misc/habanalabs/common/habanalabs.h | 2 -- drivers/misc/habanalabs/common/mmu/mmu.c | 1 - drivers/misc/habanalabs/common/sysfs.c | 2 -- drivers/misc/habanalabs/gaudi2/gaudi2.c | 2 +- 5 files changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index cb8ecc17bba14..3ea1ee1ec8ef3 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -748,9 +748,6 @@ static int device_early_init(struct hl_device *hdev) gaudi2_set_asic_funcs(hdev); strscpy(hdev->asic_name, "GAUDI2", sizeof(hdev->asic_name)); break; - case ASIC_GAUDI2_SEC: - gaudi2_set_asic_funcs(hdev); - strscpy(hdev->asic_name, "GAUDI2 SEC", sizeof(hdev->asic_name)); break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index bfaaa9daa7501..7d191f388953f 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -1192,7 +1192,6 @@ struct hl_dec { * @ASIC_GAUDI: Gaudi device (HL-2000). * @ASIC_GAUDI_SEC: Gaudi secured device (HL-2000). * @ASIC_GAUDI2: Gaudi2 device. - * @ASIC_GAUDI2_SEC: Gaudi2 secured device. */ enum hl_asic_type { ASIC_INVALID, @@ -1200,7 +1199,6 @@ enum hl_asic_type { ASIC_GAUDI, ASIC_GAUDI_SEC, ASIC_GAUDI2, - ASIC_GAUDI2_SEC, }; struct hl_cs_parser; diff --git a/drivers/misc/habanalabs/common/mmu/mmu.c b/drivers/misc/habanalabs/common/mmu/mmu.c index 589179f8cd41b..67d3e70cf5714 100644 --- a/drivers/misc/habanalabs/common/mmu/mmu.c +++ b/drivers/misc/habanalabs/common/mmu/mmu.c @@ -635,7 +635,6 @@ int hl_mmu_if_set_funcs(struct hl_device *hdev) hl_mmu_v1_set_funcs(hdev, &hdev->mmu_func[MMU_DR_PGT]); break; case ASIC_GAUDI2: - case ASIC_GAUDI2_SEC: /* MMUs in Gaudi2 are always host resident */ hl_mmu_v2_hr_set_funcs(hdev, &hdev->mmu_func[MMU_HR_PGT]); break; diff --git a/drivers/misc/habanalabs/common/sysfs.c b/drivers/misc/habanalabs/common/sysfs.c index 36e9814139d17..c924fc994bd96 100644 --- a/drivers/misc/habanalabs/common/sysfs.c +++ b/drivers/misc/habanalabs/common/sysfs.c @@ -248,8 +248,6 @@ static ssize_t device_type_show(struct device *dev, case ASIC_GAUDI2: str = "GAUDI2"; break; - case ASIC_GAUDI2_SEC: - str = "GAUDI2 SEC"; break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 22f5445fe71c2..03f8cf9bb136d 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -3969,7 +3969,7 @@ static void gaudi2_init_firmware_loader(struct hl_device *hdev) fw_loader->sram_bar_id = SRAM_CFG_BAR_ID; fw_loader->dram_bar_id = DRAM_BAR_ID; - if (hdev->asic_type == ASIC_GAUDI2 || hdev->asic_type == ASIC_GAUDI2_SEC) + if (hdev->asic_type == ASIC_GAUDI2) fw_loader->cpu_timeout = GAUDI2_CPU_TIMEOUT_USEC; else /* ASIC_GAUDI2_FPGA */ fw_loader->cpu_timeout = GAUDI2_FPGA_CPU_TIMEOUT; -- GitLab From 841cd2d7658d92e09354640c1887797f0da3d444 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Wed, 26 Oct 2022 16:20:45 +0300 Subject: [PATCH 0728/1480] habanalabs/gaudi2: add PCI revision 2 support Add support for Gaudi2 Device with PCI revision 2. Functionality is exactly the same as revision 1, the only difference is device name exposed to user. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 4 +++ drivers/misc/habanalabs/common/habanalabs.h | 2 ++ .../misc/habanalabs/common/habanalabs_drv.c | 26 +++++++++++++------ .../misc/habanalabs/common/habanalabs_ioctl.c | 6 +++-- drivers/misc/habanalabs/common/mmu/mmu.c | 1 + drivers/misc/habanalabs/common/sysfs.c | 2 ++ drivers/misc/habanalabs/gaudi2/gaudi2.c | 6 +---- drivers/misc/habanalabs/gaudi2/gaudi2P.h | 2 -- .../include/hw_ip/pci/pci_general.h | 7 +++++ include/uapi/misc/habanalabs.h | 7 +++++ 10 files changed, 46 insertions(+), 17 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 3ea1ee1ec8ef3..35ed494fcfdf0 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -748,6 +748,10 @@ static int device_early_init(struct hl_device *hdev) gaudi2_set_asic_funcs(hdev); strscpy(hdev->asic_name, "GAUDI2", sizeof(hdev->asic_name)); break; + case ASIC_GAUDI2B: + gaudi2_set_asic_funcs(hdev); + strscpy(hdev->asic_name, "GAUDI2B", sizeof(hdev->asic_name)); + break; break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 7d191f388953f..e391e7951fb75 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -1192,6 +1192,7 @@ struct hl_dec { * @ASIC_GAUDI: Gaudi device (HL-2000). * @ASIC_GAUDI_SEC: Gaudi secured device (HL-2000). * @ASIC_GAUDI2: Gaudi2 device. + * @ASIC_GAUDI2B: Gaudi2B device. */ enum hl_asic_type { ASIC_INVALID, @@ -1199,6 +1200,7 @@ enum hl_asic_type { ASIC_GAUDI, ASIC_GAUDI_SEC, ASIC_GAUDI2, + ASIC_GAUDI2B, }; struct hl_cs_parser; diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index e82af89897009..7815c60df54e2 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -9,6 +9,7 @@ #define pr_fmt(fmt) "habanalabs: " fmt #include "habanalabs.h" +#include "../include/hw_ip/pci/pci_general.h" #include #include @@ -74,16 +75,17 @@ MODULE_DEVICE_TABLE(pci, ids); /* * get_asic_type - translate device id to asic type * - * @device: id of the PCI device + * @hdev: pointer to habanalabs device structure. * - * Translate device id to asic type. + * Translate device id and revision id to asic type. * In case of unidentified device, return -1 */ -static enum hl_asic_type get_asic_type(u16 device) +static enum hl_asic_type get_asic_type(struct hl_device *hdev) { - enum hl_asic_type asic_type; + struct pci_dev *pdev = hdev->pdev; + enum hl_asic_type asic_type = ASIC_INVALID; - switch (device) { + switch (pdev->device) { case PCI_IDS_GOYA: asic_type = ASIC_GOYA; break; @@ -94,10 +96,18 @@ static enum hl_asic_type get_asic_type(u16 device) asic_type = ASIC_GAUDI_SEC; break; case PCI_IDS_GAUDI2: - asic_type = ASIC_GAUDI2; + switch (pdev->revision) { + case REV_ID_A: + asic_type = ASIC_GAUDI2; + break; + case REV_ID_B: + asic_type = ASIC_GAUDI2B; + break; + default: + break; + } break; default: - asic_type = ASIC_INVALID; break; } @@ -416,7 +426,7 @@ static int create_hdev(struct hl_device **dev, struct pci_dev *pdev) /* First, we must find out which ASIC are we handling. This is needed * to configure the behavior of the driver (kernel parameters) */ - hdev->asic_type = get_asic_type(pdev->device); + hdev->asic_type = get_asic_type(hdev); if (hdev->asic_type == ASIC_INVALID) { dev_err(&pdev->dev, "Unsupported ASIC\n"); rc = -ENODEV; diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 5ce5c42e27313..ee43017eb5636 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -10,10 +10,11 @@ #include #include "habanalabs.h" -#include #include -#include +#include +#include #include +#include #include static u32 hl_debug_struct_size[HL_DEBUG_OP_TIMESTAMP + 1] = { @@ -105,6 +106,7 @@ static int hw_ip_info(struct hl_device *hdev, struct hl_info_args *args) hw_ip.edma_enabled_mask = prop->edma_enabled_mask; hw_ip.server_type = prop->server_type; hw_ip.security_enabled = prop->fw_security_enabled; + hw_ip.revision_id = hdev->pdev->revision; return copy_to_user(out, &hw_ip, min((size_t) size, sizeof(hw_ip))) ? -EFAULT : 0; diff --git a/drivers/misc/habanalabs/common/mmu/mmu.c b/drivers/misc/habanalabs/common/mmu/mmu.c index 67d3e70cf5714..2c1005f74cf44 100644 --- a/drivers/misc/habanalabs/common/mmu/mmu.c +++ b/drivers/misc/habanalabs/common/mmu/mmu.c @@ -635,6 +635,7 @@ int hl_mmu_if_set_funcs(struct hl_device *hdev) hl_mmu_v1_set_funcs(hdev, &hdev->mmu_func[MMU_DR_PGT]); break; case ASIC_GAUDI2: + case ASIC_GAUDI2B: /* MMUs in Gaudi2 are always host resident */ hl_mmu_v2_hr_set_funcs(hdev, &hdev->mmu_func[MMU_HR_PGT]); break; diff --git a/drivers/misc/habanalabs/common/sysfs.c b/drivers/misc/habanalabs/common/sysfs.c index c924fc994bd96..735d8bed00660 100644 --- a/drivers/misc/habanalabs/common/sysfs.c +++ b/drivers/misc/habanalabs/common/sysfs.c @@ -248,6 +248,8 @@ static ssize_t device_type_show(struct device *dev, case ASIC_GAUDI2: str = "GAUDI2"; break; + case ASIC_GAUDI2B: + str = "GAUDI2B"; break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 03f8cf9bb136d..f21b68be6d207 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -3968,11 +3968,7 @@ static void gaudi2_init_firmware_loader(struct hl_device *hdev) fw_loader->skip_bmc = false; fw_loader->sram_bar_id = SRAM_CFG_BAR_ID; fw_loader->dram_bar_id = DRAM_BAR_ID; - - if (hdev->asic_type == ASIC_GAUDI2) - fw_loader->cpu_timeout = GAUDI2_CPU_TIMEOUT_USEC; - else /* ASIC_GAUDI2_FPGA */ - fw_loader->cpu_timeout = GAUDI2_FPGA_CPU_TIMEOUT; + fw_loader->cpu_timeout = GAUDI2_CPU_TIMEOUT_USEC; /* here we update initial values for few specific dynamic regs (as * before reading the first descriptor from FW those value has to be diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2P.h b/drivers/misc/habanalabs/gaudi2/gaudi2P.h index a99c348bbf390..b4383c199bbba 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2P.h +++ b/drivers/misc/habanalabs/gaudi2/gaudi2P.h @@ -23,8 +23,6 @@ #define GAUDI2_CPU_TIMEOUT_USEC 30000000 /* 30s */ -#define GAUDI2_FPGA_CPU_TIMEOUT 100000000 /* 100s */ - #define NUMBER_OF_PDMA_QUEUES 2 #define NUMBER_OF_EDMA_QUEUES 8 #define NUMBER_OF_MME_QUEUES 4 diff --git a/drivers/misc/habanalabs/include/hw_ip/pci/pci_general.h b/drivers/misc/habanalabs/include/hw_ip/pci/pci_general.h index d232081d4e0f7..f5d497dc9bdc1 100644 --- a/drivers/misc/habanalabs/include/hw_ip/pci/pci_general.h +++ b/drivers/misc/habanalabs/include/hw_ip/pci/pci_general.h @@ -20,4 +20,11 @@ #define PCI_CONFIG_ELBI_STS_MASK (PCI_CONFIG_ELBI_STS_ERR | \ PCI_CONFIG_ELBI_STS_DONE) +enum hl_revision_id { + /* PCI revision ID 0 is not legal */ + REV_ID_INVALID = 0x00, + REV_ID_A = 0x01, + REV_ID_B = 0x02, +}; + #endif /* INCLUDE_PCI_GENERAL_H_ */ diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index a4ceee6818986..58343998bd638 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -868,6 +868,7 @@ enum hl_server_type { * @number_of_user_interrupts: The number of interrupts that are available to the userspace * application to use. Relevant for Gaudi2 and later. * @device_mem_alloc_default_page_size: default page size used in device memory allocation. + * @revision_id: PCI revision ID of the ASIC. */ struct hl_info_hw_ip_info { __u64 sram_base_address; @@ -898,6 +899,12 @@ struct hl_info_hw_ip_info { __u16 pad2; __u64 reserved4; __u64 device_mem_alloc_default_page_size; + __u64 reserved5; + __u64 reserved6; + __u32 reserved7; + __u8 reserved8; + __u8 revision_id; + __u8 pad[2]; }; struct hl_info_dram_usage { -- GitLab From cb5fb665f30388cf8cb9becae86dcb84ace0ca88 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Sun, 30 Oct 2022 13:08:37 +0200 Subject: [PATCH 0729/1480] habanalabs/gaudi: add razwi notify event Each time razwi (read-only zero, write ignore) happens, besides capturing its data, also notify the user about it. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 8 +++++ drivers/misc/habanalabs/common/habanalabs.h | 2 ++ drivers/misc/habanalabs/gaudi/gaudi.c | 37 +++++++++++---------- include/uapi/misc/habanalabs.h | 2 ++ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 35ed494fcfdf0..d1a6095895584 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2409,6 +2409,14 @@ void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_ num_of_engines * sizeof(u16)); hdev->captured_err_info.razwi.flags = flags; } + +void hl_handle_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, + u8 flags, u64 *event_mask) +{ + hl_capture_razwi(hdev, addr, engine_id, num_of_engines, flags); + *event_mask |= HL_NOTIFIER_EVENT_RAZWI; +} + static void hl_capture_user_mappings(struct hl_device *hdev, bool is_pmmu) { struct page_fault_info *pgf_info = &hdev->captured_err_info.pgf_info; diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index e391e7951fb75..d9335f3769b87 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -3812,6 +3812,8 @@ hl_mmap_mem_buf_alloc(struct hl_mem_mgr *mmg, __printf(2, 3) void hl_engine_data_sprintf(struct engines_data *e, const char *fmt, ...); void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, u8 flags); +void hl_handle_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, + u8 flags, u64 *event_mask); void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 3dfb9ecf7db37..035865cb097c4 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7301,7 +7301,7 @@ static void gaudi_handle_qman_err(struct hl_device *hdev, u16 event_type, u64 *e } static void gaudi_print_irq_info(struct hl_device *hdev, u16 event_type, - bool razwi) + bool razwi, u64 *event_mask) { bool is_read = false, is_write = false; u16 engine_id[2], num_of_razwi_eng = 0; @@ -7337,7 +7337,8 @@ static void gaudi_print_irq_info(struct hl_device *hdev, u16 event_type, num_of_razwi_eng = 1; } - hl_capture_razwi(hdev, razwi_addr, engine_id, num_of_razwi_eng, razwi_flags); + hl_handle_razwi(hdev, razwi_addr, engine_id, num_of_razwi_eng, razwi_flags, + event_mask); } } @@ -7675,7 +7676,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_HBM_0_DERR ... GAUDI_EVENT_HBM_3_DERR: case GAUDI_EVENT_MMU_DERR: case GAUDI_EVENT_NIC0_CS_DBG_DERR ... GAUDI_EVENT_NIC4_CS_DBG_DERR: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); gaudi_handle_ecc_event(hdev, event_type, &eq_entry->ecc_data); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; fw_fatal_err_flag = HL_DRV_RESET_FW_FATAL_ERR; @@ -7685,7 +7686,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_AXI_ECC: case GAUDI_EVENT_L2_RAM_ECC: case GAUDI_EVENT_PLL0 ... GAUDI_EVENT_PLL17: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); fw_fatal_err_flag = HL_DRV_RESET_FW_FATAL_ERR; event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; goto reset_device; @@ -7694,7 +7695,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_HBM1_SPI_0: case GAUDI_EVENT_HBM2_SPI_0: case GAUDI_EVENT_HBM3_SPI_0: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); gaudi_hbm_read_interrupts(hdev, gaudi_hbm_event_to_dev(event_type), &eq_entry->hbm_ecc_data); @@ -7706,7 +7707,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_HBM1_SPI_1: case GAUDI_EVENT_HBM2_SPI_1: case GAUDI_EVENT_HBM3_SPI_1: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); gaudi_hbm_read_interrupts(hdev, gaudi_hbm_event_to_dev(event_type), &eq_entry->hbm_ecc_data); @@ -7728,7 +7729,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr * if the event is a TPC Assertion or a "real" TPC DEC. */ event_mask |= HL_NOTIFIER_EVENT_TPC_ASSERT; - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); reset_required = gaudi_tpc_read_interrupts(hdev, tpc_dec_event_to_tpc_id(event_type), "AXI_SLV_DEC_Error"); @@ -7753,7 +7754,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_TPC5_KRN_ERR: case GAUDI_EVENT_TPC6_KRN_ERR: case GAUDI_EVENT_TPC7_KRN_ERR: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); reset_required = gaudi_tpc_read_interrupts(hdev, tpc_krn_event_to_tpc_id(event_type), "KRN_ERR"); @@ -7792,7 +7793,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_HBM_0_SERR ... GAUDI_EVENT_HBM_3_SERR: fallthrough; case GAUDI_EVENT_MMU_SERR: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); gaudi_handle_ecc_event(hdev, event_type, &eq_entry->ecc_data); hl_fw_unmask_irq(hdev, event_type); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; @@ -7802,14 +7803,14 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_CPU_AXI_SPLITTER: case GAUDI_EVENT_PSOC_AXI_DEC: case GAUDI_EVENT_PSOC_PRSTN_FALL: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); hl_fw_unmask_irq(hdev, event_type); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; break; case GAUDI_EVENT_MMU_PAGE_FAULT: case GAUDI_EVENT_MMU_WR_PERM: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); hl_fw_unmask_irq(hdev, event_type); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -7838,14 +7839,14 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_NIC4_QM1: case GAUDI_EVENT_DMA0_CORE ... GAUDI_EVENT_DMA7_CORE: case GAUDI_EVENT_TPC0_QM ... GAUDI_EVENT_TPC7_QM: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); gaudi_handle_qman_err(hdev, event_type, &event_mask); hl_fw_unmask_irq(hdev, event_type); event_mask |= (HL_NOTIFIER_EVENT_USER_ENGINE_ERR | HL_NOTIFIER_EVENT_DEVICE_RESET); break; case GAUDI_EVENT_RAZWI_OR_ADC_SW: - gaudi_print_irq_info(hdev, event_type, true); + gaudi_print_irq_info(hdev, event_type, true, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; goto reset_device; @@ -7858,7 +7859,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr case GAUDI_EVENT_TPC6_BMON_SPMU: case GAUDI_EVENT_TPC7_BMON_SPMU: case GAUDI_EVENT_DMA_BM_CH0 ... GAUDI_EVENT_DMA_BM_CH7: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); hl_fw_unmask_irq(hdev, event_type); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -7870,7 +7871,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr break; case GAUDI_EVENT_DMA_IF_SEI_0 ... GAUDI_EVENT_DMA_IF_SEI_3: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); gaudi_print_sm_sei_info(hdev, event_type, &eq_entry->sm_sei_data); rc = hl_state_dump(hdev); @@ -7899,18 +7900,18 @@ static void gaudi_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entr break; case GAUDI_EVENT_DEV_RESET_REQ: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; goto reset_device; case GAUDI_EVENT_PKT_QUEUE_OUT_SYNC: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); gaudi_print_out_of_sync_info(hdev, &eq_entry->pkt_sync_err); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; goto reset_device; case GAUDI_EVENT_FW_ALIVE_S: - gaudi_print_irq_info(hdev, event_type, false); + gaudi_print_irq_info(hdev, event_type, false, &event_mask); gaudi_print_fw_alive_info(hdev, &eq_entry->fw_alive); event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; goto reset_device; diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index 58343998bd638..7747e19e81fe0 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -721,6 +721,7 @@ enum hl_server_type { * HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE - Indicates device is unavailable * HL_NOTIFIER_EVENT_USER_ENGINE_ERR - Indicates device engine in error state * HL_NOTIFIER_EVENT_GENERAL_HW_ERR - Indicates device HW error + * HL_NOTIFIER_EVENT_RAZWI - Indicates razwi happened */ #define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0) #define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1) @@ -729,6 +730,7 @@ enum hl_server_type { #define HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE (1ULL << 4) #define HL_NOTIFIER_EVENT_USER_ENGINE_ERR (1ULL << 5) #define HL_NOTIFIER_EVENT_GENERAL_HW_ERR (1ULL << 6) +#define HL_NOTIFIER_EVENT_RAZWI (1ULL << 7) /* Opcode for management ioctl * -- GitLab From cd21701cde33123fc53c6401192219ba14832da3 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Thu, 27 Oct 2022 20:38:26 +0300 Subject: [PATCH 0730/1480] habanalabs: use single threaded WQ for event handling Creating event queue workqueue using alloc_workqueue made it run in multi threaded mode, which caused parallel dumping of events as well as parallel events notifying to user, causing logs with multiple events to be out of order. Fixed by creating event queue workqueue as single threaded work queue. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index d1a6095895584..65bb40f81901e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -787,7 +787,7 @@ static int device_early_init(struct hl_device *hdev) } } - hdev->eq_wq = alloc_workqueue("hl-events", WQ_UNBOUND, 0); + hdev->eq_wq = create_singlethread_workqueue("hl-events"); if (hdev->eq_wq == NULL) { dev_err(hdev->dev, "Failed to allocate EQ workqueue\n"); rc = -ENOMEM; -- GitLab From aff6354afd1f9eae1e10658c157c26e316806f56 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Mon, 31 Oct 2022 11:44:45 +0200 Subject: [PATCH 0731/1480] habanalabs/gaudi: add page fault notify event Each time page fault happens, besides capturing its data, also notify the user about it. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 9 +++++++++ drivers/misc/habanalabs/common/habanalabs.h | 2 ++ drivers/misc/habanalabs/gaudi/gaudi.c | 6 +++--- include/uapi/misc/habanalabs.h | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 65bb40f81901e..31818121ef4de 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2490,3 +2490,12 @@ void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is hdev->captured_err_info.pgf_info.pgf.engine_id = eng_id; hl_capture_user_mappings(hdev, is_pmmu); } + +void hl_handle_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu, + u64 *event_mask) +{ + hl_capture_page_fault(hdev, addr, eng_id, is_pmmu); + + if (event_mask) + *event_mask |= HL_NOTIFIER_EVENT_PAGE_FAULT; +} diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index d9335f3769b87..0781b8698f744 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -3815,6 +3815,8 @@ void hl_capture_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_ void hl_handle_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_of_engines, u8 flags, u64 *event_mask); void hl_capture_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu); +void hl_handle_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_pmmu, + u64 *event_mask); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 035865cb097c4..cbe1daf5a7939 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -6740,7 +6740,7 @@ static void gaudi_print_and_get_razwi_info(struct hl_device *hdev, u16 *engine_i } } -static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr) +static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr, u64 *event_mask) { struct gaudi_device *gaudi = hdev->asic_specific; u32 val; @@ -6755,7 +6755,7 @@ static void gaudi_print_and_get_mmu_error_info(struct hl_device *hdev, u64 *addr *addr |= RREG32(mmMMU_UP_PAGE_ERROR_CAPTURE_VA); dev_err_ratelimited(hdev->dev, "MMU page fault on va 0x%llx\n", *addr); - hl_capture_page_fault(hdev, *addr, 0, true); + hl_handle_page_fault(hdev, *addr, 0, true, event_mask); WREG32(mmMMU_UP_PAGE_ERROR_CAPTURE, 0); } @@ -7323,7 +7323,7 @@ static void gaudi_print_irq_info(struct hl_device *hdev, u16 event_type, if (razwi) { gaudi_print_and_get_razwi_info(hdev, &engine_id[0], &engine_id[1], &is_read, &is_write); - gaudi_print_and_get_mmu_error_info(hdev, &razwi_addr); + gaudi_print_and_get_mmu_error_info(hdev, &razwi_addr, event_mask); if (is_read) razwi_flags |= HL_RAZWI_READ; diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index 7747e19e81fe0..e50cb71df081c 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -722,6 +722,7 @@ enum hl_server_type { * HL_NOTIFIER_EVENT_USER_ENGINE_ERR - Indicates device engine in error state * HL_NOTIFIER_EVENT_GENERAL_HW_ERR - Indicates device HW error * HL_NOTIFIER_EVENT_RAZWI - Indicates razwi happened + * HL_NOTIFIER_EVENT_PAGE_FAULT - Indicates page fault happened */ #define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0) #define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1) @@ -731,6 +732,7 @@ enum hl_server_type { #define HL_NOTIFIER_EVENT_USER_ENGINE_ERR (1ULL << 5) #define HL_NOTIFIER_EVENT_GENERAL_HW_ERR (1ULL << 6) #define HL_NOTIFIER_EVENT_RAZWI (1ULL << 7) +#define HL_NOTIFIER_EVENT_PAGE_FAULT (1ULL << 8) /* Opcode for management ioctl * -- GitLab From 91bd822448e57a55d12dc0461909b5c585485a6c Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Sun, 30 Oct 2022 15:10:13 +0200 Subject: [PATCH 0732/1480] habanalabs/gaudi2: implement fp32 not supported event Due to binning, Gaudi2 does not always support fp32. We add support for such an event in case fp32 is used by the user in such a device. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 5 +++++ drivers/misc/habanalabs/include/gaudi2/gaudi2_async_events.h | 1 + .../include/gaudi2/gaudi2_async_ids_map_extended.h | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index f21b68be6d207..77bdbab41e6c1 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -9148,6 +9148,11 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; + case GAUDI2_EVENT_CPU_FP32_NOT_SUPPORTED: + event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; + is_critical = true; + break; + default: if (gaudi2_irq_map_table[event_type].valid) dev_err_ratelimited(hdev->dev, "Cannot find handler for event %d\n", diff --git a/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_events.h b/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_events.h index 34406770a76a6..305b576222e6f 100644 --- a/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_events.h +++ b/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_events.h @@ -957,6 +957,7 @@ enum gaudi2_async_event_id { GAUDI2_EVENT_CPU11_STATUS_NIC11_ENG0 = 1317, GAUDI2_EVENT_CPU11_STATUS_NIC11_ENG1 = 1318, GAUDI2_EVENT_ARC_DCCM_FULL = 1319, + GAUDI2_EVENT_CPU_FP32_NOT_SUPPORTED = 1320, GAUDI2_EVENT_SIZE, }; diff --git a/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_ids_map_extended.h b/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_ids_map_extended.h index 5bd4383c9f2cf..d510cb10c8831 100644 --- a/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_ids_map_extended.h +++ b/drivers/misc/habanalabs/include/gaudi2/gaudi2_async_ids_map_extended.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 * - * Copyright 2018-2021 HabanaLabs, Ltd. + * Copyright 2018-2022 HabanaLabs, Ltd. * All Rights Reserved. * */ @@ -2663,6 +2663,8 @@ static struct gaudi2_async_events_ids_map gaudi2_irq_map_table[] = { .msg = 1, .reset = 0, .name = "STATUS_NIC11_ENG1" }, { .fc_id = 1319, .cpu_id = 625, .valid = 1, .msg = 1, .reset = 0, .name = "ARC_DCCM_FULL" }, + { .fc_id = 1320, .cpu_id = 626, .valid = 1, + .msg = 1, .reset = 1, .name = "FP32_NOT_SUPPORTED" }, }; #endif /* __GAUDI2_ASYNC_IDS_MAP_EVENTS_EXT_H_ */ -- GitLab From 413bdb176eaa7d02c979a3c738738aea91fe6ed7 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Sun, 30 Oct 2022 14:46:19 +0200 Subject: [PATCH 0733/1480] habanalabs/gaudi2: add razwi notify event Each time razwi (read-only zero, write ignored) event happens, besides capturing its data, also notify the user about it. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 4 +- drivers/misc/habanalabs/gaudi2/gaudi2.c | 140 +++++++++++++----------- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 31818121ef4de..708db0f48ee0e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2414,7 +2414,9 @@ void hl_handle_razwi(struct hl_device *hdev, u64 addr, u16 *engine_id, u16 num_o u8 flags, u64 *event_mask) { hl_capture_razwi(hdev, addr, engine_id, num_of_engines, flags); - *event_mask |= HL_NOTIFIER_EVENT_RAZWI; + + if (event_mask) + *event_mask |= HL_NOTIFIER_EVENT_RAZWI; } static void hl_capture_user_mappings(struct hl_device *hdev, bool is_pmmu) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 77bdbab41e6c1..59940c8df2d20 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -7063,7 +7063,7 @@ static void gaudi2_handle_qman_err_generic(struct hl_device *hdev, const char *q static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, u64 rtr_mstr_if_base_addr, bool is_write, char *name, bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info, - enum gaudi2_engine_id id) + enum gaudi2_engine_id id, u64 *event_mask) { u32 razwi_hi, razwi_lo, razwi_xy; u16 eng_id = id; @@ -7093,8 +7093,8 @@ static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, rd_wr_flag = HL_RAZWI_READ; } - hl_capture_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &eng_id, 1, - rd_wr_flag | HL_RAZWI_HBW); + hl_handle_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &eng_id, 1, + rd_wr_flag | HL_RAZWI_HBW, event_mask); dev_err_ratelimited(hdev->dev, "%s-RAZWI SHARED RR HBW %s error, address %#llx, Initiator coordinates 0x%x\n", @@ -7104,7 +7104,7 @@ static void gaudi2_razwi_rr_hbw_shared_printf_info(struct hl_device *hdev, static void gaudi2_razwi_rr_lbw_shared_printf_info(struct hl_device *hdev, u64 rtr_mstr_if_base_addr, bool is_write, char *name, bool read_razwi_regs, struct hl_eq_razwi_info *razwi_info, - enum gaudi2_engine_id id) + enum gaudi2_engine_id id, u64 *event_mask) { u32 razwi_addr, razwi_xy; u16 eng_id = id; @@ -7132,7 +7132,7 @@ static void gaudi2_razwi_rr_lbw_shared_printf_info(struct hl_device *hdev, rd_wr_flag = HL_RAZWI_READ; } - hl_capture_razwi(hdev, razwi_addr, &eng_id, 1, rd_wr_flag | HL_RAZWI_LBW); + hl_handle_razwi(hdev, razwi_addr, &eng_id, 1, rd_wr_flag | HL_RAZWI_LBW, event_mask); dev_err_ratelimited(hdev->dev, "%s-RAZWI SHARED RR LBW %s error, mstr_if 0x%llx, captured address 0x%x Initiator coordinates 0x%x\n", name, is_write ? "WR" : "RD", rtr_mstr_if_base_addr, razwi_addr, @@ -7189,7 +7189,8 @@ static enum gaudi2_engine_id gaudi2_razwi_calc_engine_id(struct hl_device *hdev, */ static void gaudi2_ack_module_razwi_event_handler(struct hl_device *hdev, enum razwi_event_sources module, u8 module_idx, - u8 module_sub_idx, struct hl_eq_razwi_info *razwi_info) + u8 module_sub_idx, struct hl_eq_razwi_info *razwi_info, + u64 *event_mask) { bool via_sft = false, read_razwi_regs = false; u32 rtr_id, dcore_id, dcore_rtr_id, sft_id, eng_id; @@ -7330,7 +7331,7 @@ dump_info: if (hbw_shrd_aw) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, true, initiator_name, read_razwi_regs, razwi_info, - eng_id); + eng_id, event_mask); /* Clear event indication */ if (read_razwi_regs) @@ -7340,7 +7341,7 @@ dump_info: if (hbw_shrd_ar) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, false, initiator_name, read_razwi_regs, razwi_info, - eng_id); + eng_id, event_mask); /* Clear event indication */ if (read_razwi_regs) @@ -7350,7 +7351,7 @@ dump_info: if (lbw_shrd_aw) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, true, initiator_name, read_razwi_regs, razwi_info, - eng_id); + eng_id, event_mask); /* Clear event indication */ if (read_razwi_regs) @@ -7360,7 +7361,7 @@ dump_info: if (lbw_shrd_ar) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, rtr_mstr_if_base_addr, false, initiator_name, read_razwi_regs, razwi_info, - eng_id); + eng_id, event_mask); /* Clear event indication */ if (read_razwi_regs) @@ -7376,38 +7377,42 @@ static void gaudi2_check_if_razwi_happened(struct hl_device *hdev) /* check all TPCs */ for (mod_idx = 0 ; mod_idx < (NUM_OF_TPC_PER_DCORE * NUM_OF_DCORES + 1) ; mod_idx++) { if (prop->tpc_enabled_mask & BIT(mod_idx)) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_TPC, mod_idx, 0, NULL); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_TPC, mod_idx, 0, NULL, + NULL); } /* check all MMEs */ for (mod_idx = 0 ; mod_idx < (NUM_OF_MME_PER_DCORE * NUM_OF_DCORES) ; mod_idx++) for (sub_mod = MME_WAP0 ; sub_mod < MME_INITIATORS_MAX ; sub_mod++) gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mod_idx, - sub_mod, NULL); + sub_mod, NULL, NULL); /* check all EDMAs */ for (mod_idx = 0 ; mod_idx < (NUM_OF_EDMA_PER_DCORE * NUM_OF_DCORES) ; mod_idx++) if (prop->edma_enabled_mask & BIT(mod_idx)) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_EDMA, mod_idx, 0, NULL); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_EDMA, mod_idx, 0, NULL, + NULL); /* check all PDMAs */ for (mod_idx = 0 ; mod_idx < NUM_OF_PDMA ; mod_idx++) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_PDMA, mod_idx, 0, NULL); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_PDMA, mod_idx, 0, NULL, + NULL); /* check all NICs */ for (mod_idx = 0 ; mod_idx < NIC_NUMBER_OF_PORTS ; mod_idx++) if (hdev->nic_ports_mask & BIT(mod_idx)) gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_NIC, mod_idx >> 1, 0, - NULL); + NULL, NULL); /* check all DECs */ for (mod_idx = 0 ; mod_idx < NUMBER_OF_DEC ; mod_idx++) if (prop->decoder_enabled_mask & BIT(mod_idx)) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_DEC, mod_idx, 0, NULL); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_DEC, mod_idx, 0, NULL, + NULL); /* check all ROTs */ for (mod_idx = 0 ; mod_idx < NUM_OF_ROT ; mod_idx++) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_ROT, mod_idx, 0, NULL); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_ROT, mod_idx, 0, NULL, NULL); } static const char *gaudi2_get_initiators_name(u32 rtr_id) @@ -7625,7 +7630,8 @@ static u16 gaudi2_get_razwi_initiators(u32 rtr_id, u16 *engines) } static void gaudi2_razwi_unmapped_addr_hbw_printf_info(struct hl_device *hdev, u32 rtr_id, - u64 rtr_ctrl_base_addr, bool is_write) + u64 rtr_ctrl_base_addr, bool is_write, + u64 *event_mask) { u16 engines[HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR], num_of_eng; u32 razwi_hi, razwi_lo; @@ -7649,8 +7655,8 @@ static void gaudi2_razwi_unmapped_addr_hbw_printf_info(struct hl_device *hdev, u WREG32(rtr_ctrl_base_addr + DEC_RAZWI_HBW_AR_SET, 0x1); } - hl_capture_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &engines[0], num_of_eng, - rd_wr_flag | HL_RAZWI_HBW); + hl_handle_razwi(hdev, (u64)razwi_hi << 32 | razwi_lo, &engines[0], num_of_eng, + rd_wr_flag | HL_RAZWI_HBW, event_mask); dev_err_ratelimited(hdev->dev, "RAZWI PSOC unmapped HBW %s error, rtr id %u, address %#llx\n", is_write ? "WR" : "RD", rtr_id, (u64)razwi_hi << 32 | razwi_lo); @@ -7660,7 +7666,8 @@ static void gaudi2_razwi_unmapped_addr_hbw_printf_info(struct hl_device *hdev, u } static void gaudi2_razwi_unmapped_addr_lbw_printf_info(struct hl_device *hdev, u32 rtr_id, - u64 rtr_ctrl_base_addr, bool is_write) + u64 rtr_ctrl_base_addr, bool is_write, + u64 *event_mask) { u16 engines[HL_RAZWI_MAX_NUM_OF_ENGINES_PER_RTR], num_of_eng; u32 razwi_addr; @@ -7682,7 +7689,8 @@ static void gaudi2_razwi_unmapped_addr_lbw_printf_info(struct hl_device *hdev, u WREG32(rtr_ctrl_base_addr + DEC_RAZWI_LBW_AR_SET, 0x1); } - hl_capture_razwi(hdev, razwi_addr, &engines[0], num_of_eng, rd_wr_flag | HL_RAZWI_LBW); + hl_handle_razwi(hdev, razwi_addr, &engines[0], num_of_eng, rd_wr_flag | HL_RAZWI_LBW, + event_mask); dev_err_ratelimited(hdev->dev, "RAZWI PSOC unmapped LBW %s error, rtr id %u, address %#x\n", is_write ? "WR" : "RD", rtr_id, razwi_addr); @@ -7692,7 +7700,7 @@ static void gaudi2_razwi_unmapped_addr_lbw_printf_info(struct hl_device *hdev, u } /* PSOC RAZWI interrupt occurs only when trying to access a bad address */ -static void gaudi2_ack_psoc_razwi_event_handler(struct hl_device *hdev) +static void gaudi2_ack_psoc_razwi_event_handler(struct hl_device *hdev, u64 *event_mask) { u32 hbw_aw_set, hbw_ar_set, lbw_aw_set, lbw_ar_set, rtr_id, dcore_id, dcore_rtr_id, xy, razwi_mask_info, razwi_intr = 0; @@ -7746,19 +7754,19 @@ static void gaudi2_ack_psoc_razwi_event_handler(struct hl_device *hdev) if (hbw_aw_set) gaudi2_razwi_unmapped_addr_hbw_printf_info(hdev, rtr_id, - rtr_ctrl_base_addr, true); + rtr_ctrl_base_addr, true, event_mask); if (hbw_ar_set) gaudi2_razwi_unmapped_addr_hbw_printf_info(hdev, rtr_id, - rtr_ctrl_base_addr, false); + rtr_ctrl_base_addr, false, event_mask); if (lbw_aw_set) gaudi2_razwi_unmapped_addr_lbw_printf_info(hdev, rtr_id, - rtr_ctrl_base_addr, true); + rtr_ctrl_base_addr, true, event_mask); if (lbw_ar_set) gaudi2_razwi_unmapped_addr_lbw_printf_info(hdev, rtr_id, - rtr_ctrl_base_addr, false); + rtr_ctrl_base_addr, false, event_mask); clear: /* Clear Interrupts only on pldm or if f/w doesn't handle interrupts */ @@ -7784,7 +7792,7 @@ static void _gaudi2_handle_qm_sei_err(struct hl_device *hdev, u64 qman_base) } static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, - struct hl_eq_razwi_info *razwi_info) + struct hl_eq_razwi_info *razwi_info, u64 *event_mask) { enum razwi_event_sources module; u64 qman_base; @@ -7837,7 +7845,7 @@ static void gaudi2_handle_qm_sei_err(struct hl_device *hdev, u16 event_type, /* check if RAZWI happened */ if (razwi_info) - gaudi2_ack_module_razwi_event_handler(hdev, module, 0, 0, razwi_info); + gaudi2_ack_module_razwi_event_handler(hdev, module, 0, 0, razwi_info, event_mask); } static void gaudi2_handle_qman_err(struct hl_device *hdev, u16 event_type) @@ -8003,7 +8011,8 @@ static void gaudi2_handle_cpu_sei_err(struct hl_device *hdev) } static void gaudi2_handle_rot_err(struct hl_device *hdev, u8 rot_index, - struct hl_eq_razwi_with_intr_cause *razwi_with_intr_cause) + struct hl_eq_razwi_with_intr_cause *razwi_with_intr_cause, + u64 *event_mask) { u64 intr_cause_data = le64_to_cpu(razwi_with_intr_cause->intr_cause.intr_cause_data); int i; @@ -8015,11 +8024,12 @@ static void gaudi2_handle_rot_err(struct hl_device *hdev, u8 rot_index, /* check if RAZWI happened */ gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_ROT, rot_index, 0, - &razwi_with_intr_cause->razwi_info); + &razwi_with_intr_cause->razwi_info, event_mask); } static void gaudi2_tpc_ack_interrupts(struct hl_device *hdev, u8 tpc_index, char *interrupt_name, - struct hl_eq_razwi_with_intr_cause *razwi_with_intr_cause) + struct hl_eq_razwi_with_intr_cause *razwi_with_intr_cause, + u64 *event_mask) { u64 intr_cause_data = le64_to_cpu(razwi_with_intr_cause->intr_cause.intr_cause_data); int i; @@ -8031,11 +8041,11 @@ static void gaudi2_tpc_ack_interrupts(struct hl_device *hdev, u8 tpc_index, char /* check if RAZWI happened */ gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_TPC, tpc_index, 0, - &razwi_with_intr_cause->razwi_info); + &razwi_with_intr_cause->razwi_info, event_mask); } static void gaudi2_handle_dec_err(struct hl_device *hdev, u8 dec_index, const char *interrupt_name, - struct hl_eq_razwi_info *razwi_info) + struct hl_eq_razwi_info *razwi_info, u64 *event_mask) { u32 sts_addr, sts_val, sts_clr_val = 0; int i; @@ -8061,14 +8071,15 @@ static void gaudi2_handle_dec_err(struct hl_device *hdev, u8 dec_index, const ch } /* check if RAZWI happened */ - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_DEC, dec_index, 0, razwi_info); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_DEC, dec_index, 0, razwi_info, + event_mask); /* Write 1 clear errors */ WREG32(sts_addr, sts_clr_val); } static void gaudi2_handle_mme_err(struct hl_device *hdev, u8 mme_index, const char *interrupt_name, - struct hl_eq_razwi_info *razwi_info) + struct hl_eq_razwi_info *razwi_info, u64 *event_mask) { u32 sts_addr, sts_val, sts_clr_addr, sts_clr_val = 0; int i; @@ -8088,7 +8099,8 @@ static void gaudi2_handle_mme_err(struct hl_device *hdev, u8 mme_index, const ch /* check if RAZWI happened */ for (i = MME_WRITE ; i < MME_INITIATORS_MAX ; i++) - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, i, razwi_info); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, i, razwi_info, + event_mask); WREG32(sts_clr_addr, sts_clr_val); } @@ -8105,7 +8117,7 @@ static void gaudi2_handle_mme_sbte_err(struct hl_device *hdev, u8 mme_index, u8 } static void gaudi2_handle_mme_wap_err(struct hl_device *hdev, u8 mme_index, - struct hl_eq_razwi_info *razwi_info) + struct hl_eq_razwi_info *razwi_info, u64 *event_mask) { u32 sts_addr, sts_val, sts_clr_addr, sts_clr_val = 0; int i; @@ -8125,8 +8137,10 @@ static void gaudi2_handle_mme_wap_err(struct hl_device *hdev, u8 mme_index, } /* check if RAZWI happened on WAP0/1 */ - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, MME_WAP0, razwi_info); - gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, MME_WAP1, razwi_info); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, MME_WAP0, razwi_info, + event_mask); + gaudi2_ack_module_razwi_event_handler(hdev, RAZWI_MME, mme_index, MME_WAP1, razwi_info, + event_mask); WREG32(sts_clr_addr, sts_clr_val); } @@ -8156,40 +8170,41 @@ static void gaudi2_handle_dma_core_event(struct hl_device *hdev, u64 intr_cause_ gaudi2_dma_core_interrupts_cause[i]); } -static void gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(struct hl_device *hdev) +static void gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(struct hl_device *hdev, u64 *event_mask) { u32 mstr_if_base_addr = mmPCIE_MSTR_RR_MSTR_IF_RR_SHRD_HBW_BASE, razwi_happened_addr; razwi_happened_addr = mstr_if_base_addr + RR_SHRD_HBW_AW_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, mstr_if_base_addr, true, "PCIE", true, - NULL, GAUDI2_ENGINE_ID_PCIE); + NULL, GAUDI2_ENGINE_ID_PCIE, event_mask); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_HBW_AR_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_hbw_shared_printf_info(hdev, mstr_if_base_addr, false, "PCIE", true, - NULL, GAUDI2_ENGINE_ID_PCIE); + NULL, GAUDI2_ENGINE_ID_PCIE, event_mask); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_LBW_AW_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, mstr_if_base_addr, true, "PCIE", true, - NULL, GAUDI2_ENGINE_ID_PCIE); + NULL, GAUDI2_ENGINE_ID_PCIE, event_mask); WREG32(razwi_happened_addr, 0x1); } razwi_happened_addr = mstr_if_base_addr + RR_SHRD_LBW_AR_RAZWI_HAPPENED; if (RREG32(razwi_happened_addr)) { gaudi2_razwi_rr_lbw_shared_printf_info(hdev, mstr_if_base_addr, false, "PCIE", true, - NULL, GAUDI2_ENGINE_ID_PCIE); + NULL, GAUDI2_ENGINE_ID_PCIE, event_mask); WREG32(razwi_happened_addr, 0x1); } } -static void gaudi2_print_pcie_addr_dec_info(struct hl_device *hdev, u64 intr_cause_data) +static void gaudi2_print_pcie_addr_dec_info(struct hl_device *hdev, u64 intr_cause_data, + u64 *event_mask) { int i; @@ -8204,7 +8219,7 @@ static void gaudi2_print_pcie_addr_dec_info(struct hl_device *hdev, u64 intr_cau case PCIE_WRAP_PCIE_IC_SEI_INTR_IND_AXI_LBW_ERR_INTR_MASK: break; case PCIE_WRAP_PCIE_IC_SEI_INTR_IND_BAD_ACCESS_INTR_MASK: - gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(hdev); + gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(hdev, event_mask); break; } } @@ -8818,29 +8833,30 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_PDMA_CH0_AXI_ERR_RSP: case GAUDI2_EVENT_PDMA_CH1_AXI_ERR_RSP: reset_flags |= HL_DRV_RESET_FW_FATAL_ERR; - gaudi2_handle_qm_sei_err(hdev, event_type, &eq_entry->razwi_info); + gaudi2_handle_qm_sei_err(hdev, event_type, &eq_entry->razwi_info, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; case GAUDI2_EVENT_ROTATOR0_AXI_ERROR_RESPONSE: case GAUDI2_EVENT_ROTATOR1_AXI_ERROR_RESPONSE: index = event_type - GAUDI2_EVENT_ROTATOR0_AXI_ERROR_RESPONSE; - gaudi2_handle_rot_err(hdev, index, &eq_entry->razwi_with_intr_cause); - gaudi2_handle_qm_sei_err(hdev, event_type, NULL); + gaudi2_handle_rot_err(hdev, index, &eq_entry->razwi_with_intr_cause, &event_mask); + gaudi2_handle_qm_sei_err(hdev, event_type, NULL, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; case GAUDI2_EVENT_TPC0_AXI_ERR_RSP ... GAUDI2_EVENT_TPC24_AXI_ERR_RSP: index = event_type - GAUDI2_EVENT_TPC0_AXI_ERR_RSP; gaudi2_tpc_ack_interrupts(hdev, index, "AXI_ERR_RSP", - &eq_entry->razwi_with_intr_cause); - gaudi2_handle_qm_sei_err(hdev, event_type, NULL); + &eq_entry->razwi_with_intr_cause, &event_mask); + gaudi2_handle_qm_sei_err(hdev, event_type, NULL, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; case GAUDI2_EVENT_DEC0_AXI_ERR_RSPONSE ... GAUDI2_EVENT_DEC9_AXI_ERR_RSPONSE: index = event_type - GAUDI2_EVENT_DEC0_AXI_ERR_RSPONSE; - gaudi2_handle_dec_err(hdev, index, "AXI_ERR_RESPONSE", &eq_entry->razwi_info); + gaudi2_handle_dec_err(hdev, index, "AXI_ERR_RESPONSE", &eq_entry->razwi_info, + &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8871,7 +8887,8 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_TPC24_KERNEL_ERR: index = (event_type - GAUDI2_EVENT_TPC0_KERNEL_ERR) / (GAUDI2_EVENT_TPC1_KERNEL_ERR - GAUDI2_EVENT_TPC0_KERNEL_ERR); - gaudi2_tpc_ack_interrupts(hdev, index, "KRN_ERR", &eq_entry->razwi_with_intr_cause); + gaudi2_tpc_ack_interrupts(hdev, index, "KRN_ERR", &eq_entry->razwi_with_intr_cause, + &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8887,7 +8904,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_DEC9_SPI: index = (event_type - GAUDI2_EVENT_DEC0_SPI) / (GAUDI2_EVENT_DEC1_SPI - GAUDI2_EVENT_DEC0_SPI); - gaudi2_handle_dec_err(hdev, index, "SPI", &eq_entry->razwi_info); + gaudi2_handle_dec_err(hdev, index, "SPI", &eq_entry->razwi_info, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8899,8 +8916,8 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent (GAUDI2_EVENT_MME1_CTRL_AXI_ERROR_RESPONSE - GAUDI2_EVENT_MME0_CTRL_AXI_ERROR_RESPONSE); gaudi2_handle_mme_err(hdev, index, - "CTRL_AXI_ERROR_RESPONSE", &eq_entry->razwi_info); - gaudi2_handle_qm_sei_err(hdev, event_type, NULL); + "CTRL_AXI_ERROR_RESPONSE", &eq_entry->razwi_info, &event_mask); + gaudi2_handle_qm_sei_err(hdev, event_type, NULL, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8911,7 +8928,8 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent index = (event_type - GAUDI2_EVENT_MME0_QMAN_SW_ERROR) / (GAUDI2_EVENT_MME1_QMAN_SW_ERROR - GAUDI2_EVENT_MME0_QMAN_SW_ERROR); - gaudi2_handle_mme_err(hdev, index, "QMAN_SW_ERROR", &eq_entry->razwi_info); + gaudi2_handle_mme_err(hdev, index, "QMAN_SW_ERROR", &eq_entry->razwi_info, + &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8922,7 +8940,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent index = (event_type - GAUDI2_EVENT_MME0_WAP_SOURCE_RESULT_INVALID) / (GAUDI2_EVENT_MME1_WAP_SOURCE_RESULT_INVALID - GAUDI2_EVENT_MME0_WAP_SOURCE_RESULT_INVALID); - gaudi2_handle_mme_wap_err(hdev, index, &eq_entry->razwi_info); + gaudi2_handle_mme_wap_err(hdev, index, &eq_entry->razwi_info, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -8941,7 +8959,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_PCIE_ADDR_DEC_ERR: gaudi2_print_pcie_addr_dec_info(hdev, - le64_to_cpu(eq_entry->intr_cause.intr_cause_data)); + le64_to_cpu(eq_entry->intr_cause.intr_cause_data), &event_mask); reset_flags |= HL_DRV_RESET_FW_FATAL_ERR; event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR; break; @@ -8970,7 +8988,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent break; case GAUDI2_EVENT_PSOC63_RAZWI_OR_PID_MIN_MAX_INTERRUPT: - gaudi2_ack_psoc_razwi_event_handler(hdev); + gaudi2_ack_psoc_razwi_event_handler(hdev, &event_mask); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; -- GitLab From 3daa64eea1fb219c8cfb3bb6948dc2993652e201 Mon Sep 17 00:00:00 2001 From: farah kassabri Date: Thu, 22 Sep 2022 14:24:35 +0300 Subject: [PATCH 0734/1480] habanalabs: fix firmware descriptor copy operation This is needed to allow adding more data to the lkd_fw_comms_desc structure. Signed-off-by: farah kassabri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 26 ++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index f18e53bbba6bb..01c4ffba6e973 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -12,6 +12,7 @@ #include #include #include +#include #define FW_FILE_MAX_SIZE 0x1400000 /* maximum size of 20MB */ @@ -1988,10 +1989,11 @@ static int hl_fw_dynamic_read_and_validate_descriptor(struct hl_device *hdev, struct fw_load_mgr *fw_loader) { struct lkd_fw_comms_desc *fw_desc; + void __iomem *src, *temp_fw_desc; struct pci_mem_region *region; struct fw_response *response; + u16 fw_data_size; enum pci_region region_id; - void __iomem *src; int rc; fw_desc = &fw_loader->dynamic_loader.comm_desc; @@ -2018,9 +2020,29 @@ static int hl_fw_dynamic_read_and_validate_descriptor(struct hl_device *hdev, fw_loader->dynamic_loader.fw_desc_valid = false; src = hdev->pcie_bar[region->bar_id] + region->offset_in_bar + response->ram_offset; + + /* + * We do the copy of the fw descriptor in 2 phases: + * 1. copy the header + data info according to our lkd_fw_comms_desc definition. + * then we're able to read the actual data size provided by fw. + * this is needed for cases where data in descriptor was changed(add/remove) + * in embedded specs header file before updating lkd copy of the header file + * 2. copy descriptor to temporary buffer with aligned size and send it to validation + */ memcpy_fromio(fw_desc, src, sizeof(struct lkd_fw_comms_desc)); + fw_data_size = le16_to_cpu(fw_desc->header.size); + + temp_fw_desc = vzalloc(sizeof(struct comms_desc_header) + fw_data_size); + if (!temp_fw_desc) + return -ENOMEM; + + memcpy_fromio(temp_fw_desc, src, sizeof(struct comms_desc_header) + fw_data_size); - return hl_fw_dynamic_validate_descriptor(hdev, fw_loader, fw_desc); + rc = hl_fw_dynamic_validate_descriptor(hdev, fw_loader, + (struct lkd_fw_comms_desc *) temp_fw_desc); + vfree(temp_fw_desc); + + return rc; } /** -- GitLab From b829e01025f8936bb85bdc39cbd1faddcca290d0 Mon Sep 17 00:00:00 2001 From: Ohad Sharabi Date: Sun, 6 Nov 2022 09:26:01 +0200 Subject: [PATCH 0735/1480] habanalabs: skip events info ioctl if not supported Some ASICs haven't yet implemented this functionality and so the ioctl call should fail and the user should be notified of the reason. Signed-off-by: Ohad Sharabi Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs_ioctl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index ee43017eb5636..b6abfa7761a70 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -123,6 +123,10 @@ static int hw_events_info(struct hl_device *hdev, bool aggregate, return -EINVAL; arr = hdev->asic_funcs->get_events_stat(hdev, aggregate, &size); + if (!arr) { + dev_err(hdev->dev, "Events info not supported\n"); + return -EOPNOTSUPP; + } return copy_to_user(out, arr, min(max_size, size)) ? -EFAULT : 0; } -- GitLab From a63de89bee7ff01dc184fbe289eade5b5ab5f49a Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Sun, 6 Nov 2022 12:07:03 +0200 Subject: [PATCH 0736/1480] habanalabs/gaudi2: classify power/thermal events as info As power and thermal envelope events are pure informative and not indicating an error, we reduce the print level to info only. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 59940c8df2d20..61960fa059e0a 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -6828,6 +6828,7 @@ static inline bool is_info_event(u32 event) { switch (event) { case GAUDI2_EVENT_CPU_CPLD_SHUTDOWN_CAUSE: + case GAUDI2_EVENT_CPU_FIX_POWER_ENV_S ... GAUDI2_EVENT_CPU_FIX_THERMAL_ENV_E: return true; default: return false; -- GitLab From d3027f4a625063c18becd6953b4a2a273033b071 Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Mon, 31 Oct 2022 23:04:14 +0200 Subject: [PATCH 0737/1480] habanalabs/gaudi2: add page fault notify event Each time page fault happens, besides capturing its data, also notify the user about it. Signed-off-by: Dani Liberman Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 61960fa059e0a..65c9b535aa698 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8253,7 +8253,8 @@ static void gaudi2_handle_hif_fatal(struct hl_device *hdev, u16 event_type, u64 } } -static void gaudi2_handle_page_error(struct hl_device *hdev, u64 mmu_base, bool is_pmmu) +static void gaudi2_handle_page_error(struct hl_device *hdev, u64 mmu_base, bool is_pmmu, + u64 *event_mask) { u32 valid, val; u64 addr; @@ -8270,7 +8271,7 @@ static void gaudi2_handle_page_error(struct hl_device *hdev, u64 mmu_base, bool dev_err_ratelimited(hdev->dev, "%s page fault on va 0x%llx\n", is_pmmu ? "PMMU" : "HMMU", addr); - hl_capture_page_fault(hdev, addr, 0, is_pmmu); + hl_handle_page_fault(hdev, addr, 0, is_pmmu, event_mask); WREG32(mmu_base + MMU_OFFSET(mmDCORE0_HMMU0_MMU_PAGE_ERROR_CAPTURE), 0); } @@ -8296,7 +8297,7 @@ static void gaudi2_handle_access_error(struct hl_device *hdev, u64 mmu_base, boo } static void gaudi2_handle_mmu_spi_sei_generic(struct hl_device *hdev, const char *mmu_name, - u64 mmu_base, bool is_pmmu) + u64 mmu_base, bool is_pmmu, u64 *event_mask) { u32 spi_sei_cause, interrupt_clr = 0x0; int i; @@ -8309,7 +8310,7 @@ static void gaudi2_handle_mmu_spi_sei_generic(struct hl_device *hdev, const char mmu_name, gaudi2_mmu_spi_sei[i].cause); if (i == 0) - gaudi2_handle_page_error(hdev, mmu_base, is_pmmu); + gaudi2_handle_page_error(hdev, mmu_base, is_pmmu, event_mask); else if (i == 1) gaudi2_handle_access_error(hdev, mmu_base, is_pmmu); @@ -8381,7 +8382,7 @@ static bool gaudi2_handle_sm_err(struct hl_device *hdev, u8 sm_index) return reset; } -static void gaudi2_handle_mmu_spi_sei_err(struct hl_device *hdev, u16 event_type) +static void gaudi2_handle_mmu_spi_sei_err(struct hl_device *hdev, u16 event_type, u64 *event_mask) { bool is_pmmu = false; char desc[32]; @@ -8439,7 +8440,7 @@ static void gaudi2_handle_mmu_spi_sei_err(struct hl_device *hdev, u16 event_type return; } - gaudi2_handle_mmu_spi_sei_generic(hdev, desc, mmu_base, is_pmmu); + gaudi2_handle_mmu_spi_sei_generic(hdev, desc, mmu_base, is_pmmu, event_mask); } @@ -8969,7 +8970,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_HMMU_0_AXI_ERR_RSP ... GAUDI2_EVENT_HMMU_12_AXI_ERR_RSP: case GAUDI2_EVENT_PMMU0_PAGE_FAULT_WR_PERM ... GAUDI2_EVENT_PMMU0_SECURITY_ERROR: case GAUDI2_EVENT_PMMU_AXI_ERR_RSP_0: - gaudi2_handle_mmu_spi_sei_err(hdev, event_type); + gaudi2_handle_mmu_spi_sei_err(hdev, event_type, &event_mask); reset_flags |= HL_DRV_RESET_FW_FATAL_ERR; event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -10206,7 +10207,7 @@ static void gaudi2_ack_mmu_error(struct hl_device *hdev, u64 mmu_id) if (gaudi2_get_mmu_base(hdev, mmu_id, &mmu_base)) return; - gaudi2_handle_page_error(hdev, mmu_base, is_pmmu); + gaudi2_handle_page_error(hdev, mmu_base, is_pmmu, NULL); gaudi2_handle_access_error(hdev, mmu_base, is_pmmu); } -- GitLab From 5f8981d699ed33017ff2212ec17f6cde89212756 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Mon, 7 Nov 2022 16:20:03 +0200 Subject: [PATCH 0738/1480] habanalabs: fix print for out-of-sync and pkt-failure events Add missing le32_to_cpu() conversions, and use %d for the value returned from atomic_read(). Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi/gaudi.c | 4 ++-- drivers/misc/habanalabs/gaudi2/gaudi2.c | 8 ++++---- drivers/misc/habanalabs/goya/goya.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index cbe1daf5a7939..7b93f0d26dd02 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7347,8 +7347,8 @@ static void gaudi_print_out_of_sync_info(struct hl_device *hdev, { struct hl_hw_queue *q = &hdev->kernel_queues[GAUDI_QUEUE_ID_CPU_PQ]; - dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%u\n", - sync_err->pi, sync_err->ci, q->pi, atomic_read(&q->ci)); + dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%d\n", + le32_to_cpu(sync_err->pi), le32_to_cpu(sync_err->ci), q->pi, atomic_read(&q->ci)); } static void gaudi_print_fw_alive_info(struct hl_device *hdev, diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 65c9b535aa698..bdb5782afb7e5 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8684,8 +8684,8 @@ static void gaudi2_print_out_of_sync_info(struct hl_device *hdev, { struct hl_hw_queue *q = &hdev->kernel_queues[GAUDI2_QUEUE_ID_CPU_PQ]; - dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%u\n", - sync_err->pi, sync_err->ci, q->pi, atomic_read(&q->ci)); + dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%d\n", + le32_to_cpu(sync_err->pi), le32_to_cpu(sync_err->ci), q->pi, atomic_read(&q->ci)); } static void gaudi2_handle_pcie_p2p_msix(struct hl_device *hdev) @@ -8751,8 +8751,8 @@ static void gaudi2_print_cpu_pkt_failure_info(struct hl_device *hdev, struct hl_hw_queue *q = &hdev->kernel_queues[GAUDI2_QUEUE_ID_CPU_PQ]; dev_warn(hdev->dev, - "FW reported sanity check failure, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%u\n", - sync_err->pi, sync_err->ci, q->pi, atomic_read(&q->ci)); + "FW reported sanity check failure, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%d\n", + le32_to_cpu(sync_err->pi), le32_to_cpu(sync_err->ci), q->pi, atomic_read(&q->ci)); } static void hl_arc_event_handle(struct hl_device *hdev, diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index 5ef9e3ca97a69..0f083fcf81a6b 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -4475,8 +4475,8 @@ static void goya_print_out_of_sync_info(struct hl_device *hdev, { struct hl_hw_queue *q = &hdev->kernel_queues[GOYA_QUEUE_ID_CPU_PQ]; - dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%u\n", - sync_err->pi, sync_err->ci, q->pi, atomic_read(&q->ci)); + dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%d\n", + le32_to_cpu(sync_err->pi), le32_to_cpu(sync_err->ci), q->pi, atomic_read(&q->ci)); } static void goya_print_irq_info(struct hl_device *hdev, u16 event_type, -- GitLab From fe3e88c9470ceb2ea67651aa397f29e80453eed1 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Mon, 7 Nov 2022 16:34:32 +0200 Subject: [PATCH 0739/1480] habanalabs/gaudi: fix print for firmware-alive event Add missing le{32,64}_to_cpu conversions. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi/gaudi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 7b93f0d26dd02..9f5e208701bad 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7356,9 +7356,10 @@ static void gaudi_print_fw_alive_info(struct hl_device *hdev, { dev_err(hdev->dev, "FW alive report: severity=%s, process_id=%u, thread_id=%u, uptime=%llu seconds\n", - (fw_alive->severity == FW_ALIVE_SEVERITY_MINOR) ? - "Minor" : "Critical", fw_alive->process_id, - fw_alive->thread_id, fw_alive->uptime_seconds); + (fw_alive->severity == FW_ALIVE_SEVERITY_MINOR) ? "Minor" : "Critical", + le32_to_cpu(fw_alive->process_id), + le32_to_cpu(fw_alive->thread_id), + le64_to_cpu(fw_alive->uptime_seconds)); } static void gaudi_print_nic_axi_irq_info(struct hl_device *hdev, u16 event_type, -- GitLab From 24c983c88f5e7865de972e3b395baf2c237485ca Mon Sep 17 00:00:00 2001 From: farah kassabri Date: Tue, 8 Nov 2022 13:23:17 +0200 Subject: [PATCH 0740/1480] habanalabs/gaudi2: remove redundant firmware version check Firmware 1.7 is the first official firmware, so no need to check if we are running a version below it. Signed-off-by: farah kassabri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index bdb5782afb7e5..36f0ea1100bbc 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -10358,10 +10358,9 @@ int gaudi2_send_device_activity(struct hl_device *hdev, bool open) { struct gaudi2_device *gaudi2 = hdev->asic_specific; - if (!(gaudi2->hw_cap_initialized & HW_CAP_CPU_Q) || hdev->fw_major_version < 37) + if (!(gaudi2->hw_cap_initialized & HW_CAP_CPU_Q)) return 0; - /* TODO: add check for FW version using minor ver once it's known */ return hl_fw_send_device_activity(hdev, open); } -- GitLab From 2c77ec14c2db228f76a74e9123aecbb5b8c994f5 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 20 Oct 2022 12:05:09 +0300 Subject: [PATCH 0741/1480] habanalabs/gaudi2: don't enable entries in the MSIX_GW table User should use the virtual MSI-X doorbell to generate interrupts from the device, so there is no need to enable entries in the MSIX_GW table. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 26 ------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 36f0ea1100bbc..d5efec347bc1c 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -4695,30 +4695,6 @@ static void gaudi2_init_dec(struct hl_device *hdev) } } -static void gaudi2_init_msix_gw_table(struct hl_device *hdev) -{ - u32 first_reg_offset, last_reg_offset, msix_gw_table_base; - u8 first_bit, last_bit; - int i; - - msix_gw_table_base = mmPCIE_WRAP_MSIX_GW_TABLE_0; - first_reg_offset = (GAUDI2_IRQ_NUM_USER_FIRST >> 5) << 2; - first_bit = GAUDI2_IRQ_NUM_USER_FIRST % 32; - last_reg_offset = (GAUDI2_IRQ_NUM_USER_LAST >> 5) << 2; - last_bit = GAUDI2_IRQ_NUM_USER_LAST % 32; - - if (first_reg_offset == last_reg_offset) { - WREG32(msix_gw_table_base + first_reg_offset, GENMASK(last_bit, first_bit)); - return; - } - - WREG32(msix_gw_table_base + first_reg_offset, GENMASK(31, first_bit)); - WREG32(msix_gw_table_base + last_reg_offset, GENMASK(last_bit, 0)); - - for (i = first_reg_offset + 4; i < last_reg_offset ; i += 4) - WREG32(msix_gw_table_base + i, 0xFFFFFFFF); -} - static int gaudi2_mmu_update_asid_hop0_addr(struct hl_device *hdev, u32 stlb_base, u32 asid, u64 phys_addr) { @@ -5232,8 +5208,6 @@ static int gaudi2_hw_init(struct hl_device *hdev) return rc; } - gaudi2_init_msix_gw_table(hdev); - gaudi2_init_scrambler_hbm(hdev); gaudi2_init_kdma(hdev); -- GitLab From 9c604af0c9d4efe4f308761229186768b3f3a6a9 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 20 Oct 2022 14:40:16 +0300 Subject: [PATCH 0742/1480] habanalabs/gaudi2: return to reset upon SM SEI BRESP error Due to a H/W issue in the LBW path to the PCIE_DBI MSI-X doorbell, there were false sporadic error responses in SM when it was configured to write to there, and hence no reset was done as part of handling the relevant event. Now that the virtual MSI-X doorbell is used, such errors in SM are not expected and reset shouldn't be skipped. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index d5efec347bc1c..f0f2f77f56deb 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -8300,11 +8300,10 @@ static void gaudi2_handle_mmu_spi_sei_generic(struct hl_device *hdev, const char WREG32(mmu_base + MMU_INTERRUPT_CLR_OFFSET, interrupt_clr); } -static bool gaudi2_handle_sm_err(struct hl_device *hdev, u8 sm_index) +static void gaudi2_handle_sm_err(struct hl_device *hdev, u8 sm_index) { u32 sei_cause_addr, sei_cause_val, sei_cause_cause, sei_cause_log; u32 cq_intr_addr, cq_intr_val, cq_intr_queue_index; - bool reset = true; int i; sei_cause_addr = mmDCORE0_SYNC_MNGR_GLBL_SM_SEI_CAUSE + DCORE_OFFSET * sm_index; @@ -8329,10 +8328,6 @@ static bool gaudi2_handle_sm_err(struct hl_device *hdev, u8 sm_index) gaudi2_sm_sei_cause[i].cause_name, gaudi2_sm_sei_cause[i].log_name, sei_cause_log & gaudi2_sm_sei_cause[i].log_mask); - - /* Due to a potential H/W issue, do not reset upon BRESP errors */ - if (i == 2) - reset = false; break; } @@ -8352,8 +8347,6 @@ static bool gaudi2_handle_sm_err(struct hl_device *hdev, u8 sm_index) /* Clear CQ_INTR */ WREG32(cq_intr_addr, 0); } - - return reset; } static void gaudi2_handle_mmu_spi_sei_err(struct hl_device *hdev, u16 event_type, u64 *event_mask) @@ -8755,8 +8748,8 @@ static void hl_arc_event_handle(struct hl_device *hdev, static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entry) { - bool reset_required = false, skip_reset = false, is_critical = false; struct gaudi2_device *gaudi2 = hdev->asic_specific; + bool reset_required = false, is_critical = false; u32 ctl, reset_flags = HL_DRV_RESET_HARD; int index, sbte_index; u64 event_mask = 0; @@ -9113,7 +9106,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent case GAUDI2_EVENT_SM0_AXI_ERROR_RESPONSE ... GAUDI2_EVENT_SM3_AXI_ERROR_RESPONSE: index = event_type - GAUDI2_EVENT_SM0_AXI_ERROR_RESPONSE; - skip_reset = !gaudi2_handle_sm_err(hdev, index); + gaudi2_handle_sm_err(hdev, index); event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR; break; @@ -9153,9 +9146,9 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent event_type); } - if ((gaudi2_irq_map_table[event_type].reset || reset_required) && !skip_reset && - (hdev->hard_reset_on_fw_events || - (hdev->asic_prop.fw_security_enabled && is_critical))) + if ((gaudi2_irq_map_table[event_type].reset || reset_required) && + (hdev->hard_reset_on_fw_events || + (hdev->asic_prop.fw_security_enabled && is_critical))) goto reset_device; /* Send unmask irq only for interrupts not classified as MSG */ -- GitLab From bc8e4bae70237f4671e07f83bcfb726eb14d86ed Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Wed, 9 Nov 2022 18:08:38 +0200 Subject: [PATCH 0743/1480] habanalabs: reset device if still in use when released If the device file is released while a context is still held, it won't be possible to reopen it until the context is eventually released. If that doesn't happen, only a device reset will revert it back to an operational state, i.e. need to wait for a CS timeout or an error, or to wait for an external intervention of injecting a reset via sysfs. At this stage, after the device was released by user, context is held either because of CS which were left running on the device and are not relevant anymore, or due to missing cleanup steps from user side. All of this is in any case handled in the device reset flow, so initiate the reset at this point instead of waiting for it. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 708db0f48ee0e..49640c8ca9102 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -504,9 +504,10 @@ static int hl_device_release(struct inode *inode, struct file *filp) hdev->compute_ctx_in_release = 1; - if (!hl_hpriv_put(hpriv)) - dev_notice(hdev->dev, - "User process closed FD but device still in use\n"); + if (!hl_hpriv_put(hpriv)) { + dev_notice(hdev->dev, "User process closed FD but device still in use\n"); + hl_device_reset(hdev, HL_DRV_RESET_HARD); + } hdev->last_open_session_duration_jif = jiffies - hdev->last_successful_open_jif; -- GitLab From f69c3e460a614cba8939f7c623f7b77f0bcb3584 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 10 Nov 2022 17:05:24 +0200 Subject: [PATCH 0744/1480] habanalabs: check schedule_hard_reset correctly schedule_hard_reset can be true only if we didn't do hard-reset. Therefore, no point of checking it in case hard_reset is true. Signed-off-by: Oded Gabbay Reviewed-by: Tomer Tayar --- drivers/misc/habanalabs/common/device.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 49640c8ca9102..0650e511a0f5e 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1737,18 +1737,19 @@ kill_processes: * the device will be operational although it shouldn't be */ hdev->asic_funcs->enable_events_from_fw(hdev); - } else if (!reset_upon_device_release) { - hdev->reset_info.compute_reset_cnt++; - } - - if (schedule_hard_reset) { - dev_info(hdev->dev, "Performing hard reset scheduled during compute reset\n"); - flags = hdev->reset_info.hard_reset_schedule_flags; - hdev->reset_info.hard_reset_schedule_flags = 0; - hdev->disabled = true; - hard_reset = true; - handle_reset_trigger(hdev, flags); - goto again; + } else { + if (!reset_upon_device_release) + hdev->reset_info.compute_reset_cnt++; + + if (schedule_hard_reset) { + dev_info(hdev->dev, "Performing hard reset scheduled during compute reset\n"); + flags = hdev->reset_info.hard_reset_schedule_flags; + hdev->reset_info.hard_reset_schedule_flags = 0; + hdev->disabled = true; + hard_reset = true; + handle_reset_trigger(hdev, flags); + goto again; + } } return 0; -- GitLab From b585daa89d572210a94c7f11a746bd5489017003 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 10 Nov 2022 17:24:02 +0200 Subject: [PATCH 0745/1480] habanalabs: extend process wait timeout in device fine Processes that use our device are likely to use at the same time other devices such as remote storage. In case our device is removed and a user process is still using the device, we need to kill the user process. However, if that process has a thread waiting for i/o to complete on remote storage, for example, the process won't terminate. Let's give it enough time to terminate before giving up. Signed-off-by: Oded Gabbay Reviewed-by: Tomer Tayar --- drivers/misc/habanalabs/common/device.c | 6 ++++-- drivers/misc/habanalabs/common/habanalabs.h | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 0650e511a0f5e..63d0cb7087e8d 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -2300,14 +2300,16 @@ void hl_device_fini(struct hl_device *hdev) */ dev_info(hdev->dev, "Waiting for all processes to exit (timeout of %u seconds)", - HL_PENDING_RESET_LONG_SEC); + HL_WAIT_PROCESS_KILL_ON_DEVICE_FINI); - rc = device_kill_open_processes(hdev, HL_PENDING_RESET_LONG_SEC, false); + hdev->process_kill_trial_cnt = 0; + rc = device_kill_open_processes(hdev, HL_WAIT_PROCESS_KILL_ON_DEVICE_FINI, false); if (rc) { dev_crit(hdev->dev, "Failed to kill all open processes\n"); device_disable_open_processes(hdev, false); } + hdev->process_kill_trial_cnt = 0; rc = device_kill_open_processes(hdev, 0, true); if (rc) { dev_crit(hdev->dev, "Failed to kill all control device open processes\n"); diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 0781b8698f744..e7f89868428d6 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -50,9 +50,14 @@ struct hl_fpriv; #define HL_MMAP_OFFSET_VALUE_MASK (0x1FFFFFFFFFFFull >> PAGE_SHIFT) #define HL_MMAP_OFFSET_VALUE_GET(off) (off & HL_MMAP_OFFSET_VALUE_MASK) -#define HL_PENDING_RESET_PER_SEC 10 -#define HL_PENDING_RESET_MAX_TRIALS 60 /* 10 minutes */ -#define HL_PENDING_RESET_LONG_SEC 60 +#define HL_PENDING_RESET_PER_SEC 10 +#define HL_PENDING_RESET_MAX_TRIALS 60 /* 10 minutes */ +#define HL_PENDING_RESET_LONG_SEC 60 +/* + * In device fini, wait 10 minutes for user processes to be terminated after we kill them. + * This is needed to prevent situation of clearing resources while user processes are still alive. + */ +#define HL_WAIT_PROCESS_KILL_ON_DEVICE_FINI 600 #define HL_HARD_RESET_MAX_TIMEOUT 120 #define HL_PLDM_HARD_RESET_MAX_TIMEOUT (HL_HARD_RESET_MAX_TIMEOUT * 3) -- GitLab From 18cd948204fffa61660d3f8454fc9d275c1f6c94 Mon Sep 17 00:00:00 2001 From: farah kassabri Date: Tue, 8 Nov 2022 15:24:33 +0200 Subject: [PATCH 0746/1480] habanalabs/gaudi2: change memory scrub mechanism Currently the scrubbing mechanism used the EDMA engines by directly setting the engine core registers to scrub a chunk of memory. Due to a sporadic failure with this mechanism, it was decided to initiate the engines via its QMAN using LIN-DMA packets. Signed-off-by: farah kassabri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 129 +++++++++++++++--------- 1 file changed, 83 insertions(+), 46 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index f0f2f77f56deb..c14e63164a848 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -9171,34 +9171,74 @@ reset_device: hl_device_cond_reset(hdev, reset_flags, event_mask); } +static int gaudi2_memset_memory_chunk_using_edma_qm(struct hl_device *hdev, + struct packet_lin_dma *lin_dma_pkt, dma_addr_t pkt_dma_addr, + u32 hw_queue_id, u32 size, u64 addr, u32 val) +{ + u32 ctl, pkt_size; + int rc = 0; + + ctl = FIELD_PREP(GAUDI2_PKT_CTL_OPCODE_MASK, PACKET_LIN_DMA); + ctl |= FIELD_PREP(GAUDI2_PKT_LIN_DMA_CTL_MEMSET_MASK, 1); + ctl |= FIELD_PREP(GAUDI2_PKT_LIN_DMA_CTL_WRCOMP_MASK, 1); + ctl |= FIELD_PREP(GAUDI2_PKT_CTL_EB_MASK, 1); + + lin_dma_pkt->ctl = cpu_to_le32(ctl); + lin_dma_pkt->src_addr = cpu_to_le64(val); + lin_dma_pkt->dst_addr = cpu_to_le64(addr); + lin_dma_pkt->tsize = cpu_to_le32(size); + + pkt_size = sizeof(struct packet_lin_dma); + + rc = hl_hw_queue_send_cb_no_cmpl(hdev, hw_queue_id, pkt_size, pkt_dma_addr); + if (rc) + dev_err(hdev->dev, "Failed to send lin dma packet to H/W queue %d\n", + hw_queue_id); + + return rc; +} + static int gaudi2_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, u64 val) { - struct asic_fixed_properties *prop = &hdev->asic_prop; + u32 edma_queues_id[] = {GAUDI2_QUEUE_ID_DCORE0_EDMA_0_0, + GAUDI2_QUEUE_ID_DCORE1_EDMA_0_0, + GAUDI2_QUEUE_ID_DCORE2_EDMA_0_0, + GAUDI2_QUEUE_ID_DCORE3_EDMA_0_0}; + u32 chunk_size, dcore, edma_idx, sob_offset, sob_addr, comp_val, + old_mmubp, mmubp, num_of_pkts, busy, pkt_size; u64 comp_addr, cur_addr = addr, end_addr = addr + size; - u32 chunk_size, busy, dcore, edma_idx, sob_offset, sob_addr, comp_val, edma_commit; - u32 old_mmubp, mmubp; - int rc = 0; + struct asic_fixed_properties *prop = &hdev->asic_prop; + void *lin_dma_pkts_arr; + dma_addr_t pkt_dma_addr; + int rc = 0, dma_num = 0; + + if (prop->edma_enabled_mask == 0) { + dev_info(hdev->dev, "non of the EDMA engines is enabled - skip dram scrubbing\n"); + return -EIO; + } sob_offset = hdev->asic_prop.first_available_user_sob[0] * 4; sob_addr = mmDCORE0_SYNC_MNGR_OBJS_SOB_OBJ_0 + sob_offset; comp_addr = CFG_BASE + sob_addr; comp_val = FIELD_PREP(DCORE0_SYNC_MNGR_OBJS_SOB_OBJ_INC_MASK, 1) | FIELD_PREP(DCORE0_SYNC_MNGR_OBJS_SOB_OBJ_VAL_MASK, 1); - - edma_commit = FIELD_PREP(ARC_FARM_KDMA_CTX_COMMIT_LIN_MASK, 1) | - FIELD_PREP(ARC_FARM_KDMA_CTX_COMMIT_MEM_SET_MASK, 1) | - FIELD_PREP(ARC_FARM_KDMA_CTX_COMMIT_WR_COMP_EN_MASK, 1); mmubp = FIELD_PREP(ARC_FARM_KDMA_CTX_AXUSER_HB_MMU_BP_WR_MASK, 1) | FIELD_PREP(ARC_FARM_KDMA_CTX_AXUSER_HB_MMU_BP_RD_MASK, 1); - if (prop->edma_enabled_mask == 0) { - dev_info(hdev->dev, "non of the EDMA engines is enabled - skip dram scrubbing\n"); - return -EIO; - } + /* Calculate how many lin dma pkts we'll need */ + num_of_pkts = div64_u64(round_up(size, SZ_2G), SZ_2G); + pkt_size = sizeof(struct packet_lin_dma); + + lin_dma_pkts_arr = hl_asic_dma_alloc_coherent(hdev, pkt_size * num_of_pkts, + &pkt_dma_addr, GFP_KERNEL); + if (!lin_dma_pkts_arr) + return -ENOMEM; /* * set mmu bypass for the scrubbing - all ddmas are configured the same so save * only the first one to restore later + * also set the sob addr for all edma cores for completion. + * set QM as trusted to allow it to access physical address with MMU bp. */ old_mmubp = RREG32(mmDCORE0_EDMA0_CORE_CTX_AXUSER_HB_MMU_BP); for (dcore = 0 ; dcore < NUM_OF_DCORES ; dcore++) { @@ -9211,17 +9251,22 @@ static int gaudi2_memset_device_memory(struct hl_device *hdev, u64 addr, u64 siz WREG32(mmDCORE0_EDMA0_CORE_CTX_AXUSER_HB_MMU_BP + edma_offset, mmubp); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_LO + edma_offset, + lower_32_bits(comp_addr)); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_HI + edma_offset, + upper_32_bits(comp_addr)); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_WDATA + edma_offset, + comp_val); + gaudi2_qman_set_test_mode(hdev, + edma_queues_id[dcore] + 4 * edma_idx, true); } } - while (cur_addr < end_addr) { - int dma_num = 0; + WREG32(sob_addr, 0); - WREG32(sob_addr, 0); + while (cur_addr < end_addr) { for (dcore = 0 ; dcore < NUM_OF_DCORES ; dcore++) { for (edma_idx = 0 ; edma_idx < NUM_OF_EDMA_PER_DCORE ; edma_idx++) { - u32 edma_offset = dcore * DCORE_OFFSET + - edma_idx * DCORE_EDMA_OFFSET; u32 edma_bit = dcore * NUM_OF_EDMA_PER_DCORE + edma_idx; if (!(prop->edma_enabled_mask & BIT(edma_bit))) @@ -9229,41 +9274,26 @@ static int gaudi2_memset_device_memory(struct hl_device *hdev, u64 addr, u64 siz chunk_size = min_t(u64, SZ_2G, end_addr - cur_addr); - WREG32(mmDCORE0_EDMA0_CORE_CTX_SRC_BASE_LO + edma_offset, - lower_32_bits(val)); - WREG32(mmDCORE0_EDMA0_CORE_CTX_SRC_BASE_HI + edma_offset, - upper_32_bits(val)); - - WREG32(mmDCORE0_EDMA0_CORE_CTX_DST_BASE_LO + edma_offset, - lower_32_bits(cur_addr)); - WREG32(mmDCORE0_EDMA0_CORE_CTX_DST_BASE_HI + edma_offset, - upper_32_bits(cur_addr)); - - WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_LO + edma_offset, - lower_32_bits(comp_addr)); - WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_HI + edma_offset, - upper_32_bits(comp_addr)); - WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_WDATA + edma_offset, - comp_val); - - WREG32(mmDCORE0_EDMA0_CORE_CTX_DST_TSIZE_0 + edma_offset, - chunk_size); - WREG32(mmDCORE0_EDMA0_CORE_CTX_COMMIT + edma_offset, edma_commit); + rc = gaudi2_memset_memory_chunk_using_edma_qm(hdev, + (struct packet_lin_dma *)lin_dma_pkts_arr + dma_num, + pkt_dma_addr + dma_num * pkt_size, + edma_queues_id[dcore] + edma_idx * 4, + chunk_size, cur_addr, val); + if (rc) + goto end; dma_num++; - cur_addr += chunk_size; - if (cur_addr == end_addr) - goto poll; + break; } } -poll: - rc = hl_poll_timeout(hdev, sob_addr, busy, (busy == dma_num), 1000, 1000000); - if (rc) { - dev_err(hdev->dev, "DMA Timeout during HBM scrubbing\n"); - goto end; - } + } + + rc = hl_poll_timeout(hdev, sob_addr, busy, (busy == dma_num), 1000, 1000000); + if (rc) { + dev_err(hdev->dev, "DMA Timeout during HBM scrubbing\n"); + goto end; } end: for (dcore = 0 ; dcore < NUM_OF_DCORES ; dcore++) { @@ -9275,10 +9305,17 @@ end: continue; WREG32(mmDCORE0_EDMA0_CORE_CTX_AXUSER_HB_MMU_BP + edma_offset, old_mmubp); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_LO + edma_offset, 0); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_ADDR_HI + edma_offset, 0); + WREG32(mmDCORE0_EDMA0_CORE_CTX_WR_COMP_WDATA + edma_offset, 0); + gaudi2_qman_set_test_mode(hdev, + edma_queues_id[dcore] + 4 * edma_idx, false); } } WREG32(sob_addr, 0); + hl_asic_dma_free_coherent(hdev, pkt_size * num_of_pkts, lin_dma_pkts_arr, pkt_dma_addr); + return rc; } -- GitLab From 01907ba5252164ca6bf0de670660cd94d77c378c Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Sun, 23 Oct 2022 12:55:21 +0300 Subject: [PATCH 0747/1480] habanalabs: increase the size of busy engines mask Increase the size of the busy engines mask in 'struct hl_info_hw_idle', for future ASICs with more than 128 engines. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 9 +++++---- include/uapi/misc/habanalabs.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 63d0cb7087e8d..f5864893237cc 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -416,8 +416,9 @@ static void hpriv_release(struct kref *ref) device_is_idle = hdev->asic_funcs->is_device_idle(hdev, idle_mask, HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL); if (!device_is_idle) { - dev_err(hdev->dev, "device not idle after user context is closed (0x%llx_%llx)\n", - idle_mask[1], idle_mask[0]); + dev_err(hdev->dev, + "device not idle after user context is closed (0x%llx_%llx_%llx_%llx)\n", + idle_mask[3], idle_mask[2], idle_mask[1], idle_mask[0]); reset_device = true; } @@ -1661,8 +1662,8 @@ kill_processes: /* If device is not idle fail the reset process */ if (!hdev->asic_funcs->is_device_idle(hdev, idle_mask, HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL)) { - dev_err(hdev->dev, "device is not idle (mask 0x%llx_%llx) after reset\n", - idle_mask[1], idle_mask[0]); + dev_err(hdev->dev, "device is not idle (mask 0x%llx_%llx_%llx_%llx) after reset\n", + idle_mask[3], idle_mask[2], idle_mask[1], idle_mask[0]); rc = -EIO; goto out_err; } diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index e50cb71df081c..3b995e841eb85 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -916,7 +916,7 @@ struct hl_info_dram_usage { __u64 ctx_dram_mem; }; -#define HL_BUSY_ENGINES_MASK_EXT_SIZE 2 +#define HL_BUSY_ENGINES_MASK_EXT_SIZE 4 struct hl_info_hw_idle { __u32 is_idle; -- GitLab From 5908560a7f14171d1100f4a357deda659dc26868 Mon Sep 17 00:00:00 2001 From: Marco Pagani Date: Wed, 16 Nov 2022 14:41:25 +0100 Subject: [PATCH 0748/1480] habanalabs: added return value check for hl_fw_dynamic_send_clear_cmd() The clang-analyzer reported a warning: "Value stored to 'rc' is never read". The return value check for the first hl_fw_dynamic_send_clear_cmd() call in hl_fw_dynamic_send_protocol_cmd() appears to be missing. Signed-off-by: Marco Pagani Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index 01c4ffba6e973..c0909d76d6eb2 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -1783,6 +1783,8 @@ int hl_fw_dynamic_send_protocol_cmd(struct hl_device *hdev, /* first send clear command to clean former commands */ rc = hl_fw_dynamic_send_clear_cmd(hdev, fw_loader); + if (rc) + return rc; /* send the actual command */ hl_fw_dynamic_send_cmd(hdev, fw_loader, cmd, size); -- GitLab From 6825b5f81f273fcc1ec61e7e203b0ea40d9987fc Mon Sep 17 00:00:00 2001 From: Marco Pagani Date: Wed, 23 Nov 2022 09:56:39 +0100 Subject: [PATCH 0749/1480] habanalabs/gaudi2: added memset for the cq_size register The clang-analyzer reported a warning: "Value stored to 'cq_size_addr' is never read". The cq_size register of dcore0 is not being zeroed using gaudi2_memset_device_lbw(), along with the other cq_* registers, even though the corresponding cq_size_addr variable is set. Signed-off-by: Marco Pagani Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi2/gaudi2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index c14e63164a848..a33a9072fca4b 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -9386,6 +9386,7 @@ static void gaudi2_restore_user_sm_registers(struct hl_device *hdev) gaudi2_memset_device_lbw(hdev, cq_lbw_data_addr, size, 0); gaudi2_memset_device_lbw(hdev, cq_base_l_addr, size, 0); gaudi2_memset_device_lbw(hdev, cq_base_h_addr, size, 0); + gaudi2_memset_device_lbw(hdev, cq_size_addr, size, 0); cq_lbw_l_addr = mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_L_0 + DCORE_OFFSET; cq_lbw_h_addr = mmDCORE0_SYNC_MNGR_GLBL_LBW_ADDR_H_0 + DCORE_OFFSET; -- GitLab From 56fb517775f4d71dbca2b1fb3562276138361072 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Fri, 18 Nov 2022 15:08:33 +0200 Subject: [PATCH 0750/1480] habanalabs: fix rc when new CPUCP opcodes are not supported When the new CPUCP opcodes are not supported and a CPUCP packet fails, the return value is the F/W error resposone which is a positive value. If this packet is sent from IOCTL and the positive value is used, the ICOTL will not be considered as unsuccessful. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index c0909d76d6eb2..cf8147e438335 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -324,6 +324,7 @@ int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, if (!prop->supports_advanced_cpucp_rc) { dev_dbg(hdev->dev, "F/W ERROR %d for CPU packet %d\n", rc, opcode); + rc = -EIO; goto scrub_descriptor; } -- GitLab From 0abcae8b48850e0f488d0eb7232323d93bdc4b13 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Sun, 30 Oct 2022 16:49:42 +0200 Subject: [PATCH 0751/1480] habanalabs: add RMWREG32_SHIFTED to set a val within a mask This is similar to RMWREG32, but the given 'val' is already shifted according to the mask. This allows several 'ORed' vals and masks to be set at once The patch also fixes wrong usage of RMWREG32 by replacing it with RMWREG32_SHIFTED Signed-off-by: Dafna Hirschfeld Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs.h | 10 +++------- drivers/misc/habanalabs/gaudi2/gaudi2.c | 6 +++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index e7f89868428d6..0329a0980bb72 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2498,13 +2498,9 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); #define WREG32_AND(reg, and) WREG32_P(reg, 0, and) #define WREG32_OR(reg, or) WREG32_P(reg, or, ~(or)) -#define RMWREG32(reg, val, mask) \ - do { \ - u32 tmp_ = RREG32(reg); \ - tmp_ &= ~(mask); \ - tmp_ |= ((val) << __ffs(mask)); \ - WREG32(reg, tmp_); \ - } while (0) +#define RMWREG32_SHIFTED(reg, val, mask) WREG32_P(reg, val, ~(mask)) + +#define RMWREG32(reg, val, mask) RMWREG32_SHIFTED(reg, (val) << __ffs(mask), mask) #define RREG32_MASK(reg, mask) ((RREG32(reg) & mask) >> __ffs(mask)) diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index a33a9072fca4b..e793fb2bdcbe6 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -5052,7 +5052,7 @@ static int gaudi2_pci_mmu_init(struct hl_device *hdev) mmu_base = mmPMMU_HBW_MMU_BASE; stlb_base = mmPMMU_HBW_STLB_BASE; - RMWREG32(stlb_base + STLB_HOP_CONFIGURATION_OFFSET, + RMWREG32_SHIFTED(stlb_base + STLB_HOP_CONFIGURATION_OFFSET, (0 << PMMU_HBW_STLB_HOP_CONFIGURATION_FIRST_HOP_SHIFT) | (5 << PMMU_HBW_STLB_HOP_CONFIGURATION_FIRST_LOOKUP_HOP_SMALL_P_SHIFT) | (4 << PMMU_HBW_STLB_HOP_CONFIGURATION_FIRST_LOOKUP_HOP_LARGE_P_SHIFT) | @@ -5068,7 +5068,7 @@ static int gaudi2_pci_mmu_init(struct hl_device *hdev) if (PAGE_SIZE == SZ_64K) { /* Set page sizes to 64K on hop5 and 16M on hop4 + enable 8 bit hops */ - RMWREG32(mmu_base + MMU_STATIC_MULTI_PAGE_SIZE_OFFSET, + RMWREG32_SHIFTED(mmu_base + MMU_STATIC_MULTI_PAGE_SIZE_OFFSET, FIELD_PREP(DCORE0_HMMU0_MMU_STATIC_MULTI_PAGE_SIZE_HOP5_PAGE_SIZE_MASK, 4) | FIELD_PREP(DCORE0_HMMU0_MMU_STATIC_MULTI_PAGE_SIZE_HOP4_PAGE_SIZE_MASK, 3) | FIELD_PREP( @@ -5116,7 +5116,7 @@ static int gaudi2_dcore_hmmu_init(struct hl_device *hdev, int dcore_id, RMWREG32(mmu_base + MMU_STATIC_MULTI_PAGE_SIZE_OFFSET, 5 /* 64MB */, MMU_STATIC_MULTI_PAGE_SIZE_HOP4_PAGE_SIZE_MASK); - RMWREG32(stlb_base + STLB_HOP_CONFIGURATION_OFFSET, + RMWREG32_SHIFTED(stlb_base + STLB_HOP_CONFIGURATION_OFFSET, FIELD_PREP(DCORE0_HMMU0_STLB_HOP_CONFIGURATION_FIRST_HOP_MASK, 0) | FIELD_PREP(DCORE0_HMMU0_STLB_HOP_CONFIGURATION_FIRST_LOOKUP_HOP_SMALL_P_MASK, 3) | FIELD_PREP(DCORE0_HMMU0_STLB_HOP_CONFIGURATION_FIRST_LOOKUP_HOP_LARGE_P_MASK, 3) | -- GitLab From 408c46bd6eb7a4e2fb9fd686218e4a13b9de844c Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Mon, 14 Nov 2022 13:26:21 +0200 Subject: [PATCH 0752/1480] habanalabs: print context refcount value if hard reset fails Failing to kill a user process during a hard reset can be due to a reference to the user context which isn't released. To make it easier to understand if this the reason for the failure and not something else, add a print of the context refcount value. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index f5864893237cc..926f230def56b 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -696,10 +696,22 @@ static void device_hard_reset_pending(struct work_struct *work) flags = device_reset_work->flags | HL_DRV_RESET_FROM_RESET_THR; rc = hl_device_reset(hdev, flags); + if ((rc == -EBUSY) && !hdev->device_fini_pending) { - dev_info(hdev->dev, - "Could not reset device. will try again in %u seconds", - HL_PENDING_RESET_PER_SEC); + struct hl_ctx *ctx = hl_get_compute_ctx(hdev); + + if (ctx) { + /* The read refcount value should subtracted by one, because the read is + * protected with hl_get_compute_ctx(). + */ + dev_info(hdev->dev, + "Could not reset device (compute_ctx refcount %u). will try again in %u seconds", + kref_read(&ctx->refcount) - 1, HL_PENDING_RESET_PER_SEC); + hl_ctx_put(ctx); + } else { + dev_info(hdev->dev, "Could not reset device. will try again in %u seconds", + HL_PENDING_RESET_PER_SEC); + } queue_delayed_work(hdev->reset_wq, &device_reset_work->reset_work, msecs_to_jiffies(HL_PENDING_RESET_PER_SEC * 1000)); -- GitLab From 1f615120fc9d24a8df7f14b0d1e79f3402330855 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Wed, 16 Nov 2022 13:14:02 +0200 Subject: [PATCH 0753/1480] habanalabs: don't put context in hl_encaps_handle_do_release_sob() hl_encaps_handle_do_release_sob() can be called only when the last reference to the context object is released and hl_ctx_do_release() is initiated, and therefore it shouldn't call hl_ctx_put(). Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/context.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/habanalabs/common/context.c b/drivers/misc/habanalabs/common/context.c index 2f4620b7990c7..ba6675960203a 100644 --- a/drivers/misc/habanalabs/common/context.c +++ b/drivers/misc/habanalabs/common/context.c @@ -39,7 +39,6 @@ static void hl_encaps_handle_do_release_sob(struct kref *ref) idr_remove(&mgr->handles, handle->id); spin_unlock(&mgr->lock); - hl_ctx_put(handle->ctx); kfree(handle); } -- GitLab From 893afb248c7a1f24d17719a5e5f4fe4174ecb60c Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 17 Nov 2022 15:22:31 +0200 Subject: [PATCH 0754/1480] habanalabs: clear non-released encapsulated signals Reserved encapsulated signals which were not released hold the context refcount, leading to a failure when killing the user process on device reset or device fini. Add the release of these left signals in the CS roll-back process. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../habanalabs/common/command_submission.c | 46 ++++++++++++---- drivers/misc/habanalabs/common/context.c | 53 +++++++++++-------- drivers/misc/habanalabs/common/habanalabs.h | 3 +- 3 files changed, 71 insertions(+), 31 deletions(-) diff --git a/drivers/misc/habanalabs/common/command_submission.c b/drivers/misc/habanalabs/common/command_submission.c index f1c69c8ed74a6..ea0e5101c10ed 100644 --- a/drivers/misc/habanalabs/common/command_submission.c +++ b/drivers/misc/habanalabs/common/command_submission.c @@ -742,13 +742,11 @@ static void cs_do_release(struct kref *ref) */ if (hl_cs_cmpl->encaps_signals) kref_put(&hl_cs_cmpl->encaps_sig_hdl->refcount, - hl_encaps_handle_do_release); + hl_encaps_release_handle_and_put_ctx); } - if ((cs->type == CS_TYPE_WAIT || cs->type == CS_TYPE_COLLECTIVE_WAIT) - && cs->encaps_signals) - kref_put(&cs->encaps_sig_hdl->refcount, - hl_encaps_handle_do_release); + if ((cs->type == CS_TYPE_WAIT || cs->type == CS_TYPE_COLLECTIVE_WAIT) && cs->encaps_signals) + kref_put(&cs->encaps_sig_hdl->refcount, hl_encaps_release_handle_and_put_ctx); out: /* Must be called before hl_ctx_put because inside we use ctx to get @@ -1011,6 +1009,34 @@ static void cs_rollback(struct hl_device *hdev, struct hl_cs *cs) hl_complete_job(hdev, job); } +/* + * release_reserved_encaps_signals() - release reserved encapsulated signals. + * @hdev: pointer to habanalabs device structure + * + * Release reserved encapsulated signals which weren't un-reserved, or for which a CS with + * encapsulated signals wasn't submitted and thus weren't released as part of CS roll-back. + * For these signals need also to put the refcount of the H/W SOB which was taken at the + * reservation. + */ +static void release_reserved_encaps_signals(struct hl_device *hdev) +{ + struct hl_ctx *ctx = hl_get_compute_ctx(hdev); + struct hl_cs_encaps_sig_handle *handle; + struct hl_encaps_signals_mgr *mgr; + u32 id; + + if (!ctx) + return; + + mgr = &ctx->sig_mgr; + + idr_for_each_entry(&mgr->handles, handle, id) + if (handle->cs_seq == ULLONG_MAX) + kref_put(&handle->refcount, hl_encaps_release_handle_and_put_sob_ctx); + + hl_ctx_put(ctx); +} + void hl_cs_rollback_all(struct hl_device *hdev, bool skip_wq_flush) { int i; @@ -1039,6 +1065,8 @@ void hl_cs_rollback_all(struct hl_device *hdev, bool skip_wq_flush) } force_complete_multi_cs(hdev); + + release_reserved_encaps_signals(hdev); } static void @@ -2001,6 +2029,8 @@ static int cs_ioctl_reserve_signals(struct hl_fpriv *hpriv, */ handle->pre_sob_val = prop->next_sob_val - handle->count; + handle->cs_seq = ULLONG_MAX; + *signals_count = prop->next_sob_val; hdev->asic_funcs->hw_queues_unlock(hdev); @@ -2350,10 +2380,8 @@ put_cs: /* We finished with the CS in this function, so put the ref */ cs_put(cs); free_cs_chunk_array: - if (!wait_cs_submitted && cs_encaps_signals && handle_found && - is_wait_cs) - kref_put(&encaps_sig_hdl->refcount, - hl_encaps_handle_do_release); + if (!wait_cs_submitted && cs_encaps_signals && handle_found && is_wait_cs) + kref_put(&encaps_sig_hdl->refcount, hl_encaps_release_handle_and_put_ctx); kfree(cs_chunk_array); out: return rc; diff --git a/drivers/misc/habanalabs/common/context.c b/drivers/misc/habanalabs/common/context.c index ba6675960203a..9c8b1b37b510c 100644 --- a/drivers/misc/habanalabs/common/context.c +++ b/drivers/misc/habanalabs/common/context.c @@ -9,37 +9,46 @@ #include -void hl_encaps_handle_do_release(struct kref *ref) +static void encaps_handle_do_release(struct hl_cs_encaps_sig_handle *handle, bool put_hw_sob, + bool put_ctx) { - struct hl_cs_encaps_sig_handle *handle = - container_of(ref, struct hl_cs_encaps_sig_handle, refcount); struct hl_encaps_signals_mgr *mgr = &handle->ctx->sig_mgr; + if (put_hw_sob) + hw_sob_put(handle->hw_sob); + spin_lock(&mgr->lock); idr_remove(&mgr->handles, handle->id); spin_unlock(&mgr->lock); - hl_ctx_put(handle->ctx); + if (put_ctx) + hl_ctx_put(handle->ctx); + kfree(handle); } -static void hl_encaps_handle_do_release_sob(struct kref *ref) +void hl_encaps_release_handle_and_put_ctx(struct kref *ref) { struct hl_cs_encaps_sig_handle *handle = - container_of(ref, struct hl_cs_encaps_sig_handle, refcount); - struct hl_encaps_signals_mgr *mgr = &handle->ctx->sig_mgr; + container_of(ref, struct hl_cs_encaps_sig_handle, refcount); - /* if we're here, then there was a signals reservation but cs with - * encaps signals wasn't submitted, so need to put refcount - * to hw_sob taken at the reservation. - */ - hw_sob_put(handle->hw_sob); + encaps_handle_do_release(handle, false, true); +} - spin_lock(&mgr->lock); - idr_remove(&mgr->handles, handle->id); - spin_unlock(&mgr->lock); +static void hl_encaps_release_handle_and_put_sob(struct kref *ref) +{ + struct hl_cs_encaps_sig_handle *handle = + container_of(ref, struct hl_cs_encaps_sig_handle, refcount); - kfree(handle); + encaps_handle_do_release(handle, true, false); +} + +void hl_encaps_release_handle_and_put_sob_ctx(struct kref *ref) +{ + struct hl_cs_encaps_sig_handle *handle = + container_of(ref, struct hl_cs_encaps_sig_handle, refcount); + + encaps_handle_do_release(handle, true, true); } static void hl_encaps_sig_mgr_init(struct hl_encaps_signals_mgr *mgr) @@ -48,8 +57,7 @@ static void hl_encaps_sig_mgr_init(struct hl_encaps_signals_mgr *mgr) idr_init(&mgr->handles); } -static void hl_encaps_sig_mgr_fini(struct hl_device *hdev, - struct hl_encaps_signals_mgr *mgr) +static void hl_encaps_sig_mgr_fini(struct hl_device *hdev, struct hl_encaps_signals_mgr *mgr) { struct hl_cs_encaps_sig_handle *handle; struct idr *idp; @@ -57,11 +65,14 @@ static void hl_encaps_sig_mgr_fini(struct hl_device *hdev, idp = &mgr->handles; + /* The IDR is expected to be empty at this stage, because any left signal should have been + * released as part of CS roll-back. + */ if (!idr_is_empty(idp)) { - dev_warn(hdev->dev, "device released while some encaps signals handles are still allocated\n"); + dev_warn(hdev->dev, + "device released while some encaps signals handles are still allocated\n"); idr_for_each_entry(idp, handle, id) - kref_put(&handle->refcount, - hl_encaps_handle_do_release_sob); + kref_put(&handle->refcount, hl_encaps_release_handle_and_put_sob); } idr_destroy(&mgr->handles); diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 0329a0980bb72..e2527d976ee05 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -3775,7 +3775,8 @@ void hl_sysfs_add_dev_vrm_attr(struct hl_device *hdev, struct attribute_group *d void hw_sob_get(struct hl_hw_sob *hw_sob); void hw_sob_put(struct hl_hw_sob *hw_sob); -void hl_encaps_handle_do_release(struct kref *ref); +void hl_encaps_release_handle_and_put_ctx(struct kref *ref); +void hl_encaps_release_handle_and_put_sob_ctx(struct kref *ref); void hl_hw_queue_encaps_sig_set_sob_info(struct hl_device *hdev, struct hl_cs *cs, struct hl_cs_job *job, struct hl_cs_compl *cs_cmpl); -- GitLab From 1b18cf33d6ce63a9f5fe3764d7b20c4738dd1245 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Thu, 17 Nov 2022 18:57:49 +0200 Subject: [PATCH 0755/1480] habanalabs: make print of engines idle mask more readable The engines idle mask was increased to be an array of 4 u64 entries. To make the print of this mask more readable, remove the "0x" prefix, and zero-pad each u64 to 16 bytes if either it isn't zero or if any of the higher-order u64's is not zero. Signed-off-by: Tomer Tayar Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 27 +++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 926f230def56b..87ab329e65d49 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -386,6 +386,23 @@ bool hl_ctrl_device_operational(struct hl_device *hdev, } } +static void print_idle_status_mask(struct hl_device *hdev, const char *message, + u64 idle_mask[HL_BUSY_ENGINES_MASK_EXT_SIZE]) +{ + u32 pad_width[HL_BUSY_ENGINES_MASK_EXT_SIZE] = {}; + + BUILD_BUG_ON(HL_BUSY_ENGINES_MASK_EXT_SIZE != 4); + + pad_width[3] = idle_mask[3] ? 16 : 0; + pad_width[2] = idle_mask[2] || pad_width[3] ? 16 : 0; + pad_width[1] = idle_mask[1] || pad_width[2] ? 16 : 0; + pad_width[0] = idle_mask[0] || pad_width[1] ? 16 : 0; + + dev_err(hdev->dev, "%s (mask %0*llx_%0*llx_%0*llx_%0*llx)\n", + message, pad_width[3], idle_mask[3], pad_width[2], idle_mask[2], + pad_width[1], idle_mask[1], pad_width[0], idle_mask[0]); +} + static void hpriv_release(struct kref *ref) { u64 idle_mask[HL_BUSY_ENGINES_MASK_EXT_SIZE] = {0}; @@ -416,9 +433,8 @@ static void hpriv_release(struct kref *ref) device_is_idle = hdev->asic_funcs->is_device_idle(hdev, idle_mask, HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL); if (!device_is_idle) { - dev_err(hdev->dev, - "device not idle after user context is closed (0x%llx_%llx_%llx_%llx)\n", - idle_mask[3], idle_mask[2], idle_mask[1], idle_mask[0]); + print_idle_status_mask(hdev, "device is not idle after user context is closed", + idle_mask); reset_device = true; } @@ -1673,9 +1689,8 @@ kill_processes: /* If device is not idle fail the reset process */ if (!hdev->asic_funcs->is_device_idle(hdev, idle_mask, - HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL)) { - dev_err(hdev->dev, "device is not idle (mask 0x%llx_%llx_%llx_%llx) after reset\n", - idle_mask[3], idle_mask[2], idle_mask[1], idle_mask[0]); + HL_BUSY_ENGINES_MASK_EXT_SIZE, NULL)) { + print_idle_status_mask(hdev, "device is not idle after reset", idle_mask); rc = -EIO; goto out_err; } -- GitLab From 5354a2a0018345774ab2517fc2fe107a6cd894fa Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Tue, 22 Nov 2022 09:59:27 +0200 Subject: [PATCH 0756/1480] habanalabs: fail driver load if EEPROM errors detected In case EEPROM is not burned, firmware sets default EEPROM values. As this is not valid in production, driver should fail load upon any EEPROM error reported by firmware. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 23 ++++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index cf8147e438335..228b92278e480 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -617,16 +617,12 @@ static bool fw_report_boot_dev0(struct hl_device *hdev, u32 err_val, if (sts_val & CPU_BOOT_DEV_STS0_ENABLED) dev_dbg(hdev->dev, "Device status0 %#x\n", sts_val); - /* All warnings should go here in order not to reach the unknown error validation */ if (err_val & CPU_BOOT_ERR0_EEPROM_FAIL) { - dev_warn(hdev->dev, - "Device boot warning - EEPROM failure detected, default settings applied\n"); - /* This is a warning so we don't want it to disable the - * device - */ - err_val &= ~CPU_BOOT_ERR0_EEPROM_FAIL; + dev_err(hdev->dev, "Device boot error - EEPROM failure detected\n"); + err_exists = true; } + /* All warnings should go here in order not to reach the unknown error validation */ if (err_val & CPU_BOOT_ERR0_DRAM_SKIPPED) { dev_warn(hdev->dev, "Device boot warning - Skipped DRAM initialization\n"); @@ -2532,7 +2528,7 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev, struct fw_load_mgr *fw_loader) { struct cpu_dyn_regs *dyn_regs; - int rc; + int rc, fw_error_rc; dev_info(hdev->dev, "Loading %sfirmware to device, may take some time...\n", @@ -2632,14 +2628,17 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev, hl_fw_dynamic_update_linux_interrupt_if(hdev); - return 0; - protocol_err: - if (fw_loader->dynamic_loader.fw_desc_valid) - fw_read_errors(hdev, le32_to_cpu(dyn_regs->cpu_boot_err0), + if (fw_loader->dynamic_loader.fw_desc_valid) { + fw_error_rc = fw_read_errors(hdev, le32_to_cpu(dyn_regs->cpu_boot_err0), le32_to_cpu(dyn_regs->cpu_boot_err1), le32_to_cpu(dyn_regs->cpu_boot_dev_sts0), le32_to_cpu(dyn_regs->cpu_boot_dev_sts1)); + + if (fw_error_rc) + return fw_error_rc; + } + return rc; } -- GitLab From 19a17a9fb486b2961dbd7f3fff0d79a144c9a3b6 Mon Sep 17 00:00:00 2001 From: Ohad Sharabi Date: Sun, 20 Nov 2022 15:12:26 +0200 Subject: [PATCH 0757/1480] habanalabs: fix VA range calculation Current implementation is fixing the page size to PAGE_SIZE whereas the input page size may be different. Signed-off-by: Ohad Sharabi Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/memory.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index 541e1b6a2176d..7c5c18be294a8 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -2508,24 +2508,20 @@ static int va_range_init(struct hl_device *hdev, struct hl_va_range **va_ranges, /* * PAGE_SIZE alignment - * it is the callers responsibility to align the addresses if the + * it is the caller's responsibility to align the addresses if the * page size is not a power of 2 */ if (is_power_of_2(page_size)) { - if (start & (PAGE_SIZE - 1)) { - start &= PAGE_MASK; - start += PAGE_SIZE; - } + start = round_up(start, page_size); /* * The end of the range is inclusive, hence we need to align it * to the end of the last full page in the range. For example if * end = 0x3ff5 with page size 0x1000, we need to align it to - * 0x2fff. The remainig 0xff5 bytes do not form a full page. + * 0x2fff. The remaining 0xff5 bytes do not form a full page. */ - if ((end + 1) & (PAGE_SIZE - 1)) - end = ((end + 1) & PAGE_MASK) - 1; + end = round_down(end + 1, page_size) - 1; } if (start >= end) { -- GitLab From 24b3e3dd9c9c742a4dd18e71b6963f9e7ab72911 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 11 Nov 2022 19:14:56 -0800 Subject: [PATCH 0758/1480] kernfs: fix all kernel-doc warnings and multiple typos Fix kernel-doc warnings. Many of these are about a function's return value, so use the kernel-doc Return: format to fix those Use % prefix on numeric constant values. dir.c: fix typos/spellos file.c fix typo: s/taret/target/ Fix all of these kernel-doc warnings: dir.c:305: warning: missing initial short description on line: * kernfs_name_hash dir.c:137: warning: No description found for return value of 'kernfs_path_from_node_locked' dir.c:196: warning: No description found for return value of 'kernfs_name' dir.c:224: warning: No description found for return value of 'kernfs_path_from_node' dir.c:292: warning: No description found for return value of 'kernfs_get_parent' dir.c:312: warning: No description found for return value of 'kernfs_name_hash' dir.c:404: warning: No description found for return value of 'kernfs_unlink_sibling' dir.c:588: warning: No description found for return value of 'kernfs_node_from_dentry' dir.c:806: warning: No description found for return value of 'kernfs_find_ns' dir.c:879: warning: No description found for return value of 'kernfs_find_and_get_ns' dir.c:904: warning: No description found for return value of 'kernfs_walk_and_get_ns' dir.c:927: warning: No description found for return value of 'kernfs_create_root' dir.c:996: warning: No description found for return value of 'kernfs_root_to_node' dir.c:1016: warning: No description found for return value of 'kernfs_create_dir_ns' dir.c:1048: warning: No description found for return value of 'kernfs_create_empty_dir' dir.c:1306: warning: No description found for return value of 'kernfs_next_descendant_post' dir.c:1568: warning: No description found for return value of 'kernfs_remove_self' dir.c:1630: warning: No description found for return value of 'kernfs_remove_by_name_ns' dir.c:1667: warning: No description found for return value of 'kernfs_rename_ns' file.c:66: warning: No description found for return value of 'of_on' file.c:88: warning: No description found for return value of 'kernfs_deref_open_node_locked' file.c:1036: warning: No description found for return value of '__kernfs_create_file' inode.c:100: warning: No description found for return value of 'kernfs_setattr' mount.c:160: warning: No description found for return value of 'kernfs_root_from_sb' mount.c:198: warning: No description found for return value of 'kernfs_node_dentry' mount.c:302: warning: No description found for return value of 'kernfs_super_ns' mount.c:318: warning: No description found for return value of 'kernfs_get_tree' symlink.c:28: warning: No description found for return value of 'kernfs_create_link' Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Tejun Heo Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20221112031456.22980-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 82 ++++++++++++++++++++++--------------- fs/kernfs/file.c | 18 ++++---- fs/kernfs/inode.c | 8 ++-- fs/kernfs/kernfs-internal.h | 2 +- fs/kernfs/mount.c | 10 +++-- fs/kernfs/symlink.c | 2 +- 6 files changed, 74 insertions(+), 48 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 77d7a3a280571..935ef8cb02b26 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -125,9 +125,9 @@ static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a, * kn_to: /n1/n2/n3 [depth=3] * result: /../.. * - * [3] when @kn_to is NULL result will be "(null)" + * [3] when @kn_to is %NULL result will be "(null)" * - * Returns the length of the full path. If the full length is equal to or + * Return: the length of the full path. If the full length is equal to or * greater than @buflen, @buf contains the truncated path with the trailing * '\0'. On error, -errno is returned. */ @@ -185,10 +185,12 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to, * @buflen: size of @buf * * Copies the name of @kn into @buf of @buflen bytes. The behavior is - * similar to strlcpy(). It returns the length of @kn's name and if @buf - * isn't long enough, it's filled upto @buflen-1 and nul terminated. + * similar to strlcpy(). * - * Fills buffer with "(null)" if @kn is NULL. + * Fills buffer with "(null)" if @kn is %NULL. + * + * Return: the length of @kn's name and if @buf isn't long enough, + * it's filled up to @buflen-1 and nul terminated. * * This function can be called from any context. */ @@ -215,7 +217,7 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) * path (which includes '..'s) as needed to reach from @from to @to is * returned. * - * Returns the length of the full path. If the full length is equal to or + * Return: the length of the full path. If the full length is equal to or * greater than @buflen, @buf contains the truncated path with the trailing * '\0'. On error, -errno is returned. */ @@ -287,6 +289,8 @@ out: * * Determines @kn's parent, pins and returns it. This function can be * called from any context. + * + * Return: parent node of @kn */ struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn) { @@ -302,11 +306,11 @@ struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn) } /** - * kernfs_name_hash + * kernfs_name_hash - calculate hash of @ns + @name * @name: Null terminated string to hash * @ns: Namespace tag to hash * - * Returns 31 bit hash of ns + name (so it fits in an off_t ) + * Return: 31-bit hash of ns + name (so it fits in an off_t) */ static unsigned int kernfs_name_hash(const char *name, const void *ns) { @@ -354,8 +358,8 @@ static int kernfs_sd_compare(const struct kernfs_node *left, * Locking: * kernfs_rwsem held exclusive * - * RETURNS: - * 0 on susccess -EEXIST on failure. + * Return: + * %0 on success, -EEXIST on failure. */ static int kernfs_link_sibling(struct kernfs_node *kn) { @@ -394,8 +398,10 @@ static int kernfs_link_sibling(struct kernfs_node *kn) * @kn: kernfs_node of interest * * Try to unlink @kn from its sibling rbtree which starts from - * kn->parent->dir.children. Returns %true if @kn was actually - * removed, %false if @kn wasn't on the rbtree. + * kn->parent->dir.children. + * + * Return: %true if @kn was actually removed, + * %false if @kn wasn't on the rbtree. * * Locking: * kernfs_rwsem held exclusive @@ -419,10 +425,10 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn) * @kn: kernfs_node to get an active reference to * * Get an active reference of @kn. This function is noop if @kn - * is NULL. + * is %NULL. * - * RETURNS: - * Pointer to @kn on success, NULL on failure. + * Return: + * Pointer to @kn on success, %NULL on failure. */ struct kernfs_node *kernfs_get_active(struct kernfs_node *kn) { @@ -442,7 +448,7 @@ struct kernfs_node *kernfs_get_active(struct kernfs_node *kn) * @kn: kernfs_node to put an active reference to * * Put an active reference to @kn. This function is noop if @kn - * is NULL. + * is %NULL. */ void kernfs_put_active(struct kernfs_node *kn) { @@ -464,7 +470,7 @@ void kernfs_put_active(struct kernfs_node *kn) * kernfs_drain - drain kernfs_node * @kn: kernfs_node to drain * - * Drain existing usages and nuke all existing mmaps of @kn. Mutiple + * Drain existing usages and nuke all existing mmaps of @kn. Multiple * removers may invoke this function concurrently on @kn and all will * return after draining is complete. */ @@ -577,7 +583,7 @@ EXPORT_SYMBOL_GPL(kernfs_put); * kernfs_node_from_dentry - determine kernfs_node associated with a dentry * @dentry: the dentry in question * - * Return the kernfs_node associated with @dentry. If @dentry is not a + * Return: the kernfs_node associated with @dentry. If @dentry is not a * kernfs one, %NULL is returned. * * While the returned kernfs_node will stay accessible as long as @dentry @@ -684,8 +690,8 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, * @id's lower 32bits encode ino and upper gen. If the gen portion is * zero, all generations are matched. * - * RETURNS: - * NULL on failure. Return a kernfs node with reference counter incremented + * Return: %NULL on failure, + * otherwise a kernfs node with reference counter incremented. */ struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root, u64 id) @@ -733,8 +739,8 @@ err_unlock: * function increments nlink of the parent's inode if @kn is a * directory and link into the children list of the parent. * - * RETURNS: - * 0 on success, -EEXIST if entry with the given name already + * Return: + * %0 on success, -EEXIST if entry with the given name already * exists. */ int kernfs_add_one(struct kernfs_node *kn) @@ -797,8 +803,9 @@ out_unlock: * @name: name to look for * @ns: the namespace tag to use * - * Look for kernfs_node with name @name under @parent. Returns pointer to - * the found kernfs_node on success, %NULL on failure. + * Look for kernfs_node with name @name under @parent. + * + * Return: pointer to the found kernfs_node on success, %NULL on failure. */ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, const unsigned char *name, @@ -871,8 +878,9 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent, * @ns: the namespace tag to use * * Look for kernfs_node with name @name under @parent and get a reference - * if found. This function may sleep and returns pointer to the found - * kernfs_node on success, %NULL on failure. + * if found. This function may sleep. + * + * Return: pointer to the found kernfs_node on success, %NULL on failure. */ struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name, const void *ns) @@ -896,8 +904,9 @@ EXPORT_SYMBOL_GPL(kernfs_find_and_get_ns); * @ns: the namespace tag to use * * Look for kernfs_node with path @path under @parent and get a reference - * if found. This function may sleep and returns pointer to the found - * kernfs_node on success, %NULL on failure. + * if found. This function may sleep. + * + * Return: pointer to the found kernfs_node on success, %NULL on failure. */ struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent, const char *path, const void *ns) @@ -919,7 +928,7 @@ struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent, * @flags: KERNFS_ROOT_* flags * @priv: opaque data associated with the new directory * - * Returns the root of the new hierarchy on success, ERR_PTR() value on + * Return: the root of the new hierarchy on success, ERR_PTR() value on * failure. */ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, @@ -991,6 +1000,8 @@ void kernfs_destroy_root(struct kernfs_root *root) /** * kernfs_root_to_node - return the kernfs_node associated with a kernfs_root * @root: root to use to lookup + * + * Return: @root's kernfs_node */ struct kernfs_node *kernfs_root_to_node(struct kernfs_root *root) { @@ -1007,7 +1018,7 @@ struct kernfs_node *kernfs_root_to_node(struct kernfs_root *root) * @priv: opaque data associated with the new directory * @ns: optional namespace tag of the directory * - * Returns the created node on success, ERR_PTR() value on failure. + * Return: the created node on success, ERR_PTR() value on failure. */ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, @@ -1041,7 +1052,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, * @parent: parent in which to create a new directory * @name: name of the new directory * - * Returns the created node on success, ERR_PTR() value on failure. + * Return: the created node on success, ERR_PTR() value on failure. */ struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, const char *name) @@ -1300,6 +1311,8 @@ static struct kernfs_node *kernfs_leftmost_descendant(struct kernfs_node *pos) * Find the next descendant to visit for post-order traversal of @root's * descendants. @root is included in the iteration and the last node to be * visited. + * + * Return: the next descendant to visit or %NULL when done. */ static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos, struct kernfs_node *root) @@ -1563,6 +1576,8 @@ void kernfs_unbreak_active_protection(struct kernfs_node *kn) * the whole kernfs_ops which won the arbitration. This can be used to * guarantee, for example, all concurrent writes to a "delete" file to * finish only after the whole operation is complete. + * + * Return: %true if @kn is removed by this call, otherwise %false. */ bool kernfs_remove_self(struct kernfs_node *kn) { @@ -1623,7 +1638,8 @@ bool kernfs_remove_self(struct kernfs_node *kn) * @ns: namespace tag of the kernfs_node to remove * * Look for the kernfs_node with @name and @ns under @parent and remove it. - * Returns 0 on success, -ENOENT if such entry doesn't exist. + * + * Return: %0 on success, -ENOENT if such entry doesn't exist. */ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns) @@ -1661,6 +1677,8 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, * @new_parent: new parent to put @sd under * @new_name: new name * @new_ns: new namespace tag + * + * Return: %0 on success, -errno on failure. */ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, const char *new_name, const void *new_ns) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 9ab6c92e02dab..e4a50e4ff0d23 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -33,7 +33,7 @@ struct kernfs_open_node { * pending queue is implemented as a singly linked list of kernfs_nodes. * The list is terminated with the self pointer so that whether a * kernfs_node is on the list or not can be determined by testing the next - * pointer for NULL. + * pointer for %NULL. */ #define KERNFS_NOTIFY_EOL ((void *)&kernfs_notify_list) @@ -59,8 +59,10 @@ static inline struct mutex *kernfs_open_file_mutex_lock(struct kernfs_node *kn) } /** - * of_on - Return the kernfs_open_node of the specified kernfs_open_file - * @of: taret kernfs_open_file + * of_on - Get the kernfs_open_node of the specified kernfs_open_file + * @of: target kernfs_open_file + * + * Return: the kernfs_open_node of the kernfs_open_file */ static struct kernfs_open_node *of_on(struct kernfs_open_file *of) { @@ -82,6 +84,8 @@ static struct kernfs_open_node *of_on(struct kernfs_open_file *of) * outside RCU read-side critical section. * * The caller needs to make sure that kernfs_open_file_mutex is held. + * + * Return: @kn->attr.open when kernfs_open_file_mutex is held. */ static struct kernfs_open_node * kernfs_deref_open_node_locked(struct kernfs_node *kn) @@ -548,11 +552,11 @@ out_unlock: * If @kn->attr.open exists, increment its reference count; otherwise, * create one. @of is chained to the files list. * - * LOCKING: + * Locking: * Kernel thread context (may sleep). * - * RETURNS: - * 0 on success, -errno on failure. + * Return: + * %0 on success, -errno on failure. */ static int kernfs_get_open_node(struct kernfs_node *kn, struct kernfs_open_file *of) @@ -1024,7 +1028,7 @@ const struct file_operations kernfs_file_fops = { * @ns: optional namespace tag of the file * @key: lockdep key for the file's active_ref, %NULL to disable lockdep * - * Returns the created node on success, ERR_PTR() value on error. + * Return: the created node on success, ERR_PTR() value on error. */ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, const char *name, diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 74f3453f4639f..eac0f210299a0 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -94,7 +94,7 @@ int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) * @kn: target node * @iattr: iattr to set * - * Returns 0 on success, -errno on failure. + * Return: %0 on success, -errno on failure. */ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { @@ -239,11 +239,11 @@ static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode) * allocated and basics are initialized. New inode is returned * locked. * - * LOCKING: + * Locking: * Kernel thread context (may sleep). * - * RETURNS: - * Pointer to allocated inode on success, NULL on failure. + * Return: + * Pointer to allocated inode on success, %NULL on failure. */ struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn) { diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index fc5821effd97d..9046d9f39e635 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -58,7 +58,7 @@ struct kernfs_root { * kernfs_root - find out the kernfs_root a kernfs_node belongs to * @kn: kernfs_node of interest * - * Return the kernfs_root @kn belongs to. + * Return: the kernfs_root @kn belongs to. */ static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) { diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index d0859f72d2d64..e08e8d9998070 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -153,7 +153,7 @@ static const struct export_operations kernfs_export_ops = { * kernfs_root_from_sb - determine kernfs_root associated with a super_block * @sb: the super_block in question * - * Return the kernfs_root associated with @sb. If @sb is not a kernfs one, + * Return: the kernfs_root associated with @sb. If @sb is not a kernfs one, * %NULL is returned. */ struct kernfs_root *kernfs_root_from_sb(struct super_block *sb) @@ -167,7 +167,7 @@ struct kernfs_root *kernfs_root_from_sb(struct super_block *sb) * find the next ancestor in the path down to @child, where @parent was the * ancestor whose descendant we want to find. * - * Say the path is /a/b/c/d. @child is d, @parent is NULL. We return the root + * Say the path is /a/b/c/d. @child is d, @parent is %NULL. We return the root * node. If @parent is b, then we return the node for c. * Passing in d as @parent is not ok. */ @@ -192,6 +192,8 @@ static struct kernfs_node *find_next_ancestor(struct kernfs_node *child, * kernfs_node_dentry - get a dentry for the given kernfs_node * @kn: kernfs_node for which a dentry is needed * @sb: the kernfs super_block + * + * Return: the dentry pointer */ struct dentry *kernfs_node_dentry(struct kernfs_node *kn, struct super_block *sb) @@ -296,7 +298,7 @@ static int kernfs_set_super(struct super_block *sb, struct fs_context *fc) * kernfs_super_ns - determine the namespace tag of a kernfs super_block * @sb: super_block of interest * - * Return the namespace tag associated with kernfs super_block @sb. + * Return: the namespace tag associated with kernfs super_block @sb. */ const void *kernfs_super_ns(struct super_block *sb) { @@ -313,6 +315,8 @@ const void *kernfs_super_ns(struct super_block *sb) * implementation, which should set the specified ->@fs_type and ->@flags, and * specify the hierarchy and namespace tag to mount via ->@root and ->@ns, * respectively. + * + * Return: %0 on success, -errno on failure. */ int kernfs_get_tree(struct fs_context *fc) { diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 0ab13824822f7..45371a70caa71 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -19,7 +19,7 @@ * @name: name of the symlink * @target: target node for the symlink to point to * - * Returns the created node on success, ERR_PTR() value on error. + * Return: the created node on success, ERR_PTR() value on error. * Ownership of the link matches ownership of the target. */ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, -- GitLab From 40eb28dc17f87cfac69d7755447039e92ac5fbda Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 22 Nov 2022 15:35:57 +0200 Subject: [PATCH 0759/1480] device property: Get rid of __PROPERTY_ENTRY_ARRAY_EL*SIZE*() First of all, _ELEMENT_SIZE() repeats existing sizeof_field() macro. Second, usage of _ARRAY_ELSIZE_LEN() adds unnecessary indirection to the data layout. It's more understandable when the data structure is placed explicitly. That said, get rid of those macros by replacing them with the existing helper and explicit data structure layout. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221122133600.49897-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/property.h | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/include/linux/property.h b/include/linux/property.h index 83674f968a8fd..04a6b1433cd93 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -12,6 +12,7 @@ #include #include +#include #include struct device; @@ -303,24 +304,14 @@ struct property_entry { * crafted to avoid gcc-4.4.4's problems with initialization of anon unions * and structs. */ - -#define __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_) \ - sizeof(((struct property_entry *)NULL)->value._elem_[0]) - -#define __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, _elsize_, _Type_, \ - _val_, _len_) \ -(struct property_entry) { \ - .name = _name_, \ - .length = (_len_) * (_elsize_), \ - .type = DEV_PROP_##_Type_, \ - { .pointer = _val_ }, \ +#define __PROPERTY_ENTRY_ARRAY_LEN(_name_, _elem_, _Type_, _val_, _len_) \ +(struct property_entry) { \ + .name = _name_, \ + .length = (_len_) * sizeof_field(struct property_entry, value._elem_[0]), \ + .type = DEV_PROP_##_Type_, \ + { .pointer = _val_ }, \ } -#define __PROPERTY_ENTRY_ARRAY_LEN(_name_, _elem_, _Type_, _val_, _len_)\ - __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, \ - __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_), \ - _Type_, _val_, _len_) - #define PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, _len_) \ __PROPERTY_ENTRY_ARRAY_LEN(_name_, u8_data, U8, _val_, _len_) #define PROPERTY_ENTRY_U16_ARRAY_LEN(_name_, _val_, _len_) \ @@ -332,9 +323,12 @@ struct property_entry { #define PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, _len_) \ __PROPERTY_ENTRY_ARRAY_LEN(_name_, str, STRING, _val_, _len_) #define PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, _len_) \ - __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, \ - sizeof(struct software_node_ref_args), \ - REF, _val_, _len_) +(struct property_entry) { \ + .name = _name_, \ + .length = (_len_) * sizeof(struct software_node_ref_args), \ + .type = DEV_PROP_REF, \ + { .pointer = _val_ }, \ +} #define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \ PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_)) @@ -352,7 +346,7 @@ struct property_entry { #define __PROPERTY_ENTRY_ELEMENT(_name_, _elem_, _Type_, _val_) \ (struct property_entry) { \ .name = _name_, \ - .length = __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_), \ + .length = sizeof_field(struct property_entry, value._elem_[0]), \ .is_inline = true, \ .type = DEV_PROP_##_Type_, \ { .value = { ._elem_[0] = _val_ } }, \ -- GitLab From c6c76563bd13871739539e20fd3116159e491f5b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 22 Nov 2022 15:35:58 +0200 Subject: [PATCH 0760/1480] device property: Move PROPERTY_ENTRY_BOOL() a bit down Let's order ARRAY and non-ARRAY macros in the same way. The PROPERTY_ENTRY_BOOL() is special, move it a bit down in the code so it won't break ordering of the rest. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221122133600.49897-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/property.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/property.h b/include/linux/property.h index 04a6b1433cd93..a1f846a151136 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -322,6 +322,7 @@ struct property_entry { __PROPERTY_ENTRY_ARRAY_LEN(_name_, u64_data, U64, _val_, _len_) #define PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, _len_) \ __PROPERTY_ENTRY_ARRAY_LEN(_name_, str, STRING, _val_, _len_) + #define PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, _len_) \ (struct property_entry) { \ .name = _name_, \ @@ -340,7 +341,7 @@ struct property_entry { PROPERTY_ENTRY_U64_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_)) #define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \ PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_)) -#define PROPERTY_ENTRY_REF_ARRAY(_name_, _val_) \ +#define PROPERTY_ENTRY_REF_ARRAY(_name_, _val_) \ PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_)) #define __PROPERTY_ENTRY_ELEMENT(_name_, _elem_, _Type_, _val_) \ @@ -363,12 +364,6 @@ struct property_entry { #define PROPERTY_ENTRY_STRING(_name_, _val_) \ __PROPERTY_ENTRY_ELEMENT(_name_, str, STRING, _val_) -#define PROPERTY_ENTRY_BOOL(_name_) \ -(struct property_entry) { \ - .name = _name_, \ - .is_inline = true, \ -} - #define PROPERTY_ENTRY_REF(_name_, _ref_, ...) \ (struct property_entry) { \ .name = _name_, \ @@ -377,9 +372,14 @@ struct property_entry { { .pointer = &SOFTWARE_NODE_REFERENCE(_ref_, ##__VA_ARGS__), }, \ } +#define PROPERTY_ENTRY_BOOL(_name_) \ +(struct property_entry) { \ + .name = _name_, \ + .is_inline = true, \ +} + struct property_entry * property_entries_dup(const struct property_entry *properties); - void property_entries_free(const struct property_entry *properties); bool device_dma_supported(const struct device *dev); -- GitLab From 4d57b4f215e8ba86c36540eaccd3b17bc5ee39c0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 22 Nov 2022 15:35:59 +0200 Subject: [PATCH 0761/1480] device property: Rename goto label to be more precise In the fwnode_property_match_string() the goto label out has an additional task. Rename the label to be more precise on what is going to happen if goto it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221122133600.49897-3-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index f7b5aa8fcf283..ed74083c179d8 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -482,12 +482,13 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode, ret = fwnode_property_read_string_array(fwnode, propname, values, nval); if (ret < 0) - goto out; + goto out_free; ret = match_string(values, nval, string); if (ret < 0) ret = -ENODATA; -out: + +out_free: kfree(values); return ret; } -- GitLab From 9dc5f12f95e00fb0e0500ea4a8da0c0f29e718cb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 22 Nov 2022 15:36:00 +0200 Subject: [PATCH 0762/1480] device property: Add a blank line in Kconfig of tests Seems the blank line to separate entries in Kconfig was missing. Add it. Signed-off-by: Andy Shevchenko Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221122133600.49897-4-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/test/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig index 2f3fa31a948e2..610a1ba7a467e 100644 --- a/drivers/base/test/Kconfig +++ b/drivers/base/test/Kconfig @@ -8,6 +8,7 @@ config TEST_ASYNC_DRIVER_PROBE The module name will be test_async_driver_probe.ko If unsure say N. + config DRIVER_PE_KUNIT_TEST bool "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS depends on KUNIT=y -- GitLab From 6865788f5ad998f261e37f6b029d61d3bb7dc373 Mon Sep 17 00:00:00 2001 From: Andra Paraschiv Date: Tue, 8 Nov 2022 20:59:12 +0200 Subject: [PATCH 0763/1480] MAINTAINERS: Update entries from the Nitro Enclaves section Update the list of maintainers for the Nitro Enclaves project. Alex (lexnv@) is not working at Amazon anymore and there will be the same case for me starting with 2023. Add a reference to the mailing list of the Nitro Enclaves development team. Signed-off-by: Andra Paraschiv Acked-by: Alexandru Vasile Link: https://lore.kernel.org/r/20221108185912.15792-1-andraprs@amazon.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 38bae79369a3c..33c76a218c0cc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14569,10 +14569,9 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git F: arch/nios2/ NITRO ENCLAVES (NE) -M: Andra Paraschiv -M: Alexandru Vasile M: Alexandru Ciobotaru L: linux-kernel@vger.kernel.org +L: The AWS Nitro Enclaves Team S: Supported W: https://aws.amazon.com/ec2/nitro/nitro-enclaves/ F: Documentation/virt/ne_overview.rst -- GitLab From 83f47eea742c1152c237398fc040ceba04fc5d76 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 16 Nov 2022 14:47:34 +0200 Subject: [PATCH 0764/1480] mei: add timeout to send When driver wakes up the firmware from the low power state, it is sending a memory ready message. The send is done via synchronous/blocking function to ensure that firmware is in ready state. However, in case of firmware undergoing reset send might be block forever. To address this issue a timeout is added to blocking write command on the internal bus. Introduce the __mei_cl_send_timeout function to use instead of __mei_cl_send in cases where timeout is required. The mei_cl_write has only two callers and there is no need to split it into two functions. Signed-off-by: Alexander Usyskin Link: https://lore.kernel.org/r/20221116124735.2493847-2-alexander.usyskin@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus-fixup.c | 7 +++++-- drivers/misc/mei/bus.c | 22 +++++++++++++++++++++- drivers/misc/mei/client.c | 20 ++++++++++++++++---- drivers/misc/mei/client.h | 2 +- drivers/misc/mei/main.c | 2 +- drivers/misc/mei/mei_dev.h | 2 ++ 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 71fbf0bc84532..90023c34666ea 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -188,17 +188,20 @@ static int mei_fwver(struct mei_cl_device *cldev) return ret; } +#define GFX_MEMORY_READY_TIMEOUT 200 /* timeout in milliseconds */ + static int mei_gfx_memory_ready(struct mei_cl_device *cldev) { struct mkhi_gfx_mem_ready req = {0}; - unsigned int mode = MEI_CL_IO_TX_INTERNAL; + unsigned int mode = MEI_CL_IO_TX_INTERNAL | MEI_CL_IO_TX_BLOCKING; req.hdr.group_id = MKHI_GROUP_ID_GFX; req.hdr.command = MKHI_GFX_MEMORY_READY_CMD_REQ; req.flags = MKHI_GFX_MEM_READY_PXP_ALLOWED; dev_dbg(&cldev->dev, "Sending memory ready command\n"); - return __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0, mode); + return __mei_cl_send_timeout(cldev->cl, (u8 *)&req, sizeof(req), 0, + mode, GFX_MEMORY_READY_TIMEOUT); } static void mei_mkhi_fix(struct mei_cl_device *cldev) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 46aa3554e97b0..fdb5f73316958 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -33,6 +33,26 @@ */ ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, unsigned int mode) +{ + return __mei_cl_send_timeout(cl, buf, length, vtag, mode, MAX_SCHEDULE_TIMEOUT); +} + +/** + * __mei_cl_send_timeout - internal client send (write) + * + * @cl: host client + * @buf: buffer to send + * @length: buffer length + * @vtag: virtual tag + * @mode: sending mode + * @timeout: send timeout in milliseconds. + * effective only for blocking writes: the MEI_CL_IO_TX_BLOCKING mode bit is set. + * set timeout to the MAX_SCHEDULE_TIMEOUT to maixum allowed wait. + * + * Return: written size bytes or < 0 on error + */ +ssize_t __mei_cl_send_timeout(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, + unsigned int mode, unsigned long timeout) { struct mei_device *bus; struct mei_cl_cb *cb; @@ -101,7 +121,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING); memcpy(cb->buf.data, buf, length); - rets = mei_cl_write(cl, cb); + rets = mei_cl_write(cl, cb, timeout); out: mutex_unlock(&bus->device_lock); diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 0b2fbe1335a77..b4c104907ce21 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1926,10 +1926,13 @@ err: * * @cl: host client * @cb: write callback with filled data + * @timeout: send timeout in milliseconds. + * effective only for blocking writes: the cb->blocking is set. + * set timeout to the MAX_SCHEDULE_TIMEOUT to maixum allowed wait. * * Return: number of bytes sent on success, <0 on failure. */ -ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) +ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long timeout) { struct mei_device *dev; struct mei_msg_data *buf; @@ -2056,11 +2059,20 @@ out: if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { mutex_unlock(&dev->device_lock); - rets = wait_event_interruptible(cl->tx_wait, - cl->writing_state == MEI_WRITE_COMPLETE || - (!mei_cl_is_connected(cl))); + rets = wait_event_interruptible_timeout(cl->tx_wait, + cl->writing_state == MEI_WRITE_COMPLETE || + (!mei_cl_is_connected(cl)), + msecs_to_jiffies(timeout)); mutex_lock(&dev->device_lock); + /* clean all queue on timeout as something fatal happened */ + if (rets == 0) { + rets = -ETIME; + mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); + mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); + } /* wait_event_interruptible returns -ERESTARTSYS */ + if (rets > 0) + rets = 0; if (rets) { if (signal_pending(current)) rets = -EINTR; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 418056fb1489c..9052860bcfe03 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -246,7 +246,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, struct list_head *cmpl_list); int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp); -ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb); +ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long timeout); int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct list_head *cmpl_list); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 930887e7e38d6..632d4ae21e465 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -383,7 +383,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - rets = mei_cl_write(cl, cb); + rets = mei_cl_write(cl, cb, MAX_SCHEDULE_TIMEOUT); out: mutex_unlock(&dev->device_lock); return rets; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 6bb3e1ba9ded4..c1618a44c5a4c 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -373,6 +373,8 @@ void mei_cl_bus_rescan_work(struct work_struct *work); void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, unsigned int mode); +ssize_t __mei_cl_send_timeout(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, + unsigned int mode, unsigned long timeout); ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, unsigned int mode, unsigned long timeout); bool mei_cl_bus_rx_event(struct mei_cl *cl); -- GitLab From 0ef77698b85603d21453daf32ae70f76ae62ccae Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 16 Nov 2022 14:47:35 +0200 Subject: [PATCH 0765/1480] mei: bus-fixup: change pxp mode only if message was sent Move PXP mode state machine to SETUP mode only if memory ready message sent successfully to the firmware. Leave it in INIT mode otherwise to allow try to send message later. Signed-off-by: Alexander Usyskin Link: https://lore.kernel.org/r/20221116124735.2493847-3-alexander.usyskin@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus-fixup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 90023c34666ea..6df7679d97391 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -266,12 +266,13 @@ static void mei_gsc_mkhi_fix_ver(struct mei_cl_device *cldev) if (cldev->bus->pxp_mode == MEI_DEV_PXP_INIT) { ret = mei_gfx_memory_ready(cldev); - if (ret < 0) + if (ret < 0) { dev_err(&cldev->dev, "memory ready command failed %d\n", ret); - else + } else { dev_dbg(&cldev->dev, "memory ready command sent\n"); + cldev->bus->pxp_mode = MEI_DEV_PXP_SETUP; + } /* we go to reset after that */ - cldev->bus->pxp_mode = MEI_DEV_PXP_SETUP; goto out; } -- GitLab From c002f04c0bc79ec00d4beb75fb631d5bf37419bd Mon Sep 17 00:00:00 2001 From: Eli Billauer Date: Thu, 17 Nov 2022 09:18:25 +0200 Subject: [PATCH 0766/1480] char: xillybus: Fix trivial bug with mutex @unit_mutex protects @unit from being freed, so obviously it should be released after @unit is used, and not before. This is a follow-up to commit 282a4b71816b ("char: xillybus: Prevent use-after-free due to race condition") which ensures, among others, the protection of @private_data after @unit_mutex has been released. Reported-by: Hyunwoo Kim Signed-off-by: Eli Billauer Link: https://lore.kernel.org/r/20221117071825.3942-1-eli.billauer@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/xillybus/xillybus_class.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c index 0f238648dcfe2..e9a288e61c156 100644 --- a/drivers/char/xillybus/xillybus_class.c +++ b/drivers/char/xillybus/xillybus_class.c @@ -227,14 +227,15 @@ int xillybus_find_inode(struct inode *inode, break; } - mutex_unlock(&unit_mutex); - - if (!unit) + if (!unit) { + mutex_unlock(&unit_mutex); return -ENODEV; + } *private_data = unit->private_data; *index = minor - unit->lowest_minor; + mutex_unlock(&unit_mutex); return 0; } EXPORT_SYMBOL(xillybus_find_inode); -- GitLab From adc40221bf676f3e722d135889a7b913b4162dc2 Mon Sep 17 00:00:00 2001 From: Yuma Ueda Date: Fri, 18 Nov 2022 22:36:31 +0900 Subject: [PATCH 0767/1480] scripts/kallsyms.c Make the comment up-to-date with current implementation The comment in scripts/kallsyms.c describing the usage of scripts/kallsyms does not reflect the latest implementation. Fix the comment to be equivalent to what the usage() function prints. Signed-off-by: Yuma Ueda Reviewed-by: Miguel Ojeda Link: https://lore.kernel.org/r/20221118133631.4554-1-cyan@0x00a1e9.dev Signed-off-by: Greg Kroah-Hartman --- scripts/kallsyms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 03fa07ad45d95..46d1afaaf4cd0 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -5,7 +5,8 @@ * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * - * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S + * Usage: kallsyms [--all-symbols] [--absolute-percpu] + * [--base-relative] in.map > out.S * * Table compression uses all the unused char codes on the symbols and * maps these to the most used substrings (tokens). For instance, it might -- GitLab From e6278a5445780c71cc3dfc6ceda2875838eac8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 22 Nov 2022 14:46:43 +0100 Subject: [PATCH 0768/1480] virtio_console: Introduce an ID allocator for virtual console numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a virtio console port is initialized, it is registered as an hvc console using a virtual console number. If a KVM guest is started with multiple virtio console devices, the same vtermno (or virtual console number) can be used to allocate different hvc consoles, which leads to various communication problems later on. This is also reported in debugfs : # grep vtermno /sys/kernel/debug/virtio-ports/* /sys/kernel/debug/virtio-ports/vport1p1:console_vtermno: 1 /sys/kernel/debug/virtio-ports/vport2p1:console_vtermno: 1 /sys/kernel/debug/virtio-ports/vport3p1:console_vtermno: 2 /sys/kernel/debug/virtio-ports/vport4p1:console_vtermno: 3 Replace the next_vtermno global with an ID allocator and start the allocation at 1 as it is today. Also recycle IDs when a console port is removed. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Huth Link: https://lore.kernel.org/r/20221122134643.376184-1-clg@kaod.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 9fa3c76a267f5..6a821118d5530 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -48,22 +49,11 @@ struct ports_driver_data { /* List of all the devices we're handling */ struct list_head portdevs; - /* - * This is used to keep track of the number of hvc consoles - * spawned by this driver. This number is given as the first - * argument to hvc_alloc(). To correctly map an initial - * console spawned via hvc_instantiate to the console being - * hooked up via hvc_alloc, we need to pass the same vtermno. - * - * We also just assume the first console being initialised was - * the first one that got used as the initial console. - */ - unsigned int next_vtermno; - /* All the console devices handled by this driver */ struct list_head consoles; }; -static struct ports_driver_data pdrvdata = { .next_vtermno = 1}; + +static struct ports_driver_data pdrvdata; static DEFINE_SPINLOCK(pdrvdata_lock); static DECLARE_COMPLETION(early_console_added); @@ -89,6 +79,8 @@ struct console { u32 vtermno; }; +static DEFINE_IDA(vtermno_ida); + struct port_buffer { char *buf; @@ -1244,18 +1236,21 @@ static int init_port_console(struct port *port) * pointers. The final argument is the output buffer size: we * can do any size, so we put PAGE_SIZE here. */ - port->cons.vtermno = pdrvdata.next_vtermno; + ret = ida_alloc_min(&vtermno_ida, 1, GFP_KERNEL); + if (ret < 0) + return ret; + port->cons.vtermno = ret; port->cons.hvc = hvc_alloc(port->cons.vtermno, 0, &hv_ops, PAGE_SIZE); if (IS_ERR(port->cons.hvc)) { ret = PTR_ERR(port->cons.hvc); dev_err(port->dev, "error %d allocating hvc for port\n", ret); port->cons.hvc = NULL; + ida_free(&vtermno_ida, port->cons.vtermno); return ret; } spin_lock_irq(&pdrvdata_lock); - pdrvdata.next_vtermno++; list_add_tail(&port->cons.list, &pdrvdata.consoles); spin_unlock_irq(&pdrvdata_lock); port->guest_connected = true; @@ -1532,6 +1527,7 @@ static void unplug_port(struct port *port) list_del(&port->cons.list); spin_unlock_irq(&pdrvdata_lock); hvc_remove(port->cons.hvc); + ida_free(&vtermno_ida, port->cons.vtermno); } remove_port_data(port); -- GitLab From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 18 Nov 2022 06:39:20 +0000 Subject: [PATCH 0769/1480] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare the next SoC in STM32MP family. Signed-off-by: Patrick Delaunay Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index 354be526897ff..d93baee01d7b6 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -22,16 +22,15 @@ /* shadow registers offest */ #define STM32MP15_BSEC_DATA0 0x200 -/* 32 (x 32-bits) lower shadow registers */ -#define STM32MP15_BSEC_NUM_LOWER 32 - struct stm32_romem_cfg { int size; + u8 lower; }; struct stm32_romem_priv { void __iomem *base; struct nvmem_config cfg; + u8 lower; }; static int stm32_romem_read(void *context, unsigned int offset, void *buf, @@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf, for (i = roffset; (i < roffset + rbytes); i += 4) { u32 otp = i >> 2; - if (otp < STM32MP15_BSEC_NUM_LOWER) { + if (otp < priv->lower) { /* read lower data from shadow registers */ val = readl_relaxed( priv->base + STM32MP15_BSEC_DATA0 + i); @@ -159,6 +158,8 @@ static int stm32_romem_probe(struct platform_device *pdev) priv->cfg.priv = priv; priv->cfg.owner = THIS_MODULE; + priv->lower = 0; + cfg = (const struct stm32_romem_cfg *) of_match_device(dev->driver->of_match_table, dev)->data; if (!cfg) { @@ -167,6 +168,7 @@ static int stm32_romem_probe(struct platform_device *pdev) priv->cfg.reg_read = stm32_romem_read; } else { priv->cfg.size = cfg->size; + priv->lower = cfg->lower; priv->cfg.reg_read = stm32_bsec_read; priv->cfg.reg_write = stm32_bsec_write; } @@ -174,8 +176,17 @@ static int stm32_romem_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); } +/* + * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) + * => 96 x 32-bits data words + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming + * => 32 (x 32-bits) lower shadow registers = words 0 to 31 + * - Upper: 2K bits, ECC protection, word programming only + * => 64 (x 32-bits) = words 32 to 95 + */ static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { - .size = 384, /* 96 x 32-bits data words */ + .size = 384, + .lower = 32, }; static const struct of_device_id stm32_romem_of_match[] = { -- GitLab From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 18 Nov 2022 06:39:21 +0000 Subject: [PATCH 0770/1480] nvmem: stm32: add warning when upper OTPs are updated As the upper OTPs are ECC protected, they support only one 32 bits word programming. For a second modification of this word, these ECC become invalid and this OTP will be no more accessible, the shadowed value is invalid. This patch adds a warning to indicate an upper OTP update, because this operation is dangerous as OTP is not locked by the driver after the first update to avoid a second update. Signed-off-by: Patrick Delaunay Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/stm32-romem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index d93baee01d7b6..bb8aa72ba2f94 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -132,6 +132,9 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf, } } + if (offset + bytes >= priv->lower * 4) + dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); + return 0; } -- GitLab From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 18 Nov 2022 06:39:22 +0000 Subject: [PATCH 0771/1480] nvmem: stm32: add nvmem type attribute Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP so userspace is able to know how the data is stored in BSEC. Signed-off-by: Patrick Delaunay Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/stm32-romem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index bb8aa72ba2f94..6de565639d5f4 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -160,6 +160,7 @@ static int stm32_romem_probe(struct platform_device *pdev) priv->cfg.dev = dev; priv->cfg.priv = priv; priv->cfg.owner = THIS_MODULE; + priv->cfg.type = NVMEM_TYPE_OTP; priv->lower = 0; -- GitLab From 107548adf89d581d1271cb2c81858bc793930306 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 18 Nov 2022 06:39:23 +0000 Subject: [PATCH 0772/1480] dt-bindings: nvmem: add new stm32mp13 compatible for stm32-romem Add a new compatible for stm32mp13 support. Acked-by: Rob Herring Signed-off-by: Patrick Delaunay Reviewed-by: Fabrice Gasnier Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml b/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml index 448a2678dc624..16f4cad2fa551 100644 --- a/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml +++ b/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml @@ -22,6 +22,7 @@ properties: compatible: enum: - st,stm32f4-otp + - st,stm32mp13-bsec - st,stm32mp15-bsec reg: -- GitLab From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 From: Jiangshan Yi Date: Fri, 18 Nov 2022 06:39:24 +0000 Subject: [PATCH 0773/1480] nvmem: stm32: fix spelling typo in comment Fix spelling typo in comment. Reported-by: k2ci Signed-off-by: Jiangshan Yi Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/stm32-romem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index 6de565639d5f4..d1d03c2ad0816 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -19,7 +19,7 @@ #define STM32_SMC_WRITE_SHADOW 0x03 #define STM32_SMC_READ_OTP 0x04 -/* shadow registers offest */ +/* shadow registers offset */ #define STM32MP15_BSEC_DATA0 0x200 struct stm32_romem_cfg { -- GitLab From 42b868b032901075f8e9bdcd8d700cb9c0d03ba5 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 18 Nov 2022 06:39:25 +0000 Subject: [PATCH 0774/1480] dt-bindings: nvmem: Fix example Despite not being listed nor required within the top level nvmem yaml file, the "compatible" property is mandatory and is actually enforced by all the nvmem provider bindings. Unfortunately, the lack of compatible in the nvmem.yaml to level description file lead to the example not matching anything and thus not being checked at all. Let's pick a compatible almost randomly (one which is already used with the qfprom label) to make the example at least valid on a semantic point of view and getting it checked. Signed-off-by: Miquel Raynal Acked-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-7-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/nvmem/nvmem.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml index 1eb22dba364c7..0455506fc30fa 100644 --- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml +++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml @@ -67,6 +67,7 @@ examples: #include qfprom: eeprom@700000 { + compatible = "qcom,msm8974-qfprom", "qcom,qfprom"; #address-cells = <1>; #size-cells = <1>; reg = <0x00700000 0x100000>; -- GitLab From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 18 Nov 2022 06:39:26 +0000 Subject: [PATCH 0775/1480] nvmem: Kconfig: Fix spelling mistake "controlls" -> "controls" There is a spelling mistake in a Kconfig description. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index ec8a49c040031..755f551426b55 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC depends on ARCH_AT91 || COMPILE_TEST help This driver enable the OTP controller available on Microchip SAMA7G5 - SoCs. It controlls the access to the OTP memory connected to it. + SoCs. It controls the access to the OTP memory connected to it. config NVMEM_MTK_EFUSE tristate "Mediatek SoCs EFUSE support" -- GitLab From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 18 Nov 2022 06:39:27 +0000 Subject: [PATCH 0776/1480] nvmem: u-boot-env: add Broadcom format support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They decided to store U-Boot environment data inside U-Boot partition and to use a custom header (with "uEnv" magic and env data length). Add support for Broadcom's specific binding and their custom format. Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") Signed-off-by: Rafał Miłecki Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c index 4fdbdccebda16..29b1d87a3c515 100644 --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c @@ -16,6 +16,7 @@ enum u_boot_env_format { U_BOOT_FORMAT_SINGLE, U_BOOT_FORMAT_REDUNDANT, + U_BOOT_FORMAT_BROADCOM, }; struct u_boot_env { @@ -40,6 +41,13 @@ struct u_boot_env_image_redundant { uint8_t data[]; } __packed; +struct u_boot_env_image_broadcom { + __le32 magic; + __le32 len; + __le32 crc32; + uint8_t data[0]; +} __packed; + static int u_boot_env_read(void *context, unsigned int offset, void *val, size_t bytes) { @@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boot_env *priv) crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); data_offset = offsetof(struct u_boot_env_image_redundant, data); break; + case U_BOOT_FORMAT_BROADCOM: + crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); + crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); + data_offset = offsetof(struct u_boot_env_image_broadcom, data); + break; } crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); crc32_data_len = priv->mtd->size - crc32_data_offset; @@ -202,6 +215,7 @@ static const struct of_device_id u_boot_env_of_match_table[] = { { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, + { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, {}, }; -- GitLab From 27dfc44e1ba30d2d49675e21918bf4b3b3b59fa6 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 18 Nov 2022 06:39:28 +0000 Subject: [PATCH 0777/1480] dt-bindings: nvmem: Introduce the nvmem-layout container The nvmem devices description works like this: * Most cases (EEPROM & co): eeprom@x { compatible = ""; ... }; * MTD case: flash@y { compatible = ""; ... otp { compatible = "user-otp"; /* or "factory-otp" */ ... }; }; In the former case, the nvmem device is "eeprom@x", while in the latter case the nvmem device is "otp". Nvmem devices can produce nvmem cells. The current way to describe nvmem cells is to locate them by providing their static byte and bit offset and length. These information are stored in subnodes of the nvmem device. It is now a fact that such description does not fit more advanced use cases where the location or the size of the cells may vary. There are currently three known situations which require being described differently: Kontron's SL28 VPD, ONIE's TLV table and U-Boot's environment variables. Hence, we need a way to describe the parsers that must be used in order to make the dynamic discovery of the nvmem cells. This new description must fit both use cases (the generic situation and the MTD case). Let's create in both cases a container node named nvmem-layout whose content will depend on the parser. Right now nvmem-layout.yaml is "empty", but references to additional layout parser bindings will be inserted in the near future. The final goal being something that looks like: * Most cases (EEPROM & co): eeprom@x { compatible = ""; ... nvmem-layout { compatible = ""; ... }; }; * MTD case: flash@y { compatible = ""; ... otp { compatible = "user-otp"; /* or "factory-otp" */ ... nvmem-layout { compatible = ""; ... }; }; }; Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-10-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/nvmem/layouts/nvmem-layout.yaml | 30 +++++++++++++++++++ .../devicetree/bindings/nvmem/nvmem.yaml | 7 +++++ 2 files changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml diff --git a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml new file mode 100644 index 0000000000000..ecc7c37cbc1fc --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/layouts/nvmem-layout.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVMEM (Non Volatile Memory) layouts + +maintainers: + - Srinivas Kandagatla + - Michael Walle + - Miquel Raynal + +description: | + Most NVMEM layouts are static and thus do not require additional description + besides the bytes/bits offset and length. Other layouts can be less statically + define and might require dynamic reading of the NVMEM device in order to + perform their parsing. The nvmem-layout container is here to describe these. + +properties: + compatible: true + + '#address-cells': false + + '#size-cells': false + +required: + - compatible + +unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml index 0455506fc30fa..75bb93dda9df1 100644 --- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml +++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml @@ -39,6 +39,13 @@ properties: when it's driven low (logical '0') to allow writing. maxItems: 1 + nvmem-layout: + $ref: /schemas/nvmem/layouts/nvmem-layout.yaml + description: + Alternative to the statically defined nvmem cells, this + container may reference more advanced (dynamic) layout + parsers. + patternProperties: "@[0-9a-f]+(,[0-7])?$": type: object -- GitLab From ca104926184db10d486e91e64cec725e6c2bd8ae Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 18 Nov 2022 06:39:29 +0000 Subject: [PATCH 0778/1480] dt-bindings: eeprom: Inherit from nvmem.yaml EEPROMs can be nvmem providers. Let's make all EEPROM bindings reference nvmem.yaml as they should, so that nvmem cells and layout parsers can be safely described within the EEPROM nodes. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-11-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/eeprom/at24.yaml | 5 ++++- Documentation/devicetree/bindings/eeprom/at25.yaml | 1 + .../devicetree/bindings/eeprom/microchip,93lc46b.yaml | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml index d14e0accbda81..84af0d5f52aaf 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.yaml +++ b/Documentation/devicetree/bindings/eeprom/at24.yaml @@ -10,6 +10,9 @@ title: I2C EEPROMs compatible with Atmel's AT24 maintainers: - Bartosz Golaszewski +allOf: + - $ref: /schemas/nvmem/nvmem.yaml + select: properties: compatible: @@ -183,7 +186,7 @@ required: - compatible - reg -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/eeprom/at25.yaml b/Documentation/devicetree/bindings/eeprom/at25.yaml index 8b1c997caac12..0f5a8ef996d33 100644 --- a/Documentation/devicetree/bindings/eeprom/at25.yaml +++ b/Documentation/devicetree/bindings/eeprom/at25.yaml @@ -104,6 +104,7 @@ required: allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/nvmem/nvmem.yaml - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/eeprom/microchip,93lc46b.yaml b/Documentation/devicetree/bindings/eeprom/microchip,93lc46b.yaml index 0c2f5ddb79c5a..64cfd971c9c5e 100644 --- a/Documentation/devicetree/bindings/eeprom/microchip,93lc46b.yaml +++ b/Documentation/devicetree/bindings/eeprom/microchip,93lc46b.yaml @@ -47,6 +47,7 @@ required: allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/nvmem/nvmem.yaml unevaluatedProperties: false -- GitLab From e33cfae0eff66dca02ed482cf3ef01bb61f84fb0 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 18 Nov 2022 06:39:30 +0000 Subject: [PATCH 0779/1480] dt-bindings: nvmem: add YAML schema for the sl28 vpd layout Add a schema for the NVMEM layout on Kontron's sl28 boards. Signed-off-by: Michael Walle Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-12-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../nvmem/layouts/kontron,sl28-vpd.yaml | 64 +++++++++++++++++++ .../bindings/nvmem/layouts/nvmem-layout.yaml | 3 + 2 files changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml diff --git a/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml b/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml new file mode 100644 index 0000000000000..c713e23819f11 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/layouts/kontron,sl28-vpd.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVMEM layout of the Kontron SMARC-sAL28 vital product data + +maintainers: + - Michael Walle + +description: + The vital product data (VPD) of the sl28 boards contains a serial + number and a base MAC address. The actual MAC addresses for the + on-board ethernet devices are derived from this base MAC address by + adding an offset. + +select: false + +properties: + compatible: + const: kontron,sl28-vpd + + serial-number: + type: object + description: The board's serial number + + additionalProperties: false + + base-mac-address: + type: object + description: + Base MAC address for all on-module network interfaces. The first + argument of the phandle will be treated as an offset. + + properties: + "#nvmem-cell-cells": + const: 1 + + additionalProperties: false + +required: + - compatible + +additionalProperties: false + +examples: + - | + otp-1 { + compatible = "user-otp"; + + nvmem-layout { + compatible = "kontron,sl28-vpd"; + + serial_number: serial-number { + }; + + base_mac_address: base-mac-address { + #nvmem-cell-cells = <1>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml index ecc7c37cbc1fc..f64ea2fa362d1 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml @@ -17,6 +17,9 @@ description: | define and might require dynamic reading of the NVMEM device in order to perform their parsing. The nvmem-layout container is here to describe these. +oneOf: + - $ref: kontron,sl28-vpd.yaml + properties: compatible: true -- GitLab From b6c88f10e8bb20f0ccaabe4c0a4ac3c6c1fb8768 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 18 Nov 2022 06:39:31 +0000 Subject: [PATCH 0780/1480] dt-bindings: vendor-prefixes: Add ONIE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As described on their website (see link below), "The Open Network Install Environment (ONIE) is an open source initiative that defines an open “install environment” for modern networking hardware." It is not a proper corporation per-se but rather more a group which tries to spread the use of open source standards in the networking hardware world. Link: https://opencomputeproject.github.io/onie/ Signed-off-by: Miquel Raynal Acked-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-13-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6e323a380294a..65a74026cf2b7 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -927,6 +927,8 @@ patternProperties: description: One Laptop Per Child "^oneplus,.*": description: OnePlus Technology (Shenzhen) Co., Ltd. + "^onie,.*": + description: Open Network Install Environment group "^onion,.*": description: Onion Corporation "^onnn,.*": -- GitLab From ce9c0b06abc44d51e81ce36b83a81e960034f3ee Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 18 Nov 2022 06:39:32 +0000 Subject: [PATCH 0781/1480] dt-bindings: nvmem: add YAML schema for the ONIE tlv layout Add a schema for the ONIE tlv NVMEM layout that can be found on any ONIE compatible networking device. Describe all the possible NVMEM cells that can be produced by this layout parser. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118063932.6418-14-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/nvmem/layouts/nvmem-layout.yaml | 1 + .../nvmem/layouts/onie,tlv-layout.yaml | 147 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/onie,tlv-layout.yaml diff --git a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml index f64ea2fa362d1..8512ee538c4c1 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml @@ -19,6 +19,7 @@ description: | oneOf: - $ref: kontron,sl28-vpd.yaml + - $ref: onie,tlv-layout.yaml properties: compatible: true diff --git a/Documentation/devicetree/bindings/nvmem/layouts/onie,tlv-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/onie,tlv-layout.yaml new file mode 100644 index 0000000000000..5a0e7671aa3f5 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/layouts/onie,tlv-layout.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/layouts/onie,tlv-layout.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVMEM layout of the ONIE tlv table + +maintainers: + - Miquel Raynal + +description: + Modern networking hardware implementing the Open Compute Project ONIE + infrastructure shall provide a non-volatile memory with a table whose the + content is well specified and gives many information about the manufacturer + (name, country of manufacture, etc) as well as device caracteristics (serial + number, hardware version, mac addresses, etc). The underlaying device type + (flash, EEPROM,...) is not specified. The exact location of each value is also + dynamic and should be discovered at run time because it depends on the + parameters the manufacturer decided to embed. + +select: false + +properties: + compatible: + const: onie,tlv-layout + + product-name: + type: object + additionalProperties: false + + part-number: + type: object + additionalProperties: false + + serial-number: + type: object + additionalProperties: false + + mac-address: + type: object + description: + Base MAC address for all on-module network interfaces. The first + argument of the phandle will be treated as an offset. + + properties: + "#nvmem-cell-cells": + const: 1 + + additionalProperties: false + + manufacture-date: + type: object + additionalProperties: false + + device-version: + type: object + additionalProperties: false + + label-revision: + type: object + additionalProperties: false + + platforn-name: + type: object + additionalProperties: false + + onie-version: + type: object + additionalProperties: false + + num-macs: + type: object + additionalProperties: false + + manufacturer: + type: object + additionalProperties: false + + country-code: + type: object + additionalProperties: false + + vendor: + type: object + additionalProperties: false + + diag-version: + type: object + additionalProperties: false + + service-tag: + type: object + additionalProperties: false + + vendor-extension: + type: object + additionalProperties: false + +required: + - compatible + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + eeprom@56 { + compatible = "atmel,24c64"; + read-only; + reg = <0x56>; + + nvmem-layout { + compatible = "onie,tlv-layout"; + + serial-number { + }; + }; + }; + }; + + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + reg = <0>; + + otp { + compatible = "user-otp"; + + nvmem-layout { + compatible = "onie,tlv-layout"; + + mac-address { + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; +... -- GitLab From 97e1a5309190aca528c7e12697a898bda793a460 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:35 +0000 Subject: [PATCH 0782/1480] slimbus: qcom-ngd-ctrl: check for device runtime PM status during ISR Slimbus core interrupt is getting fired after suspend. At this point ADSP slimbus hardware is off with gated clocks which is leading to an unclocked access when HLOS slimbus tried to read the interrupt status register in the ISR. Co-developed-by: Chandana Kishori Chiluveru Signed-off-by: Chandana Kishori Chiluveru Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 76c5e446d2433..964adf77b51b9 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -763,7 +763,14 @@ static irqreturn_t qcom_slim_ngd_interrupt(int irq, void *d) { struct qcom_slim_ngd_ctrl *ctrl = d; void __iomem *base = ctrl->ngd->base; - u32 stat = readl(base + NGD_INT_STAT); + u32 stat; + + if (pm_runtime_suspended(ctrl->ctrl.dev)) { + dev_warn_once(ctrl->dev, "Interrupt received while suspended\n"); + return IRQ_NONE; + } + + stat = readl(base + NGD_INT_STAT); if ((stat & NGD_INT_MSG_BUF_CONTE) || (stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) || -- GitLab From 63c60a226c908f46589b57b5bcb220ca82a76cc5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:36 +0000 Subject: [PATCH 0783/1480] slimbus: qcom-ngd-ctrl: drop PM runtime counter on transfer error paths If transfer in qcom_slim_ngd_xfer_msg_sync() fails, we need to drop the PM runtime usage counter to have it balanced. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-3-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 964adf77b51b9..d48e58ca5d585 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -919,21 +919,29 @@ static int qcom_slim_ngd_xfer_msg_sync(struct slim_controller *ctrl, DECLARE_COMPLETION_ONSTACK(done); int ret, timeout; - pm_runtime_get_sync(ctrl->dev); + ret = pm_runtime_get_sync(ctrl->dev); + if (ret < 0) + goto pm_put; txn->comp = &done; ret = qcom_slim_ngd_xfer_msg(ctrl, txn); if (ret) - return ret; + goto pm_put; timeout = wait_for_completion_timeout(&done, HZ); if (!timeout) { dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc, txn->mt); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto pm_put; } return 0; + +pm_put: + pm_runtime_put(ctrl->dev); + + return ret; } static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt) -- GitLab From 434d25728171aa72ed1b1c4d248527cbf6b6c99b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:37 +0000 Subject: [PATCH 0784/1480] slimbus: stream: handle unsupported bitrates for presence rate Handle errors of getting presence rate for unsupported stream bitrate, instead of sending -EINVAL in change content message. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Konrad Dybcio Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/stream.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c index 73a2aa3629572..7e9c818e66c13 100644 --- a/drivers/slimbus/stream.c +++ b/drivers/slimbus/stream.c @@ -204,7 +204,7 @@ int slim_stream_prepare(struct slim_stream_runtime *rt, { struct slim_controller *ctrl = rt->dev->ctrl; struct slim_port *port; - int num_ports, i, port_id; + int num_ports, i, port_id, prrate; if (rt->ports) { dev_err(&rt->dev->dev, "Stream already Prepared\n"); @@ -221,6 +221,13 @@ int slim_stream_prepare(struct slim_stream_runtime *rt, rt->bps = cfg->bps; rt->direction = cfg->direction; + prrate = slim_get_prate_code(cfg->rate); + if (prrate < 0) { + dev_err(&rt->dev->dev, "Cannot get presence rate for rate %d Hz\n", + cfg->rate); + return prrate; + } + if (cfg->rate % ctrl->a_framer->superfreq) { /* * data rate not exactly multiple of super frame, @@ -241,7 +248,7 @@ int slim_stream_prepare(struct slim_stream_runtime *rt, port = &rt->ports[i]; port->state = SLIM_PORT_DISCONNECTED; port->id = port_id; - port->ch.prrate = slim_get_prate_code(cfg->rate); + port->ch.prrate = prrate; port->ch.id = cfg->chs[i]; port->ch.data_fmt = SLIM_CH_DATA_FMT_NOT_DEFINED; port->ch.aux_fmt = SLIM_CH_AUX_FMT_NOT_APPLICABLE; -- GitLab From 4594cb4b76c6cf9acf81d3044c6a6817ed4a3781 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:38 +0000 Subject: [PATCH 0785/1480] slimbus: qcom-ngd-ctrl: add support for 44.1 Khz frequency Add support for 44.1Khz frequency by dynamically calculating the slimbus parameters instead of statically defining them. Co-developed-by: Prudhvi Yarlagadda Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 64 ++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index d48e58ca5d585..22720ad4c22d7 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -944,6 +944,54 @@ pm_put: return ret; } +static int qcom_slim_calc_coef(struct slim_stream_runtime *rt, int *exp) +{ + struct slim_controller *ctrl = rt->dev->ctrl; + int coef; + + if (rt->ratem * ctrl->a_framer->superfreq < rt->rate) + rt->ratem++; + + coef = rt->ratem; + *exp = 0; + + /* + * CRM = Cx(2^E) is the formula we are using. + * Here C is the coffecient and E is the exponent. + * CRM is the Channel Rate Multiplier. + * Coefficeint should be either 1 or 3 and exponenet + * should be an integer between 0 to 9, inclusive. + */ + while (1) { + while ((coef & 0x1) != 0x1) { + coef >>= 1; + *exp = *exp + 1; + } + + if (coef <= 3) + break; + + coef++; + } + + /* + * we rely on the coef value (1 or 3) to set a bit + * in the slimbus message packet. This bit is + * BIT(5) which is the segment rate coefficient. + */ + if (coef == 1) { + if (*exp > 9) + return -EIO; + coef = 0; + } else { + if (*exp > 8) + return -EIO; + coef = 1; + } + + return coef; +} + static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt) { struct slim_device *sdev = rt->dev; @@ -967,16 +1015,22 @@ static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt) struct slim_port *port = &rt->ports[i]; if (txn.msg->num_bytes == 0) { - int seg_interval = SLIM_SLOTS_PER_SUPERFRAME/rt->ratem; - int exp; + int exp = 0, coef = 0; wbuf[txn.msg->num_bytes++] = sdev->laddr; wbuf[txn.msg->num_bytes] = rt->bps >> 2 | (port->ch.aux_fmt << 6); - /* Data channel segment interval not multiple of 3 */ - exp = seg_interval % 3; - if (exp) + /* calculate coef dynamically */ + coef = qcom_slim_calc_coef(rt, &exp); + if (coef < 0) { + dev_err(&sdev->dev, + "%s: error calculating coef %d\n", __func__, + coef); + return -EIO; + } + + if (coef) wbuf[txn.msg->num_bytes] |= BIT(5); txn.msg->num_bytes++; -- GitLab From a82b1ec34e9bea94058f429560e311e5ca634356 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:39 +0000 Subject: [PATCH 0786/1480] slimbus: stream: add checks for invalid unprepare/disable usage slim_disable_stream() and slim_stream_unprepare() are exported, so add sanity checks preventing unmatched/invalid calls. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-6-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/stream.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c index 7e9c818e66c13..1d6b386579173 100644 --- a/drivers/slimbus/stream.c +++ b/drivers/slimbus/stream.c @@ -414,6 +414,9 @@ int slim_stream_disable(struct slim_stream_runtime *stream) struct slim_controller *ctrl = stream->dev->ctrl; int ret, i; + if (!stream->ports || !stream->num_ports) + return -EINVAL; + if (ctrl->disable_stream) ctrl->disable_stream(stream); @@ -445,6 +448,9 @@ int slim_stream_unprepare(struct slim_stream_runtime *stream) { int i; + if (!stream->ports || !stream->num_ports) + return -EINVAL; + for (i = 0; i < stream->num_ports; i++) slim_disconnect_port(stream, &stream->ports[i]); -- GitLab From 8c8112d7c442579cca821836bbcc46b747ceca74 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:40 +0000 Subject: [PATCH 0787/1480] slimbus: qcom-ctrl: drop unneeded qcom,apq8064-slim compatible Bindings require usage of fallback "qcom,slim" compatible, so "qcom,apq8064-slim" is redundant. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-7-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c index c0c4f895d76e2..bb106eab8ae27 100644 --- a/drivers/slimbus/qcom-ctrl.c +++ b/drivers/slimbus/qcom-ctrl.c @@ -718,7 +718,6 @@ static const struct dev_pm_ops qcom_slim_dev_pm_ops = { static const struct of_device_id qcom_slim_dt_match[] = { { .compatible = "qcom,slim", }, - { .compatible = "qcom,apq8064-slim", }, {} }; -- GitLab From 3d58b933c9eb2da5745c485bc7008d29c0eaddac Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:41 +0000 Subject: [PATCH 0788/1480] slimbus: qcom-ctrl: use devm_platform_ioremap_resource_byname() Simplify the code with devm_platform_ioremap_resource_byname(). Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-8-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ctrl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c index bb106eab8ae27..400b7b385a443 100644 --- a/drivers/slimbus/qcom-ctrl.c +++ b/drivers/slimbus/qcom-ctrl.c @@ -488,7 +488,6 @@ static int qcom_slim_probe(struct platform_device *pdev) { struct qcom_slim_ctrl *ctrl; struct slim_controller *sctrl; - struct resource *slim_mem; int ret, ver; ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); @@ -519,8 +518,7 @@ static int qcom_slim_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctrl); dev_set_drvdata(ctrl->dev, ctrl); - slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); - ctrl->base = devm_ioremap_resource(ctrl->dev, slim_mem); + ctrl->base = devm_platform_ioremap_resource_byname(pdev, "ctrl"); if (IS_ERR(ctrl->base)) return PTR_ERR(ctrl->base); -- GitLab From 1d01bcb4659cfca87d92075b87cdadb0a9897d14 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:42 +0000 Subject: [PATCH 0789/1480] slimbus: qcom-ngd-ctrl: use devm_platform_get_and_ioremap_resource() Simplify the code with devm_platform_get_and_ioremap_resource(). Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-9-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 22720ad4c22d7..a6f3b6860d8f0 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1597,7 +1597,6 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct qcom_slim_ngd_ctrl *ctrl; - struct resource *res; int ret; struct pdr_service *pds; @@ -1607,8 +1606,7 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) dev_set_drvdata(dev, ctrl); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctrl->base = devm_ioremap_resource(dev, res); + ctrl->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(ctrl->base)) return PTR_ERR(ctrl->base); -- GitLab From 319a538d618fea33434387c4502361bb8f047e11 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:43 +0000 Subject: [PATCH 0790/1480] slimbus: qcom-ngd-ctrl: reinit the reconf completion flag Reinitialize the reconf completion flag when ngd registers are not retainied or when enumeration is lost for ngd. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-10-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index a6f3b6860d8f0..77aa6d26476cd 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1205,6 +1205,12 @@ static int qcom_slim_ngd_power_up(struct qcom_slim_ngd_ctrl *ctrl) return 0; } + /* + * Reinitialize only when registers are not retained or when enumeration + * is lost for ngd. + */ + reinit_completion(&ctrl->reconf); + writel_relaxed(DEF_NGD_INT_MASK, ngd->base + NGD_INT_EN); rx_msgq = readl_relaxed(ngd->base + NGD_RX_MSGQ_CFG); -- GitLab From c53627f83abc9fb4ac5cbd9dc1c898008bcc2ac8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:44 +0000 Subject: [PATCH 0791/1480] dt-bindings: slimbus: convert bus description to DT schema Convert the SLIMbus bus description bindings to DT Schema. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-11-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/slimbus/bus.txt | 60 ------------ .../bindings/slimbus/slim-ngd-qcom-ctrl.txt | 2 - .../bindings/slimbus/slim-qcom-ctrl.txt | 3 - .../devicetree/bindings/slimbus/slimbus.yaml | 95 +++++++++++++++++++ 4 files changed, 95 insertions(+), 65 deletions(-) delete mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt create mode 100644 Documentation/devicetree/bindings/slimbus/slimbus.yaml diff --git a/Documentation/devicetree/bindings/slimbus/bus.txt b/Documentation/devicetree/bindings/slimbus/bus.txt deleted file mode 100644 index bbe871f82a8b9..0000000000000 --- a/Documentation/devicetree/bindings/slimbus/bus.txt +++ /dev/null @@ -1,60 +0,0 @@ -SLIM(Serial Low Power Interchip Media Bus) bus - -SLIMbus is a 2-wire bus, and is used to communicate with peripheral -components like audio-codec. - -Required property for SLIMbus controller node: -- compatible - name of SLIMbus controller - -Child nodes: -Every SLIMbus controller node can contain zero or more child nodes -representing slave devices on the bus. Every SLIMbus slave device is -uniquely determined by the enumeration address containing 4 fields: -Manufacturer ID, Product code, Device index, and Instance value for -the device. -If child node is not present and it is instantiated after device -discovery (slave device reporting itself present). - -In some cases it may be necessary to describe non-probeable device -details such as non-standard ways of powering up a device. In -such cases, child nodes for those devices will be present as -slaves of the SLIMbus controller, as detailed below. - -Required property for SLIMbus child node if it is present: -- reg - Should be ('Device index', 'Instance ID') from SLIMbus - Enumeration Address. - Device Index Uniquely identifies multiple Devices within - a single Component. - Instance ID Is for the cases where multiple Devices of the - same type or Class are attached to the bus. - -- compatible -"slimMID,PID". The textual representation of Manufacturer ID, - Product Code, shall be in lower case hexadecimal with leading - zeroes suppressed - -Optional property for SLIMbus child node if it is present: -- slim-ifc-dev - Should be phandle to SLIMBus Interface device. - Required for devices which deal with streams. - -SLIMbus example for Qualcomm's slimbus manager component: - - slim@28080000 { - compatible = "qcom,apq8064-slim", "qcom,slim"; - reg = <0x28080000 0x2000>, - interrupts = <0 33 0>; - clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; - clock-names = "iface", "core"; - #address-cells = <2>; - #size-cell = <0>; - - codec_ifd: ifd@0,0{ - compatible = "slim217,60"; - reg = <0 0>; - }; - - codec: wcd9310@1,0{ - compatible = "slim217,60"; - reg = <1 0>; - slim-ifc-dev = <&codec_ifd>; - }; - }; diff --git a/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt index e94a2ad3a710d..7c3d9eb6af5d1 100644 --- a/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt +++ b/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt @@ -5,8 +5,6 @@ with SLIMBus slaves directly over the bus using messaging interface and communicating with master component residing on ADSP for bandwidth and data-channel management -Please refer to slimbus/bus.txt for details of the common SLIMBus bindings. - - compatible: Usage: required Value type: diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt index 922dcb8ff24ab..6d955e129f908 100644 --- a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt +++ b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt @@ -4,9 +4,6 @@ master component. Required properties: - - #address-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt - - #size-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt - - reg : Offset and length of the register region(s) for the device - reg-names : Register region name(s) referenced in reg above Required register resource entries are: diff --git a/Documentation/devicetree/bindings/slimbus/slimbus.yaml b/Documentation/devicetree/bindings/slimbus/slimbus.yaml new file mode 100644 index 0000000000000..22513fb7c59a8 --- /dev/null +++ b/Documentation/devicetree/bindings/slimbus/slimbus.yaml @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/slimbus/slimbus.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SLIM (Serial Low Power Interchip Media) bus + +maintainers: + - Srinivas Kandagatla + +description: + SLIMbus is a 2-wire bus, and is used to communicate with peripheral + components like audio-codec. + +properties: + $nodename: + pattern: "^slim(@.*|-[0-9a-f])*$" + + "#address-cells": + const: 2 + + "#size-cells": + const: 0 + +patternProperties: + "^.*@[0-9a-f]+,[0-9a-f]+$": + type: object + description: | + Every SLIMbus controller node can contain zero or more child nodes + representing slave devices on the bus. Every SLIMbus slave device is + uniquely determined by the enumeration address containing 4 fields:: + Manufacturer ID, Product code, Device index, and Instance value for the + device. + + If child node is not present and it is instantiated after device + discovery (slave device reporting itself present). + + In some cases it may be necessary to describe non-probeable device + details such as non-standard ways of powering up a device. In such cases, + child nodes for those devices will be present as slaves of the SLIMbus + controller. + + properties: + compatible: + pattern: "^slim[0-9a-f]+,[0-9a-f]+$" + + reg: + maxItems: 1 + description: | + Pair of (device index, instande ID), where:: + - Device index, which uniquely identifies multiple devices within a + single component. + - Instance ID, can be used for the cases where multiple devices of + the same type or class are attached to the bus. + + required: + - compatible + - reg + + additionalProperties: true + +required: + - "#address-cells" + - "#size-cells" + +additionalProperties: true + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + slim@28080000 { + compatible = "qcom,apq8064-slim", "qcom,slim"; + reg = <0x28080000 0x2000>, <0x80207c 4>; + reg-names = "ctrl", "slew"; + interrupts = ; + clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; + clock-names = "iface", "core"; + #address-cells = <2>; + #size-cells = <0>; + + audio-codec@1,0 { + compatible = "slim217,60"; + reg = <1 0>; + }; + }; + }; -- GitLab From 717bd3dfc4ced0a12bc177b267a0c6fd23eec620 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:45 +0000 Subject: [PATCH 0792/1480] dt-bindings: slimbus: qcom,slim: convert to DT schema Convert the Qualcomm SoC SLIMbus controller bindings to DT Schema. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-12-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/slimbus/qcom,slim.yaml | 86 +++++++++++++++++++ .../bindings/slimbus/slim-qcom-ctrl.txt | 36 -------- 2 files changed, 86 insertions(+), 36 deletions(-) create mode 100644 Documentation/devicetree/bindings/slimbus/qcom,slim.yaml delete mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt diff --git a/Documentation/devicetree/bindings/slimbus/qcom,slim.yaml b/Documentation/devicetree/bindings/slimbus/qcom,slim.yaml new file mode 100644 index 0000000000000..883bda58ca977 --- /dev/null +++ b/Documentation/devicetree/bindings/slimbus/qcom,slim.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/slimbus/qcom,slim.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SoC SLIMbus controller + +maintainers: + - Krzysztof Kozlowski + - Srinivas Kandagatla + +description: + SLIMbus controller used when applications processor controls SLIMbus master + component. + +allOf: + - $ref: slimbus.yaml# + +properties: + compatible: + items: + - enum: + - qcom,apq8064-slim + - const: qcom,slim + + reg: + items: + - description: Physical address of controller register blocks + - description: SLEW RATE register + + reg-names: + items: + - const: ctrl + - const: slew + + clocks: + items: + - description: Interface clock for this controller + - description: Interrupt for controller core's BAM + + clock-names: + items: + - const: iface + - const: core + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + slim@28080000 { + compatible = "qcom,apq8064-slim", "qcom,slim"; + reg = <0x28080000 0x2000>, <0x80207c 4>; + reg-names = "ctrl", "slew"; + interrupts = ; + clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; + clock-names = "iface", "core"; + #address-cells = <2>; + #size-cells = <0>; + + audio-codec@1,0 { + compatible = "slim217,60"; + reg = <1 0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt deleted file mode 100644 index 6d955e129f908..0000000000000 --- a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt +++ /dev/null @@ -1,36 +0,0 @@ -Qualcomm SLIMbus controller -This controller is used if applications processor driver controls SLIMbus -master component. - -Required properties: - - - reg : Offset and length of the register region(s) for the device - - reg-names : Register region name(s) referenced in reg above - Required register resource entries are: - "ctrl": Physical address of controller register blocks - "slew": required for "qcom,apq8064-slim" SOC. - - compatible : should be "qcom,-slim" for SOC specific compatible - followed by "qcom,slim" for fallback. - - interrupts : Interrupt number used by this controller - - clocks : Interface and core clocks used by this SLIMbus controller - - clock-names : Required clock-name entries are: - "iface" : Interface clock for this controller - "core" : Interrupt for controller core's BAM - -Example: - - slim@28080000 { - compatible = "qcom,apq8064-slim", "qcom,slim"; - reg = <0x28080000 0x2000>, <0x80207C 4>; - reg-names = "ctrl", "slew"; - interrupts = <0 33 0>; - clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; - clock-names = "iface", "core"; - #address-cells = <2>; - #size-cell = <0>; - - wcd9310: audio-codec@1,0{ - compatible = "slim217,60"; - reg = <1 0>; - }; - }; -- GitLab From 5f115bb92a631b01bee7ca2310c6c353a770656e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2022 06:52:46 +0000 Subject: [PATCH 0793/1480] dt-bindings: slimbus: qcom,slim-ngd: convert to DT schema Convert the Qualcomm SoC SLIMBus Non Generic Device (NGD) controller bindings to DT Schema. During conversion add iommus already present in DTS and extend the example based on SDM845. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221118065246.6835-13-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/slimbus/qcom,slim-ngd.yaml | 120 ++++++++++++++++++ .../bindings/slimbus/slim-ngd-qcom-ctrl.txt | 82 ------------ 2 files changed, 120 insertions(+), 82 deletions(-) create mode 100644 Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml delete mode 100644 Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt diff --git a/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml b/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml new file mode 100644 index 0000000000000..abf61c15246eb --- /dev/null +++ b/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/slimbus/qcom,slim-ngd.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SoC SLIMBus Non Generic Device (NGD) Controller + +maintainers: + - Krzysztof Kozlowski + - Srinivas Kandagatla + +description: + SLIMBus NGD controller is a light-weight driver responsible for communicating + with SLIMBus slaves directly over the bus using messaging interface and + communicating with master component residing on ADSP for bandwidth and + data-channel management + +properties: + compatible: + enum: + - qcom,slim-ngd-v1.5.0 # for MSM8996 + - qcom,slim-ngd-v2.1.0 # for SDM845 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + dmas: + maxItems: 2 + + dma-names: + items: + - const: rx + - const: tx + + interrupts: + maxItems: 1 + + iommus: + maxItems: 1 + +patternProperties: + "^slim@[0-9a-f]+$": + type: object + $ref: slimbus.yaml# + description: + Each subnode represents an instance of NGD + + properties: + reg: + maxItems: 1 + + unevaluatedProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - dmas + - dma-names + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + slim-ngd@171c0000 { + compatible = "qcom,slim-ngd-v2.1.0"; + reg = <0x171c0000 0x2c000>; + interrupts = ; + + dmas = <&slimbam 3>, <&slimbam 4>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x1806 0x0>; + #address-cells = <1>; + #size-cells = <0>; + + slim@1 { + reg = <1>; + #address-cells = <2>; + #size-cells = <0>; + + codec@1,0 { + compatible = "slim217,250"; + reg = <1 0>; + slim-ifc-dev = <&wcd9340_ifd>; + + #sound-dai-cells = <1>; + + interrupts-extended = <&tlmm 54 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + + #clock-cells = <0>; + clock-frequency = <9600000>; + clock-output-names = "mclk"; + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + + #address-cells = <1>; + #size-cells = <1>; + + reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + + /* Rest of the WCD9340 codec */ + }; + }; + }; diff --git a/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt deleted file mode 100644 index 7c3d9eb6af5d1..0000000000000 --- a/Documentation/devicetree/bindings/slimbus/slim-ngd-qcom-ctrl.txt +++ /dev/null @@ -1,82 +0,0 @@ -Qualcomm SLIMBus Non Generic Device (NGD) Controller binding - -SLIMBus NGD controller is a light-weight driver responsible for communicating -with SLIMBus slaves directly over the bus using messaging interface and -communicating with master component residing on ADSP for bandwidth and -data-channel management - -- compatible: - Usage: required - Value type: - Definition: must be "qcom,slim-ngd-v.." - must be one of the following. - "qcom,slim-ngd-v1.5.0" for MSM8996 - "qcom,slim-ngd-v2.1.0" for SDM845 - -- reg: - Usage: required - Value type: - Definition: must specify the base address and size of the controller - register space. -- dmas - Usage: required - Value type: - Definition: List of rx and tx dma channels - -- dma-names - Usage: required - Value type: - Definition: must be "rx" and "tx". - -- interrupts: - Usage: required - Value type: - Definition: must list controller IRQ. - -#address-cells - Usage: required - Value type: - Definition: Should be 1, reflecting the instance id of ngd. - -#size-cells - Usage: required - Value type: - Definition: Should be 0 - -= NGD Devices -Each subnode represents an instance of NGD, must contain the following -properties: - -- reg: - Usage: required - Value type: - Definition: Should be instance id of ngd. - -#address-cells - Usage: required - Refer to slimbus/bus.txt for details of the common SLIMBus bindings. - -#size-cells - Usage: required - Refer to slimbus/bus.txt for details of the common SLIMBus bindings. - -= EXAMPLE - -slim@91c0000 { - compatible = "qcom,slim-ngd-v1.5.0"; - reg = <0x91c0000 0x2c000>; - interrupts = <0 163 0>; - dmas = <&slimbam 3>, <&slimbam 4>; - dma-names = "rx", "tx"; - #address-cells = <1>; - #size-cells = <0>; - ngd@1 { - reg = <1>; - #address-cells = <1>; - #size-cells = <1>; - codec@1 { - compatible = "slim217,1a0"; - reg = <1 0>; - }; - }; -}; -- GitLab From b9bf27386dddab16bc455124c54cbeea6cb9a1ca Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:54 +0500 Subject: [PATCH 0794/1480] Accessiblity: speakup_soft: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_soft module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-2-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_soft.c | 59 ++++++++++++++------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_soft.c b/drivers/accessibility/speakup/speakup_soft.c index 28c8f60370cf8..6d446824677b4 100644 --- a/drivers/accessibility/speakup/speakup_soft.c +++ b/drivers/accessibility/speakup/speakup_soft.c @@ -33,21 +33,30 @@ static struct miscdevice synth_device, synthu_device; static int init_pos; static int misc_registered; -static struct var_t vars[] = { - /* DIRECT is put first so that module_param_named can access it easily */ - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, - - { CAPS_START, .u.s = {"\x01+3p" } }, - { CAPS_STOP, .u.s = {"\x01-3p" } }, - { PAUSE, .u.n = {"\x01P" } }, - { RATE, .u.n = {"\x01%ds", 2, 0, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"\x01%dp", 5, 0, 9, 0, 0, NULL } }, - { INFLECTION, .u.n = {"\x01%dr", 5, 0, 9, 0, 0, NULL } }, - { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, - { PUNCT, .u.n = {"\x01%db", 0, 0, 3, 0, 0, NULL } }, - { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, - { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, + +enum default_vars_id { + DIRECT_ID = 0, CAPS_START_ID, CAPS_STOP_ID, + PAUSE_ID, RATE_ID, PITCH_ID, INFLECTION_ID, + VOL_ID, TONE_ID, PUNCT_ID, VOICE_ID, + FREQUENCY_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x01+3p" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x01-3p" } }, + [PAUSE_ID] = { PAUSE, .u.n = {"\x01P" } }, + [RATE_ID] = { RATE, .u.n = {"\x01%ds", 2, 0, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x01%dp", 5, 0, 9, 0, 0, NULL } }, + [INFLECTION_ID] = { INFLECTION, .u.n = {"\x01%dr", 5, 0, 9, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"\x01%db", 0, 0, 3, 0, 0, NULL } }, + [VOICE_ID] = { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, + [FREQUENCY_ID] = { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, V_LAST_VAR }; @@ -451,10 +460,28 @@ static int softsynth_adjust(struct spk_synth *synth, struct st_var_header *var) } module_param_named(start, synth_soft.startup, short, 0444); -module_param_named(direct, vars[0].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(inflection, vars[INFLECTION_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(frequency, vars[FREQUENCY_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); MODULE_PARM_DESC(direct, "Set the direct variable on load."); +MODULE_PARM_DESC(rate, "Sets the rate of the synthesizer."); +MODULE_PARM_DESC(pitch, "Sets the pitch of the synthesizer."); +MODULE_PARM_DESC(inflection, "Sets the inflection of the synthesizer."); +MODULE_PARM_DESC(vol, "Sets the volume of the speech synthesizer."); +MODULE_PARM_DESC(tone, "Sets the tone of the speech synthesizer."); +MODULE_PARM_DESC(punct, "Sets the amount of punctuation spoken by the synthesizer."); +MODULE_PARM_DESC(voice, "Sets the voice used by the synthesizer."); +MODULE_PARM_DESC(frequency, "Sets the frequency of speech synthesizer."); module_spk_synth(synth_soft); -- GitLab From 5e3e27f040ec3611db14a5efe23c9108831c38be Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:55 +0500 Subject: [PATCH 0795/1480] Accessiblity: speakup_apollo: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_apollo module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-3-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_apollo.c | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_apollo.c b/drivers/accessibility/speakup/speakup_apollo.c index c84a7e0864b7c..d2fbb3f572219 100644 --- a/drivers/accessibility/speakup/speakup_apollo.c +++ b/drivers/accessibility/speakup/speakup_apollo.c @@ -24,15 +24,28 @@ static void do_catch_up(struct spk_synth *synth); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"cap, " } }, - { CAPS_STOP, .u.s = {"" } }, - { RATE, .u.n = {"@W%d", 6, 1, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"@F%x", 10, 0, 15, 0, 0, NULL } }, - { VOL, .u.n = {"@A%x", 10, 0, 15, 0, 0, NULL } }, - { VOICE, .u.n = {"@V%d", 1, 1, 6, 0, 0, NULL } }, - { LANG, .u.n = {"@=%d,", 1, 1, 4, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, VOICE_ID, LANG_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"cap, " } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"" } }, + [RATE_ID] = { RATE, .u.n = {"@W%d", 6, 1, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"@F%x", 10, 0, 15, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"@A%x", 10, 0, 15, 0, 0, NULL } }, + [VOICE_ID] = { VOICE, .u.n = {"@V%d", 1, 1, 6, 0, 0, NULL } }, + [LANG_ID] = { LANG, .u.n = {"@=%d,", 1, 1, 4, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -193,10 +206,25 @@ static void do_catch_up(struct spk_synth *synth) module_param_named(ser, synth_apollo.ser, int, 0444); module_param_named(dev, synth_apollo.dev_name, charp, 0444); module_param_named(start, synth_apollo.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(lang, vars[LANG_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(lang, "Set the lang variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + + module_spk_synth(synth_apollo); -- GitLab From d5dab7ff97b8370d8bf406d9be2113b1df7d2f0c Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:56 +0500 Subject: [PATCH 0796/1480] Accessiblity: speakup_audptr: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding a default variables to the speakup_audptr module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-4-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_audptr.c | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_audptr.c b/drivers/accessibility/speakup/speakup_audptr.c index 4d16d60db9b23..55813f3e40ff5 100644 --- a/drivers/accessibility/speakup/speakup_audptr.c +++ b/drivers/accessibility/speakup/speakup_audptr.c @@ -19,15 +19,24 @@ static int synth_probe(struct spk_synth *synth); static void synth_flush(struct spk_synth *synth); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x05[f99]" } }, - { CAPS_STOP, .u.s = {"\x05[f80]" } }, - { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } }, - { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } }, - { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } }, - { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } }, - { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, PUNCT_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x05[f99]" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x05[f80]" } }, + [RATE_ID] = { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -158,10 +167,25 @@ static int synth_probe(struct spk_synth *synth) module_param_named(ser, synth_audptr.ser, int, 0444); module_param_named(dev, synth_audptr.dev_name, charp, 0444); module_param_named(start, synth_audptr.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_audptr); -- GitLab From 95892c4e70f391955dcd69dd25bd6be8f888590f Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:57 +0500 Subject: [PATCH 0797/1480] Accessiblity: speakup_bns: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_bns module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-5-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_bns.c | 36 ++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_bns.c b/drivers/accessibility/speakup/speakup_bns.c index b8103eb117b86..60507756499c2 100644 --- a/drivers/accessibility/speakup/speakup_bns.c +++ b/drivers/accessibility/speakup/speakup_bns.c @@ -16,14 +16,23 @@ #define SYNTH_CLEAR 0x18 #define PROCSPEECH '\r' -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x05\x31\x32P" } }, - { CAPS_STOP, .u.s = {"\x05\x38P" } }, - { RATE, .u.n = {"\x05%dE", 8, 1, 16, 0, 0, NULL } }, - { PITCH, .u.n = {"\x05%dP", 8, 0, 16, 0, 0, NULL } }, - { VOL, .u.n = {"\x05%dV", 8, 0, 16, 0, 0, NULL } }, - { TONE, .u.n = {"\x05%dT", 8, 0, 16, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x05\x31\x32P" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x05\x38P" } }, + [RATE_ID] = { RATE, .u.n = {"\x05%dE", 8, 1, 16, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x05%dP", 8, 0, 16, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x05%dV", 8, 0, 16, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x05%dT", 8, 0, 16, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -113,10 +122,21 @@ static struct spk_synth synth_bns = { module_param_named(ser, synth_bns.ser, int, 0444); module_param_named(dev, synth_bns.dev_name, charp, 0444); module_param_named(start, synth_bns.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); module_spk_synth(synth_bns); -- GitLab From f613f00eb046970f20f4abe1ab8b26c1424a4f5a Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:58 +0500 Subject: [PATCH 0798/1480] Accessiblity: speakup_decext: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding a default variables to the speakup_decext module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-6-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_decext.c | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_decext.c b/drivers/accessibility/speakup/speakup_decext.c index eaebf62300a41..271bcf279bf9b 100644 --- a/drivers/accessibility/speakup/speakup_decext.c +++ b/drivers/accessibility/speakup/speakup_decext.c @@ -38,16 +38,25 @@ static void synth_flush(struct spk_synth *synth); static int in_escape; -static struct var_t vars[] = { - { CAPS_START, .u.s = {"[:dv ap 222]" } }, - { CAPS_STOP, .u.s = {"[:dv ap 100]" } }, - { RATE, .u.n = {"[:ra %d]", 7, 0, 9, 150, 25, NULL } }, - { PITCH, .u.n = {"[:dv ap %d]", 100, 0, 100, 0, 0, NULL } }, - { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, - { VOL, .u.n = {"[:dv gv %d]", 13, 0, 16, 0, 5, NULL } }, - { PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" } }, - { VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, INFLECTION_ID, + VOL_ID, PUNCT_ID, VOICE_ID, + DIRECT_ID, V_LAST_ID, + NB_ID, +}; + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"[:dv ap 222]" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"[:dv ap 100]" } }, + [RATE_ID] = { RATE, .u.n = {"[:ra %d]", 7, 0, 9, 150, 25, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"[:dv ap %d]", 100, 0, 100, 0, 0, NULL } }, + [INFLECTION_ID] = { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"[:dv gv %d]", 13, 0, 16, 0, 5, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" } }, + [VOICE_ID] = { VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -225,10 +234,25 @@ static void synth_flush(struct spk_synth *synth) module_param_named(ser, synth_decext.ser, int, 0444); module_param_named(dev, synth_decext.dev_name, charp, 0444); module_param_named(start, synth_decext.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(inflection, vars[INFLECTION_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(inflection, "Set the inflection variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); module_spk_synth(synth_decext); -- GitLab From b75cfeb116de5894a2e7cc6f8bcf53c4910a7c6f Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:50:59 +0500 Subject: [PATCH 0799/1480] Accessiblity: speakup_decpc: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_decpc module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-7-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_decpc.c | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_decpc.c b/drivers/accessibility/speakup/speakup_decpc.c index dec314dee214f..083ca92658057 100644 --- a/drivers/accessibility/speakup/speakup_decpc.c +++ b/drivers/accessibility/speakup/speakup_decpc.c @@ -134,16 +134,27 @@ static int synth_portlist[] = { 0x340, 0x350, 0x240, 0x250, 0 }; static int in_escape, is_flushing; static int dt_stat, dma_state; -static struct var_t vars[] = { - { CAPS_START, .u.s = {"[:dv ap 200]" } }, - { CAPS_STOP, .u.s = {"[:dv ap 100]" } }, - { RATE, .u.n = {"[:ra %d]", 9, 0, 18, 150, 25, NULL } }, - { PITCH, .u.n = {"[:dv ap %d]", 80, 0, 100, 20, 0, NULL } }, - { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, - { VOL, .u.n = {"[:vo se %d]", 5, 0, 9, 5, 10, NULL } }, - { PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" } }, - { VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, INFLECTION_ID, + VOL_ID, PUNCT_ID, VOICE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID, +}; + + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"[:dv ap 200]" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"[:dv ap 100]" } }, + [RATE_ID] = { RATE, .u.n = {"[:ra %d]", 9, 0, 18, 150, 25, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"[:dv ap %d]", 80, 0, 100, 20, 0, NULL } }, + [INFLECTION_ID] = { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"[:vo se %d]", 5, 0, 9, 5, 10, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" } }, + [VOICE_ID] = { VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -483,8 +494,25 @@ static void dtpc_release(struct spk_synth *synth) } module_param_named(start, synth_dec_pc.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(inflection, vars[INFLECTION_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + + MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(inflection, "Set the inflection variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); module_spk_synth(synth_dec_pc); -- GitLab From 44d3e977dd361f4491bd5adc31f32ca13243703b Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:00 +0500 Subject: [PATCH 0800/1480] Accessiblity: speakup_dectlk: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding a default variables to the speakup_dectlk module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-8-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_dectlk.c | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_dectlk.c b/drivers/accessibility/speakup/speakup_dectlk.c index 2a7e8d727904a..56334405d865c 100644 --- a/drivers/accessibility/speakup/speakup_dectlk.c +++ b/drivers/accessibility/speakup/speakup_dectlk.c @@ -40,16 +40,24 @@ static int is_flushing; static DEFINE_SPINLOCK(flush_lock); static DECLARE_WAIT_QUEUE_HEAD(flush); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"[:dv ap 160] " } }, - { CAPS_STOP, .u.s = {"[:dv ap 100 ] " } }, - { RATE, .u.n = {"[:ra %d] ", 180, 75, 650, 0, 0, NULL } }, - { PITCH, .u.n = {"[:dv ap %d] ", 122, 50, 350, 0, 0, NULL } }, - { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, - { VOL, .u.n = {"[:dv g5 %d] ", 86, 60, 86, 0, 0, NULL } }, - { PUNCT, .u.n = {"[:pu %c] ", 0, 0, 2, 0, 0, "nsa" } }, - { VOICE, .u.n = {"[:n%c] ", 0, 0, 9, 0, 0, "phfdburwkv" } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, INFLECTION_ID, + VOL_ID, PUNCT_ID, VOICE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID, +}; + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"[:dv ap 160] " } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"[:dv ap 100 ] " } }, + [RATE_ID] = { RATE, .u.n = {"[:ra %d] ", 180, 75, 650, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"[:dv ap %d] ", 122, 50, 350, 0, 0, NULL } }, + [INFLECTION_ID] = { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"[:dv g5 %d] ", 86, 60, 86, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"[:pu %c] ", 0, 0, 2, 0, 0, "nsa" } }, + [VOICE_ID] = { VOICE, .u.n = {"[:n%c] ", 0, 0, 9, 0, 0, "phfdburwkv" } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -306,10 +314,27 @@ static void synth_flush(struct spk_synth *synth) module_param_named(ser, synth_dectlk.ser, int, 0444); module_param_named(dev, synth_dectlk.dev_name, charp, 0444); module_param_named(start, synth_dectlk.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(inflection, vars[INFLECTION_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(inflection, "Set the inflection variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_dectlk); -- GitLab From 251ca7da3087361d25bfd05e23ebd711e82ccf20 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:01 +0500 Subject: [PATCH 0801/1480] Accessiblity: speakup_dtlk: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_dtlk module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-9-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_dtlk.c | 50 +++++++++++++++----- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_dtlk.c b/drivers/accessibility/speakup/speakup_dtlk.c index 6f01e010aaf43..fa826568937bf 100644 --- a/drivers/accessibility/speakup/speakup_dtlk.c +++ b/drivers/accessibility/speakup/speakup_dtlk.c @@ -37,17 +37,27 @@ static unsigned int synth_portlist[] = { static u_char synth_status; -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x01+35p" } }, - { CAPS_STOP, .u.s = {"\x01-35p" } }, - { RATE, .u.n = {"\x01%ds", 8, 0, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"\x01%dp", 50, 0, 99, 0, 0, NULL } }, - { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, - { PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL } }, - { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, - { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, PUNCT_ID, + VOICE_ID, FREQUENCY_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID, +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x01+35p" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x01-35p" } }, + [RATE_ID] = { RATE, .u.n = {"\x01%ds", 8, 0, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x01%dp", 50, 0, 99, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL } }, + [VOICE_ID] = { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, + [FREQUENCY_ID] = { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -376,9 +386,27 @@ static void dtlk_release(struct spk_synth *synth) module_param_hw_named(port, port_forced, int, ioport, 0444); module_param_named(start, synth_dtlk.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(frequency, vars[FREQUENCY_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(frequency, "Set the frequency variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_dtlk); -- GitLab From 81188dd195788a1b314570c5d901a88de2179cf4 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:02 +0500 Subject: [PATCH 0802/1480] Accessiblity: speakup_dummy: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_dummy module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-10-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_dummy.c | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_dummy.c b/drivers/accessibility/speakup/speakup_dummy.c index 56419dbb28d3c..52b2c5d44576d 100644 --- a/drivers/accessibility/speakup/speakup_dummy.c +++ b/drivers/accessibility/speakup/speakup_dummy.c @@ -18,17 +18,30 @@ #define DRV_VERSION "2.11" #define SYNTH_CLEAR '!' -static struct var_t vars[] = { - { CAPS_START, .u.s = {"CAPS_START\n" } }, - { CAPS_STOP, .u.s = {"CAPS_STOP\n" } }, - { PAUSE, .u.s = {"PAUSE\n"} }, - { RATE, .u.n = {"RATE %d\n", 8, 1, 16, 0, 0, NULL } }, - { PITCH, .u.n = {"PITCH %d\n", 8, 0, 16, 0, 0, NULL } }, - { INFLECTION, .u.n = {"INFLECTION %d\n", 8, 0, 16, 0, 0, NULL } }, - { VOL, .u.n = {"VOL %d\n", 8, 0, 16, 0, 0, NULL } }, - { TONE, .u.n = {"TONE %d\n", 8, 0, 16, 0, 0, NULL } }, - { PUNCT, .u.n = {"PUNCT %d\n", 0, 0, 3, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + PAUSE_ID, + RATE_ID, PITCH_ID, INFLECTION_ID, + VOL_ID, TONE_ID, PUNCT_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"CAPS_START\n" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"CAPS_STOP\n" } }, + [PAUSE_ID] = { PAUSE, .u.s = {"PAUSE\n"} }, + [RATE_ID] = { RATE, .u.n = {"RATE %d\n", 8, 1, 16, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"PITCH %d\n", 8, 0, 16, 0, 0, NULL } }, + [INFLECTION_ID] = { INFLECTION, .u.n = {"INFLECTION %d\n", 8, 0, 16, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"VOL %d\n", 8, 0, 16, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"TONE %d\n", 8, 0, 16, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"PUNCT %d\n", 0, 0, 3, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -129,10 +142,28 @@ static struct spk_synth synth_dummy = { module_param_named(ser, synth_dummy.ser, int, 0444); module_param_named(dev, synth_dummy.dev_name, charp, 0444); module_param_named(start, synth_dummy.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(inflection, vars[INFLECTION_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(inflection, "Set the inflection variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_dummy); -- GitLab From 031c122f8950f939b715781dadea0b7659f1ea3b Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:03 +0500 Subject: [PATCH 0803/1480] Accessiblity: speakup_keypc: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_keypc module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-11-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_keypc.c | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_keypc.c b/drivers/accessibility/speakup/speakup_keypc.c index f61b62f1ea4db..9356f63795603 100644 --- a/drivers/accessibility/speakup/speakup_keypc.c +++ b/drivers/accessibility/speakup/speakup_keypc.c @@ -33,12 +33,21 @@ static int synth_port; static int port_forced; static unsigned int synth_portlist[] = { 0x2a8, 0 }; -static struct var_t vars[] = { - { CAPS_START, .u.s = {"[f130]" } }, - { CAPS_STOP, .u.s = {"[f90]" } }, - { RATE, .u.n = {"\04%c ", 8, 0, 10, 81, -8, NULL } }, - { PITCH, .u.n = {"[f%d]", 5, 0, 9, 40, 10, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"[f130]" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"[f90]" } }, + [RATE_ID] = { RATE, .u.n = {"\04%c ", 8, 0, 10, 81, -8, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"[f%d]", 5, 0, 9, 40, 10, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -305,9 +314,17 @@ static void keynote_release(struct spk_synth *synth) module_param_hw_named(port, port_forced, int, ioport, 0444); module_param_named(start, synth_keypc.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + + module_spk_synth(synth_keypc); -- GitLab From 88dce45b3282647ac0b2916d4820956cd239a1e9 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:04 +0500 Subject: [PATCH 0804/1480] Accessiblity: speakup_ltlk: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_ltlk module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-12-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_ltlk.c | 53 ++++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_ltlk.c b/drivers/accessibility/speakup/speakup_ltlk.c index f885cfaa27c80..1e279ae143bfd 100644 --- a/drivers/accessibility/speakup/speakup_ltlk.c +++ b/drivers/accessibility/speakup/speakup_ltlk.c @@ -18,17 +18,28 @@ static int synth_probe(struct spk_synth *synth); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x01+35p" } }, - { CAPS_STOP, .u.s = {"\x01-35p" } }, - { RATE, .u.n = {"\x01%ds", 8, 0, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"\x01%dp", 50, 0, 99, 0, 0, NULL } }, - { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, - { PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL } }, - { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, - { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, PUNCT_ID, + VOICE_ID, FREQUENCY_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x01+35p" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x01-35p" } }, + [RATE_ID] = { RATE, .u.n = {"\x01%ds", 8, 0, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x01%dp", 50, 0, 99, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL } }, + [VOICE_ID] = { VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL } }, + [FREQUENCY_ID] = { FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -160,10 +171,30 @@ static int synth_probe(struct spk_synth *synth) module_param_named(ser, synth_ltlk.ser, int, 0444); module_param_named(dev, synth_ltlk.dev_name, charp, 0444); module_param_named(start, synth_ltlk.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(voice, vars[VOICE_ID].u.n.default_val, int, 0444); +module_param_named(frequency, vars[FREQUENCY_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(voice, "Set the voice variable on load."); +MODULE_PARM_DESC(frequency, "Set the frequency variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_ltlk); -- GitLab From 9744f41fe0879eb971a5cab950f7022ac49c0a92 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:05 +0500 Subject: [PATCH 0805/1480] Accessiblity: speakup_spkout: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_spkout module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-13-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_spkout.c | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_spkout.c b/drivers/accessibility/speakup/speakup_spkout.c index 5e3bb3aa98b62..d3f26095b0eef 100644 --- a/drivers/accessibility/speakup/speakup_spkout.c +++ b/drivers/accessibility/speakup/speakup_spkout.c @@ -18,15 +18,26 @@ static void synth_flush(struct spk_synth *synth); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x05P+" } }, - { CAPS_STOP, .u.s = {"\x05P-" } }, - { RATE, .u.n = {"\x05R%d", 7, 0, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"\x05P%d", 3, 0, 9, 0, 0, NULL } }, - { VOL, .u.n = {"\x05V%d", 9, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\x05T%c", 8, 0, 25, 65, 0, NULL } }, - { PUNCT, .u.n = {"\x05M%c", 0, 0, 3, 0, 0, "nsma" } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, PUNCT_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x05P+" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x05P-" } }, + [RATE_ID] = { RATE, .u.n = {"\x05R%d", 7, 0, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x05P%d", 3, 0, 9, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x05V%d", 9, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x05T%c", 8, 0, 25, 65, 0, NULL } }, + [PUNCT_ID] = { PUNCT, .u.n = {"\x05M%c", 0, 0, 3, 0, 0, "nsma" } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -124,10 +135,24 @@ static void synth_flush(struct spk_synth *synth) module_param_named(ser, synth_spkout.ser, int, 0444); module_param_named(dev, synth_spkout.dev_name, charp, 0444); module_param_named(start, synth_spkout.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(punct, vars[PUNCT_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(punct, "Set the punct variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + + module_spk_synth(synth_spkout); -- GitLab From dfa6c10c89f8e9d001d649201bd5a5d821c23c36 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:06 +0500 Subject: [PATCH 0806/1480] Accessiblity: speakup_txprt: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding a default variables to the speakup_txprt module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Link: https://lore.kernel.org/r/20221109215108.7933-14-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/speakup_txprt.c | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_txprt.c b/drivers/accessibility/speakup/speakup_txprt.c index 9e781347f7ebb..4d0a0d4c41f0b 100644 --- a/drivers/accessibility/speakup/speakup_txprt.c +++ b/drivers/accessibility/speakup/speakup_txprt.c @@ -16,14 +16,29 @@ #define SYNTH_CLEAR 0x18 #define PROCSPEECH '\r' /* process speech char */ -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\x05P8" } }, - { CAPS_STOP, .u.s = {"\x05P5" } }, - { RATE, .u.n = {"\x05R%d", 5, 0, 9, 0, 0, NULL } }, - { PITCH, .u.n = {"\x05P%d", 5, 0, 9, 0, 0, NULL } }, - { VOL, .u.n = {"\x05V%d", 5, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\x05T%c", 12, 0, 25, 61, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + + + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + + + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\x05P8" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\x05P5" } }, + [RATE_ID] = { RATE, .u.n = {"\x05R%d", 5, 0, 9, 0, 0, NULL } }, + [PITCH_ID] = { PITCH, .u.n = {"\x05P%d", 5, 0, 9, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\x05V%d", 5, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\x05T%c", 12, 0, 25, 61, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -112,10 +127,24 @@ static struct spk_synth synth_txprt = { module_param_named(ser, synth_txprt.ser, int, 0444); module_param_named(dev, synth_txprt.dev_name, charp, 0444); module_param_named(start, synth_txprt.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + + module_spk_synth(synth_txprt); -- GitLab From cf0b4652d6acaed768b81b153872476a10b7db3b Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:07 +0500 Subject: [PATCH 0807/1480] Accessiblity: speakup_acntpc: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_acntpc module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-15-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_acntpc.c | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_acntpc.c b/drivers/accessibility/speakup/speakup_acntpc.c index a55b60754eb10..a27e6bbf05da3 100644 --- a/drivers/accessibility/speakup/speakup_acntpc.c +++ b/drivers/accessibility/speakup/speakup_acntpc.c @@ -34,14 +34,23 @@ static int synth_port_control; static int port_forced; static unsigned int synth_portlist[] = { 0x2a8, 0 }; -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\033P8" } }, - { CAPS_STOP, .u.s = {"\033P5" } }, - { RATE, .u.n = {"\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" } }, - { PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL } }, - { VOL, .u.n = {"\033A%d", 5, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\033P8" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\033P5" } }, + [RATE_ID] = { RATE, .u.n = {"\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" } }, + [PITCH_ID] = { PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\033A%d", 5, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -305,9 +314,22 @@ static void accent_release(struct spk_synth *synth) module_param_hw_named(port, port_forced, int, ioport, 0444); module_param_named(start, synth_acntpc.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); + + MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing)."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_acntpc); -- GitLab From a606dd6253b8de8dc81a1112ab702edfe7a98d72 Mon Sep 17 00:00:00 2001 From: Osama Muhammad Date: Thu, 10 Nov 2022 02:51:08 +0500 Subject: [PATCH 0808/1480] Accessiblity: speakup_acntsa: specifying the default driver parameters among the module params This is an enhancement which allows to specify the default driver parameters among the module parameters. Adding default variables to the speakup_acntsa module allows to easily set that at boot, rather than setting the sys variables after boot. More details can be found here: https://github.com/linux-speakup/speakup/issues/7 Signed-off-by: Osama Muhammad Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221109215108.7933-16-osmtendev@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../accessibility/speakup/speakup_acntsa.c | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_acntsa.c b/drivers/accessibility/speakup/speakup_acntsa.c index 2697c51ed6b56..26bb9f9399d33 100644 --- a/drivers/accessibility/speakup/speakup_acntsa.c +++ b/drivers/accessibility/speakup/speakup_acntsa.c @@ -19,14 +19,24 @@ static int synth_probe(struct spk_synth *synth); -static struct var_t vars[] = { - { CAPS_START, .u.s = {"\033P8" } }, - { CAPS_STOP, .u.s = {"\033P5" } }, - { RATE, .u.n = {"\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" } }, - { PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL } }, - { VOL, .u.n = {"\033A%d", 9, 0, 9, 0, 0, NULL } }, - { TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL } }, - { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, + +enum default_vars_id { + CAPS_START_ID = 0, CAPS_STOP_ID, + RATE_ID, PITCH_ID, + VOL_ID, TONE_ID, + DIRECT_ID, V_LAST_VAR_ID, + NB_ID +}; + + +static struct var_t vars[NB_ID] = { + [CAPS_START_ID] = { CAPS_START, .u.s = {"\033P8" } }, + [CAPS_STOP_ID] = { CAPS_STOP, .u.s = {"\033P5" } }, + [RATE_ID] = { RATE, .u.n = {"\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" } }, + [PITCH_ID] = { PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL } }, + [VOL_ID] = { VOL, .u.n = {"\033A%d", 9, 0, 9, 0, 0, NULL } }, + [TONE_ID] = { TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL } }, + [DIRECT_ID] = { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR }; @@ -129,10 +139,21 @@ static int synth_probe(struct spk_synth *synth) module_param_named(ser, synth_acntsa.ser, int, 0444); module_param_named(dev, synth_acntsa.dev_name, charp, 0444); module_param_named(start, synth_acntsa.startup, short, 0444); +module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444); +module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444); +module_param_named(vol, vars[VOL_ID].u.n.default_val, int, 0444); +module_param_named(tone, vars[TONE_ID].u.n.default_val, int, 0444); +module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444); MODULE_PARM_DESC(ser, "Set the serial port for the synthesizer (0-based)."); MODULE_PARM_DESC(dev, "Set the device e.g. ttyUSB0, for the synthesizer."); MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded."); +MODULE_PARM_DESC(rate, "Set the rate variable on load."); +MODULE_PARM_DESC(pitch, "Set the pitch variable on load."); +MODULE_PARM_DESC(vol, "Set the vol variable on load."); +MODULE_PARM_DESC(tone, "Set the tone variable on load."); +MODULE_PARM_DESC(direct, "Set the direct variable on load."); + module_spk_synth(synth_acntsa); -- GitLab From f43241aafedb1c7d72825cea1a521cef183ee61d Mon Sep 17 00:00:00 2001 From: Mushahid Hussain Date: Tue, 15 Nov 2022 15:05:29 +0500 Subject: [PATCH 0809/1480] accessibility: speakup: Specify spk_vars among module parameters This is an enhancement which allows setting default variables for speakup module at the boot rather than setting the sys variables after the boot. Signed-off-by: Mushahid Hussain Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221115100530.91174-2-mushi.shar@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/main.c | 60 ++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c index 73db0cb44fc7b..1df9a27a5214d 100644 --- a/drivers/accessibility/speakup/main.c +++ b/drivers/accessibility/speakup/main.c @@ -1268,20 +1268,28 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) return 0; } -static struct var_t spk_vars[] = { +enum spk_vars_id { + BELL_POS_ID = 0, SPELL_DELAY_ID, ATTRIB_BLEEP_ID, + BLEEPS_ID, BLEEP_TIME_ID, PUNC_LEVEL_ID, + READING_PUNC_ID, CURSOR_TIME_ID, SAY_CONTROL_ID, + SAY_WORD_CTL_ID, NO_INTERRUPT_ID, KEY_ECHO_ID, + V_LAST_VAR_ID, NB_ID +}; + +static struct var_t spk_vars[NB_ID] = { /* bell must be first to set high limit */ - {BELL_POS, .u.n = {NULL, 0, 0, 0, 0, 0, NULL} }, - {SPELL_DELAY, .u.n = {NULL, 0, 0, 4, 0, 0, NULL} }, - {ATTRIB_BLEEP, .u.n = {NULL, 1, 0, 3, 0, 0, NULL} }, - {BLEEPS, .u.n = {NULL, 3, 0, 3, 0, 0, NULL} }, - {BLEEP_TIME, .u.n = {NULL, 30, 1, 200, 0, 0, NULL} }, - {PUNC_LEVEL, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, - {READING_PUNC, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, - {CURSOR_TIME, .u.n = {NULL, 120, 50, 600, 0, 0, NULL} }, - {SAY_CONTROL, TOGGLE_0}, - {SAY_WORD_CTL, TOGGLE_0}, - {NO_INTERRUPT, TOGGLE_0}, - {KEY_ECHO, .u.n = {NULL, 1, 0, 2, 0, 0, NULL} }, + [BELL_POS_ID] = { BELL_POS, .u.n = {NULL, 0, 0, 0, 0, 0, NULL} }, + [SPELL_DELAY_ID] = { SPELL_DELAY, .u.n = {NULL, 0, 0, 4, 0, 0, NULL} }, + [ATTRIB_BLEEP_ID] = { ATTRIB_BLEEP, .u.n = {NULL, 1, 0, 3, 0, 0, NULL} }, + [BLEEPS_ID] = { BLEEPS, .u.n = {NULL, 3, 0, 3, 0, 0, NULL} }, + [BLEEP_TIME_ID] = { BLEEP_TIME, .u.n = {NULL, 30, 1, 200, 0, 0, NULL} }, + [PUNC_LEVEL_ID] = { PUNC_LEVEL, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, + [READING_PUNC_ID] = { READING_PUNC, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, + [CURSOR_TIME_ID] = { CURSOR_TIME, .u.n = {NULL, 120, 50, 600, 0, 0, NULL} }, + [SAY_CONTROL_ID] { SAY_CONTROL, TOGGLE_0}, + [SAY_WORD_CTL_ID] = {SAY_WORD_CTL, TOGGLE_0}, + [NO_INTERRUPT_ID] = { NO_INTERRUPT, TOGGLE_0}, + [KEY_ECHO_ID] = { KEY_ECHO, .u.n = {NULL, 1, 0, 2, 0, 0, NULL} }, V_LAST_VAR }; @@ -2453,5 +2461,31 @@ out: return err; } +module_param_named(bell_pos, spk_vars[BELL_POS_ID].u.n.default_val, int, 0444); +module_param_named(spell_delay, spk_vars[SPELL_DELAY_ID].u.n.default_val, int, 0444); +module_param_named(attrib_bleep, spk_vars[ATTRIB_BLEEP_ID].u.n.default_val, int, 0444); +module_param_named(bleeps, spk_vars[BLEEPS_ID].u.n.default_val, int, 0444); +module_param_named(bleep_time, spk_vars[BLEEP_TIME_ID].u.n.default_val, int, 0444); +module_param_named(punc_level, spk_vars[PUNC_LEVEL_ID].u.n.default_val, int, 0444); +module_param_named(reading_punc, spk_vars[READING_PUNC_ID].u.n.default_val, int, 0444); +module_param_named(cursor_time, spk_vars[CURSOR_TIME_ID].u.n.default_val, int, 0444); +module_param_named(say_control, spk_vars[SAY_CONTROL_ID].u.n.default_val, int, 0444); +module_param_named(say_word_ctl, spk_vars[SAY_WORD_CTL_ID].u.n.default_val, int, 0444); +module_param_named(no_interrupt, spk_vars[NO_INTERRUPT_ID].u.n.default_val, int, 0444); +module_param_named(key_echo, spk_vars[KEY_ECHO_ID].u.n.default_val, int, 0444); + +MODULE_PARM_DESC(bell_pos, "This works much like a typewriter bell. If for example 72 is echoed to bell_pos, it will beep the PC speaker when typing on a line past character 72."); +MODULE_PARM_DESC(spell_delay, "This controls how fast a word is spelled when speakup's spell word review command is pressed."); +MODULE_PARM_DESC(attrib_bleep, "Beeps the PC speaker when there is an attribute change such as background color when using speakup review commands. One = on, zero = off."); +MODULE_PARM_DESC(bleeps, "This controls whether one hears beeps through the PC speaker when using speakup review commands."); +MODULE_PARM_DESC(bleep_time, "This controls the duration of the PC speaker beeps speakup produces."); +MODULE_PARM_DESC(punc_level, "Controls the level of punctuation spoken as the screen is displayed, not reviewed."); +MODULE_PARM_DESC(reading_punc, "It controls the level of punctuation when reviewing the screen with speakup's screen review commands."); +MODULE_PARM_DESC(cursor_time, "This controls cursor delay when using arrow keys."); +MODULE_PARM_DESC(say_control, "This controls if speakup speaks shift, alt and control when those keys are pressed or not."); +MODULE_PARM_DESC(say_word_ctl, "Sets thw say_word_ctl on load."); +MODULE_PARM_DESC(no_interrupt, "Controls if typing interrupts output from speakup."); +MODULE_PARM_DESC(key_echo, "Controls if speakup speaks keys when they are typed. One = on zero = off or don't echo keys."); + module_init(speakup_init); module_exit(speakup_exit); -- GitLab From 72b8ec15f97bbabbb2379c87cb5f7a9dc63f0d88 Mon Sep 17 00:00:00 2001 From: Mushahid Hussain Date: Tue, 15 Nov 2022 15:05:30 +0500 Subject: [PATCH 0810/1480] accessibility: speakup: phonetic spelling while arrowing letter by letter This patch includes an enhancement requested frequently on the mailing list.[1][2] It adds a variable, cur_phonetic in the spk_vars, which can be set as a module parameter, as well as in /sys/speakup/cur_phonetic. This patch also documents cur_phonetic as a sysfs attribute in sysfs-driver-speakup. When cur_phonetic=1, it causes speakup to speak letters phonetically if paused on the character while arrowing through a word. When a user does not set cur_phonetic to any value, the default value for it would be 0. [1]: https://github.com/linux-speakup/speakup/issues/6 [2]: https://github.com/linux-speakup/speakup/issues/5 since V1: - removed unnecessary lines Signed-off-by: Mushahid Hussain Reviewed-by: Samuel Thibault Link: https://lore.kernel.org/r/20221115100530.91174-3-mushi.shar@gmail.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-driver-speakup | 9 +++++++++ drivers/accessibility/speakup/kobjects.c | 3 +++ drivers/accessibility/speakup/main.c | 14 +++++++++++--- drivers/accessibility/speakup/speakup.h | 1 + drivers/accessibility/speakup/spk_types.h | 2 +- drivers/accessibility/speakup/varhandlers.c | 1 + 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-driver-speakup b/Documentation/ABI/stable/sysfs-driver-speakup index dc2a6ba1674b8..bcb6831aa114d 100644 --- a/Documentation/ABI/stable/sysfs-driver-speakup +++ b/Documentation/ABI/stable/sysfs-driver-speakup @@ -35,6 +35,15 @@ Description: This controls cursor delay when using arrow keys. When a characters. Set this to a higher value to adjust for the delay and better synchronisation between cursor position and speech. +What: /sys/accessibility/speakup/cur_phonetic +KernelVersion: 6.2 +Contact: speakup@linux-speakup.org +Description: This allows speakup to speak letters phoneticaly when arrowing through + a word letter by letter. This doesn't affect the spelling when typing + the characters. When cur_phonetic=1, speakup will speak characters + phoneticaly when arrowing over a letter. When cur_phonetic=0, speakup + will speak letters as normally. + What: /sys/accessibility/speakup/delimiters KernelVersion: 2.6 Contact: speakup@linux-speakup.org diff --git a/drivers/accessibility/speakup/kobjects.c b/drivers/accessibility/speakup/kobjects.c index 41ae24ab5d086..a7522d4098025 100644 --- a/drivers/accessibility/speakup/kobjects.c +++ b/drivers/accessibility/speakup/kobjects.c @@ -914,6 +914,8 @@ static struct kobj_attribute say_word_ctl_attribute = __ATTR(say_word_ctl, 0644, spk_var_show, spk_var_store); static struct kobj_attribute spell_delay_attribute = __ATTR(spell_delay, 0644, spk_var_show, spk_var_store); +static struct kobj_attribute cur_phonetic_attribute = + __ATTR(cur_phonetic, 0644, spk_var_show, spk_var_store); /* * These attributes are i18n related. @@ -967,6 +969,7 @@ static struct attribute *main_attrs[] = { &say_control_attribute.attr, &say_word_ctl_attribute.attr, &spell_delay_attribute.attr, + &cur_phonetic_attribute.attr, NULL, }; diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c index 1df9a27a5214d..4733fd6334ab8 100644 --- a/drivers/accessibility/speakup/main.c +++ b/drivers/accessibility/speakup/main.c @@ -65,6 +65,7 @@ int spk_key_echo, spk_say_word_ctl; int spk_say_ctrl, spk_bell_pos; short spk_punc_mask; int spk_punc_level, spk_reading_punc; +int spk_cur_phonetic; char spk_str_caps_start[MAXVARLEN + 1] = "\0"; char spk_str_caps_stop[MAXVARLEN + 1] = "\0"; char spk_str_pause[MAXVARLEN + 1] = "\0"; @@ -1273,7 +1274,7 @@ enum spk_vars_id { BLEEPS_ID, BLEEP_TIME_ID, PUNC_LEVEL_ID, READING_PUNC_ID, CURSOR_TIME_ID, SAY_CONTROL_ID, SAY_WORD_CTL_ID, NO_INTERRUPT_ID, KEY_ECHO_ID, - V_LAST_VAR_ID, NB_ID + CUR_PHONETIC_ID, V_LAST_VAR_ID, NB_ID }; static struct var_t spk_vars[NB_ID] = { @@ -1290,6 +1291,7 @@ static struct var_t spk_vars[NB_ID] = { [SAY_WORD_CTL_ID] = {SAY_WORD_CTL, TOGGLE_0}, [NO_INTERRUPT_ID] = { NO_INTERRUPT, TOGGLE_0}, [KEY_ECHO_ID] = { KEY_ECHO, .u.n = {NULL, 1, 0, 2, 0, 0, NULL} }, + [CUR_PHONETIC_ID] = { CUR_PHONETIC, .u.n = {NULL, 0, 0, 1, 0, 0, NULL} }, V_LAST_VAR }; @@ -1720,8 +1722,12 @@ static void cursor_done(struct timer_list *unused) speakup_win_say(vc); else if (is_cursor == 1 || is_cursor == 4) say_line_from_to(vc, 0, vc->vc_cols, 0); - else - say_char(vc); + else { + if (spk_cur_phonetic == 1) + say_phonetic_char(vc); + else + say_char(vc); + } spk_keydown = 0; is_cursor = 0; out: @@ -2473,6 +2479,7 @@ module_param_named(say_control, spk_vars[SAY_CONTROL_ID].u.n.default_val, int, 0 module_param_named(say_word_ctl, spk_vars[SAY_WORD_CTL_ID].u.n.default_val, int, 0444); module_param_named(no_interrupt, spk_vars[NO_INTERRUPT_ID].u.n.default_val, int, 0444); module_param_named(key_echo, spk_vars[KEY_ECHO_ID].u.n.default_val, int, 0444); +module_param_named(cur_phonetic, spk_vars[CUR_PHONETIC_ID].u.n.default_val, int, 0444); MODULE_PARM_DESC(bell_pos, "This works much like a typewriter bell. If for example 72 is echoed to bell_pos, it will beep the PC speaker when typing on a line past character 72."); MODULE_PARM_DESC(spell_delay, "This controls how fast a word is spelled when speakup's spell word review command is pressed."); @@ -2486,6 +2493,7 @@ MODULE_PARM_DESC(say_control, "This controls if speakup speaks shift, alt and co MODULE_PARM_DESC(say_word_ctl, "Sets thw say_word_ctl on load."); MODULE_PARM_DESC(no_interrupt, "Controls if typing interrupts output from speakup."); MODULE_PARM_DESC(key_echo, "Controls if speakup speaks keys when they are typed. One = on zero = off or don't echo keys."); +MODULE_PARM_DESC(cur_phonetic, "Controls if speakup speaks letters phonetically during navigation. One = on zero = off or don't speak phonetically."); module_init(speakup_init); module_exit(speakup_exit); diff --git a/drivers/accessibility/speakup/speakup.h b/drivers/accessibility/speakup/speakup.h index 33594f5a79837..364fde99749ed 100644 --- a/drivers/accessibility/speakup/speakup.h +++ b/drivers/accessibility/speakup/speakup.h @@ -105,6 +105,7 @@ extern int spk_no_intr, spk_say_ctrl, spk_say_word_ctl, spk_punc_level; extern int spk_reading_punc, spk_attrib_bleep, spk_bleeps; extern int spk_bleep_time, spk_bell_pos; extern int spk_spell_delay, spk_key_echo; +extern int spk_cur_phonetic; extern short spk_punc_mask; extern short spk_pitch_shift, synth_flags; extern bool spk_quiet_boot; diff --git a/drivers/accessibility/speakup/spk_types.h b/drivers/accessibility/speakup/spk_types.h index 3a14d39bf896e..08011518a28ae 100644 --- a/drivers/accessibility/speakup/spk_types.h +++ b/drivers/accessibility/speakup/spk_types.h @@ -49,7 +49,7 @@ enum var_id_t { RATE, PITCH, VOL, TONE, PUNCT, VOICE, FREQUENCY, LANG, DIRECT, PAUSE, CAPS_START, CAPS_STOP, CHARTAB, INFLECTION, FLUSH, - MAXVARS + CUR_PHONETIC, MAXVARS }; typedef int (*special_func)(struct vc_data *vc, u_char type, u_char ch, diff --git a/drivers/accessibility/speakup/varhandlers.c b/drivers/accessibility/speakup/varhandlers.c index e1c9f42e39f0f..462f8d879053c 100644 --- a/drivers/accessibility/speakup/varhandlers.c +++ b/drivers/accessibility/speakup/varhandlers.c @@ -48,6 +48,7 @@ static struct st_var_header var_headers[] = { { "chartab", CHARTAB, VAR_PROC, NULL, NULL }, { "direct", DIRECT, VAR_NUM, NULL, NULL }, { "pause", PAUSE, VAR_STRING, spk_str_pause, NULL }, + { "cur_phonetic", CUR_PHONETIC, VAR_NUM, &spk_cur_phonetic, NULL }, }; static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL }; -- GitLab From 7610615e8cdb3f6f5bbd9d8e7a5d8a63e3cabf2e Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Sat, 19 Nov 2022 11:57:21 +0800 Subject: [PATCH 0811/1480] test_firmware: fix memory leak in test_firmware_init() When misc_register() failed in test_firmware_init(), the memory pointed by test_fw_config->name is not released. The memory leak information is as follows: unreferenced object 0xffff88810a34cb00 (size 32): comm "insmod", pid 7952, jiffies 4294948236 (age 49.060s) hex dump (first 32 bytes): 74 65 73 74 2d 66 69 72 6d 77 61 72 65 2e 62 69 test-firmware.bi 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 n............... backtrace: [] __kmalloc_node_track_caller+0x4b/0xc0 [] kstrndup+0x46/0xc0 [] __test_firmware_config_init+0x29/0x380 [test_firmware] [] 0xffffffffa040f068 [] do_one_initcall+0x141/0x780 [] do_init_module+0x1c3/0x630 [] load_module+0x623e/0x76a0 [] __do_sys_finit_module+0x181/0x240 [] do_syscall_64+0x39/0xb0 [] entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: c92316bf8e94 ("test_firmware: add batched firmware tests") Signed-off-by: Zhengchao Shao Acked-by: Luis Chamberlain Link: https://lore.kernel.org/r/20221119035721.18268-1-shaozhengchao@huawei.com Signed-off-by: Greg Kroah-Hartman --- lib/test_firmware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 0c714cdd51eff..e207bc08820d0 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -1491,6 +1491,7 @@ static int __init test_firmware_init(void) rc = misc_register(&test_fw_misc_device); if (rc) { + __test_firmware_config_free(); kfree(test_fw_config); pr_err("could not register misc device: %d\n", rc); return rc; -- GitLab From a4cb1004aeed2ab893a058fad00a5b41a12c4691 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 11 Nov 2022 22:59:29 +0800 Subject: [PATCH 0812/1480] misc: ocxl: fix possible name leak in ocxl_file_register_afu() If device_register() returns error in ocxl_file_register_afu(), the name allocated by dev_set_name() need be freed. As comment of device_register() says, it should use put_device() to give up the reference in the error path. So fix this by calling put_device(), then the name can be freed in kobject_cleanup(), and info is freed in info_release(). Fixes: 75ca758adbaf ("ocxl: Create a clear delineation between ocxl backend & frontend") Signed-off-by: Yang Yingliang Acked-by: Andrew Donnellan Acked-by: Frederic Barrat Link: https://lore.kernel.org/r/20221111145929.2429271-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ocxl/file.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index d46dba2df5a10..452d5777a0e4c 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -541,8 +541,11 @@ int ocxl_file_register_afu(struct ocxl_afu *afu) goto err_put; rc = device_register(&info->dev); - if (rc) - goto err_put; + if (rc) { + free_minor(info); + put_device(&info->dev); + return rc; + } rc = ocxl_sysfs_register_afu(info); if (rc) -- GitLab From 27158c72678b39ee01cc01de1aba6b51c71abe2f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 21 Nov 2022 23:43:39 +0800 Subject: [PATCH 0813/1480] ocxl: fix pci device refcount leak when calling get_function_0() get_function_0() calls pci_get_domain_bus_and_slot(), as comment says, it returns a pci device with refcount increment, so after using it, pci_dev_put() needs be called. Get the device reference when get_function_0() is not called, so pci_dev_put() can be called in the error path and callers unconditionally. And add comment above get_dvsec_vendor0() to tell callers to call pci_dev_put(). Fixes: 87db7579ebd5 ("ocxl: control via sysfs whether the FPGA is reloaded on a link reset") Suggested-by: Andrew Donnellan Signed-off-by: Yang Yingliang Acked-by: Andrew Donnellan Link: https://lore.kernel.org/r/20221121154339.4088935-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ocxl/config.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c index e401a51596b9c..92ab49705f645 100644 --- a/drivers/misc/ocxl/config.c +++ b/drivers/misc/ocxl/config.c @@ -193,6 +193,18 @@ static int read_dvsec_vendor(struct pci_dev *dev) return 0; } +/** + * get_dvsec_vendor0() - Find a related PCI device (function 0) + * @dev: PCI device to match + * @dev0: The PCI device (function 0) found + * @out_pos: The position of PCI device (function 0) + * + * Returns 0 on success, negative on failure. + * + * NOTE: If it's successful, the reference of dev0 is increased, + * so after using it, the callers must call pci_dev_put() to give + * up the reference. + */ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0, int *out_pos) { @@ -202,10 +214,14 @@ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0, dev = get_function_0(dev); if (!dev) return -1; + } else { + dev = pci_dev_get(dev); } pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID); - if (!pos) + if (!pos) { + pci_dev_put(dev); return -1; + } *dev0 = dev; *out_pos = pos; return 0; @@ -222,6 +238,7 @@ int ocxl_config_get_reset_reload(struct pci_dev *dev, int *val) pci_read_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD, &reset_reload); + pci_dev_put(dev0); *val = !!(reset_reload & BIT(0)); return 0; } @@ -243,6 +260,7 @@ int ocxl_config_set_reset_reload(struct pci_dev *dev, int val) reset_reload &= ~BIT(0); pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD, reset_reload); + pci_dev_put(dev0); return 0; } -- GitLab From e68a558fb2af06daa38f86dad25061ddd90ab131 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 18 Nov 2022 02:22:06 +0100 Subject: [PATCH 0814/1480] speakup: Fix building as extmod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit spk_priv_keyinfo.h should be opened from the speakup directory. When building as extmod we should thus open it from the module directory rather than the main Linux source. Signed-off-by: Samuel Thibault  Link: https://lore.kernel.org/r/20221118012206.j6hq6b6nfx2jhqg6@begin Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/Makefile | 4 +++- drivers/accessibility/speakup/makemapdata.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/accessibility/speakup/Makefile b/drivers/accessibility/speakup/Makefile index ba69b0803d428..6f6a83565c0de 100644 --- a/drivers/accessibility/speakup/Makefile +++ b/drivers/accessibility/speakup/Makefile @@ -40,7 +40,9 @@ hostprogs += makemapdata makemapdata-objs := makemapdata.o quiet_cmd_mkmap = MKMAP $@ - cmd_mkmap = TOPDIR=$(srctree) $(obj)/makemapdata > $@ + cmd_mkmap = TOPDIR=$(srctree) \ + SPKDIR=$(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD),$(srctree)/drivers/accessibility/speakup) \ + $(obj)/makemapdata > $@ $(obj)/mapdata.h: $(obj)/makemapdata $(call cmd,mkmap) diff --git a/drivers/accessibility/speakup/makemapdata.c b/drivers/accessibility/speakup/makemapdata.c index 81db9ebf1fff8..d7d41bb9b05fb 100644 --- a/drivers/accessibility/speakup/makemapdata.c +++ b/drivers/accessibility/speakup/makemapdata.c @@ -51,12 +51,15 @@ main(int argc, char *argv[]) { int value, i; struct st_key *this; - const char *dir_name; + const char *dir_name, *spk_dir_name; char *cp; dir_name = getenv("TOPDIR"); if (!dir_name) dir_name = "."; + spk_dir_name = getenv("SPKDIR"); + if (!spk_dir_name) + spk_dir_name = "drivers/accessibility/speakup"; bzero(key_table, sizeof(key_table)); add_key("shift", 1, is_shift); add_key("altgr", 2, is_shift); @@ -83,7 +86,7 @@ main(int argc, char *argv[]) add_key(def_name, value, is_input); } - open_input(dir_name, "drivers/accessibility/speakup/spk_priv_keyinfo.h"); + open_input(spk_dir_name, "spk_priv_keyinfo.h"); while (get_define()) { if (strlen(def_val) > 5) { //if (def_val[0] == '(') -- GitLab From 1dbb4f0235a450f22e518124cbf9b922802ce38f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 16 Nov 2022 18:29:56 +0200 Subject: [PATCH 0815/1480] virt: acrn: Mark the uuid field as unused After the commits for userspace (see Link tags below) the uuid field is not being used in the ACRN code. Update kernel to reflect these changes, i.e. do the following: - adding a comment explaining that it's not used anymore - replacing the specific type by a raw buffer - updating the example code accordingly The advertised field confused users and actually never been used. So the wrong part here is that kernel puts something which userspace never used and hence this may confuse a reader of this code. Note, that there is only a single tool that had been prepared a year ago for these forthcoming changes in the kernel. Link: https://github.com/projectacrn/acrn-hypervisor/commit/da0d24326ed6 Link: https://github.com/projectacrn/acrn-hypervisor/commit/bb0327e70097 Signed-off-by: Andy Shevchenko Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221116162956.72658-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/acrn.h | 5 ++--- samples/acrn/vm-sample.c | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/acrn.h b/include/uapi/linux/acrn.h index ccf47ed925008..7b714c1902eb2 100644 --- a/include/uapi/linux/acrn.h +++ b/include/uapi/linux/acrn.h @@ -12,7 +12,6 @@ #define _UAPI_ACRN_H #include -#include #define ACRN_IO_REQUEST_MAX 16 @@ -186,7 +185,7 @@ struct acrn_ioreq_notify { * @reserved0: Reserved and must be 0 * @vcpu_num: Number of vCPU in the VM. Return from hypervisor. * @reserved1: Reserved and must be 0 - * @uuid: UUID of the VM. Pass to hypervisor directly. + * @uuid: Empty space never to be used again (used to be UUID of the VM) * @vm_flag: Flag of the VM creating. Pass to hypervisor directly. * @ioreq_buf: Service VM GPA of I/O request buffer. Pass to * hypervisor directly. @@ -198,7 +197,7 @@ struct acrn_vm_creation { __u16 reserved0; __u16 vcpu_num; __u16 reserved1; - guid_t uuid; + __u8 uuid[16]; __u64 vm_flag; __u64 ioreq_buf; __u64 cpu_affinity; diff --git a/samples/acrn/vm-sample.c b/samples/acrn/vm-sample.c index b2dad47a77a01..7abd68b20153b 100644 --- a/samples/acrn/vm-sample.c +++ b/samples/acrn/vm-sample.c @@ -29,8 +29,6 @@ static struct acrn_io_request *io_req_buf = (struct acrn_io_request *)io_request __u16 vcpu_num; __u16 vmid; -/* POST_STANDARD_VM_UUID1, refer to https://github.com/projectacrn/acrn-hypervisor/blob/master/hypervisor/include/common/vm_uuids.h */ -guid_t vm_uuid = GUID_INIT(0x385479d2, 0xd625, 0xe811, 0x86, 0x4e, 0xcb, 0x7a, 0x18, 0xb3, 0x46, 0x43); int hsm_fd; int is_running = 1; @@ -63,7 +61,6 @@ int main(int argc, char **argv) } hsm_fd = open("/dev/acrn_hsm", O_RDWR|O_CLOEXEC); - memcpy(&create_vm.uuid, &vm_uuid, 16); create_vm.ioreq_buf = (__u64)io_req_buf; ret = ioctl(hsm_fd, ACRN_IOCTL_CREATE_VM, &create_vm); printf("Created VM! [%d]\n", ret); -- GitLab From fd2c930cf6a5b9176382c15f9acb1996e76e25ad Mon Sep 17 00:00:00 2001 From: ruanjinjie Date: Thu, 17 Nov 2022 14:47:25 +0800 Subject: [PATCH 0816/1480] misc: tifm: fix possible memory leak in tifm_7xx1_switch_media() If device_register() returns error in tifm_7xx1_switch_media(), name of kobject which is allocated in dev_set_name() called in device_add() is leaked. Never directly free @dev after calling device_register(), even if it returned an error! Always use put_device() to give up the reference initialized. Fixes: 2428a8fe2261 ("tifm: move common device management tasks from tifm_7xx1 to tifm_core") Signed-off-by: ruanjinjie Link: https://lore.kernel.org/r/20221117064725.3478402-1-ruanjinjie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/tifm_7xx1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 017c2f7d62871..7dd86a9858aba 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c @@ -190,7 +190,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work) spin_unlock_irqrestore(&fm->lock, flags); } if (sock) - tifm_free_device(&sock->dev); + put_device(&sock->dev); } spin_lock_irqsave(&fm->lock, flags); } -- GitLab From 643a16a0eb1d6ac23744bb6e90a00fc21148a9dc Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Thu, 10 Nov 2022 11:50:33 +0800 Subject: [PATCH 0817/1480] misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault and gru_handle_user_call_os In some bad situation, the gts may be freed gru_check_chiplet_assignment. The call chain can be gru_unload_context->gru_free_gru_context->gts_drop and kfree finally. However, the caller didn't know if the gts is freed or not and use it afterwards. This will trigger a Use after Free bug. Fix it by introducing a return value to see if it's in error path or not. Free the gts in caller if gru_check_chiplet_assignment check failed. Fixes: 55484c45dbec ("gru: allow users to specify gru chiplet 2") Signed-off-by: Zheng Wang Acked-by: Dimitri Sivanich Link: https://lore.kernel.org/r/20221110035033.19498-1-zyytlz.wz@163.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/sgi-gru/grufault.c | 13 +++++++++++-- drivers/misc/sgi-gru/grumain.c | 22 ++++++++++++++++++---- drivers/misc/sgi-gru/grutables.h | 2 +- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c index d7ef61e602ede..b836936e97471 100644 --- a/drivers/misc/sgi-gru/grufault.c +++ b/drivers/misc/sgi-gru/grufault.c @@ -648,6 +648,7 @@ int gru_handle_user_call_os(unsigned long cb) if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB) return -EINVAL; +again: gts = gru_find_lock_gts(cb); if (!gts) return -EINVAL; @@ -656,7 +657,11 @@ int gru_handle_user_call_os(unsigned long cb) if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) goto exit; - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + gru_unlock_gts(gts); + gru_unload_context(gts, 1); + goto again; + } /* * CCH may contain stale data if ts_force_cch_reload is set. @@ -874,7 +879,11 @@ int gru_set_context_option(unsigned long arg) } else { gts->ts_user_blade_id = req.val1; gts->ts_user_chiplet_id = req.val0; - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + gru_unlock_gts(gts); + gru_unload_context(gts, 1); + return ret; + } } break; case sco_gseg_owner: diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c index 6706ef3c59776..4eb4b94551390 100644 --- a/drivers/misc/sgi-gru/grumain.c +++ b/drivers/misc/sgi-gru/grumain.c @@ -716,9 +716,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru, * chiplet. Misassignment can occur if the process migrates to a different * blade or if the user changes the selected blade/chiplet. */ -void gru_check_context_placement(struct gru_thread_state *gts) +int gru_check_context_placement(struct gru_thread_state *gts) { struct gru_state *gru; + int ret = 0; /* * If the current task is the context owner, verify that the @@ -726,15 +727,23 @@ void gru_check_context_placement(struct gru_thread_state *gts) * references. Pthread apps use non-owner references to the CBRs. */ gru = gts->ts_gru; + /* + * If gru or gts->ts_tgid_owner isn't initialized properly, return + * success to indicate that the caller does not need to unload the + * gru context.The caller is responsible for their inspection and + * reinitialization if needed. + */ if (!gru || gts->ts_tgid_owner != current->tgid) - return; + return ret; if (!gru_check_chiplet_assignment(gru, gts)) { STAT(check_context_unload); - gru_unload_context(gts, 1); + ret = -EINVAL; } else if (gru_retarget_intr(gts)) { STAT(check_context_retarget_intr); } + + return ret; } @@ -934,7 +943,12 @@ again: mutex_lock(>s->ts_ctxlock); preempt_disable(); - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + preempt_enable(); + mutex_unlock(>s->ts_ctxlock); + gru_unload_context(gts, 1); + return VM_FAULT_NOPAGE; + } if (!gts->ts_gru) { STAT(load_user_context); diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index 8c52776db2341..640daf1994df7 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h @@ -632,7 +632,7 @@ extern int gru_user_flush_tlb(unsigned long arg); extern int gru_user_unload_context(unsigned long arg); extern int gru_get_exception_detail(unsigned long arg); extern int gru_set_context_option(unsigned long address); -extern void gru_check_context_placement(struct gru_thread_state *gts); +extern int gru_check_context_placement(struct gru_thread_state *gts); extern int gru_cpu_fault_map_id(void); extern struct vm_area_struct *gru_find_vma(unsigned long vaddr); extern void gru_flush_all_tlb(struct gru_state *gru); -- GitLab From 7198cf0f1ca90581f27452664216a662ad72aed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:48 +0100 Subject: [PATCH 0818/1480] misc: lis3lv02d/lis3lv02d_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-495-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index d7daa01fe7ca9..7071412d6bf63 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -100,8 +100,7 @@ static const struct of_device_id lis3lv02d_i2c_dt_ids[] = { MODULE_DEVICE_TABLE(of, lis3lv02d_i2c_dt_ids); #endif -static int lis3lv02d_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lis3lv02d_i2c_probe(struct i2c_client *client) { int ret = 0; struct lis3lv02d_platform_data *pdata = client->dev.platform_data; @@ -263,7 +262,7 @@ static struct i2c_driver lis3lv02d_i2c_driver = { .pm = &lis3_pm_ops, .of_match_table = of_match_ptr(lis3lv02d_i2c_dt_ids), }, - .probe = lis3lv02d_i2c_probe, + .probe_new = lis3lv02d_i2c_probe, .remove = lis3lv02d_i2c_remove, .id_table = lis3lv02d_id, }; -- GitLab From 59ee8ca4eeda35d850e4c81ec3065dba10023842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:41 +0100 Subject: [PATCH 0819/1480] misc: eeprom/eeprom: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-488-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/eeprom.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 8a841a75d8931..32611100d5cd3 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -141,8 +141,7 @@ static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) return 0; } -static int eeprom_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int eeprom_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct eeprom_data *data; @@ -197,7 +196,7 @@ static struct i2c_driver eeprom_driver = { .driver = { .name = "eeprom", }, - .probe = eeprom_probe, + .probe_new = eeprom_probe, .remove = eeprom_remove, .id_table = eeprom_id, -- GitLab From 8427bd8bdee8f35797cade56fe173fbea990e38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:49 +0100 Subject: [PATCH 0820/1480] misc: tsl2550: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-496-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/tsl2550.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 1652fb9b3856c..6c62b94e0acdb 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -331,8 +331,7 @@ static int tsl2550_init_client(struct i2c_client *client) */ static struct i2c_driver tsl2550_driver; -static int tsl2550_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsl2550_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct tsl2550_data *data; @@ -438,7 +437,7 @@ static struct i2c_driver tsl2550_driver = { .of_match_table = tsl2550_of_match, .pm = TSL2550_PM_OPS, }, - .probe = tsl2550_probe, + .probe_new = tsl2550_probe, .remove = tsl2550_remove, .id_table = tsl2550_id, }; -- GitLab From 327e1ad186d91b12b6ece0b21178c07edef01806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:47 +0100 Subject: [PATCH 0821/1480] misc: isl29020: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-494-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/isl29020.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index c6f2a94f501ac..3be02093368cf 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -151,8 +151,7 @@ static int als_set_default_config(struct i2c_client *client) return 0; } -static int isl29020_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29020_probe(struct i2c_client *client) { int res; @@ -215,7 +214,7 @@ static struct i2c_driver isl29020_driver = { .name = "isl29020", .pm = ISL29020_PM_OPS, }, - .probe = isl29020_probe, + .probe_new = isl29020_probe, .remove = isl29020_remove, .id_table = isl29020_id, }; -- GitLab From 99b0cb3f5f8d67f4552c24d9b0aa6cda38f558aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:43 +0100 Subject: [PATCH 0822/1480] misc: eeprom/max6875: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-490-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/max6875.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 6bd4f4339af4a..79cf8afcef2e8 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -130,8 +130,7 @@ static const struct bin_attribute user_eeprom_attr = { .read = max6875_read, }; -static int max6875_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max6875_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct max6875_data *data; @@ -193,7 +192,7 @@ static struct i2c_driver max6875_driver = { .driver = { .name = "max6875", }, - .probe = max6875_probe, + .probe_new = max6875_probe, .remove = max6875_remove, .id_table = max6875_id, }; -- GitLab From 654700c9fc2860d33d57b42fd39cae2310dbc2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:44 +0100 Subject: [PATCH 0823/1480] misc: hmc6352: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-491-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hmc6352.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index 42b9adef28a3c..8967940ecd1e8 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -101,8 +101,7 @@ static const struct attribute_group m_compass_gr = { .attrs = mid_att_compass }; -static int hmc6352_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hmc6352_probe(struct i2c_client *client) { int res; @@ -132,7 +131,7 @@ static struct i2c_driver hmc6352_driver = { .driver = { .name = "hmc6352", }, - .probe = hmc6352_probe, + .probe_new = hmc6352_probe, .remove = hmc6352_remove, .id_table = hmc6352_id, }; -- GitLab From 9c18dad44dc1de202a69c8ccef983e6070740acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:45 +0100 Subject: [PATCH 0824/1480] misc: ics932s401: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-492-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ics932s401.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 1cb71df966a4c..12108a7b9b40d 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -89,8 +89,7 @@ struct ics932s401_data { u8 regs[NUM_REGS]; }; -static int ics932s401_probe(struct i2c_client *client, - const struct i2c_device_id *id); +static int ics932s401_probe(struct i2c_client *client); static int ics932s401_detect(struct i2c_client *client, struct i2c_board_info *info); static void ics932s401_remove(struct i2c_client *client); @@ -106,7 +105,7 @@ static struct i2c_driver ics932s401_driver = { .driver = { .name = "ics932s401", }, - .probe = ics932s401_probe, + .probe_new = ics932s401_probe, .remove = ics932s401_remove, .id_table = ics932s401_id, .detect = ics932s401_detect, @@ -429,8 +428,7 @@ static int ics932s401_detect(struct i2c_client *client, return 0; } -static int ics932s401_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ics932s401_probe(struct i2c_client *client) { struct ics932s401_data *data; int err; -- GitLab From db687ce71845aeb639be7452f4d8a272cf190cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:46 +0100 Subject: [PATCH 0825/1480] misc: isl29003: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-493-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/isl29003.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index 8ab61be79c762..aeda2fa89e61f 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -374,8 +374,7 @@ static int isl29003_init_client(struct i2c_client *client) * I2C layer */ -static int isl29003_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29003_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct isl29003_data *data; @@ -460,7 +459,7 @@ static struct i2c_driver isl29003_driver = { .name = ISL29003_DRV_NAME, .pm = ISL29003_PM_OPS, }, - .probe = isl29003_probe, + .probe_new = isl29003_probe, .remove = isl29003_remove, .id_table = isl29003_id, }; -- GitLab From 244179dbe11e707a0ef596246a9b80327492fc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:42 +0100 Subject: [PATCH 0826/1480] misc: eeprom/idt_89hpesx: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-489-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/idt_89hpesx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index bb3ed352b95f9..4e07ee9cb500e 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -1366,7 +1366,7 @@ static void idt_remove_dbgfs_files(struct idt_89hpesx_dev *pdev) /* * idt_probe() - IDT 89HPESx driver probe() callback method */ -static int idt_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int idt_probe(struct i2c_client *client) { struct idt_89hpesx_dev *pdev; int ret; @@ -1556,7 +1556,7 @@ static struct i2c_driver idt_driver = { .name = IDT_NAME, .of_match_table = idt_of_match, }, - .probe = idt_probe, + .probe_new = idt_probe, .remove = idt_remove, .id_table = idt_ids, }; -- GitLab From 6757c6480d7f34cb272d28339dfac096b94c8638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:38 +0100 Subject: [PATCH 0827/1480] misc: apds990x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-485-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds990x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index e2100cc42ce86..0024503ea6dbb 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1051,8 +1051,7 @@ static const struct attribute_group apds990x_attribute_group[] = { {.attrs = sysfs_attrs_ctrl }, }; -static int apds990x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds990x_probe(struct i2c_client *client) { struct apds990x_chip *chip; int err; @@ -1272,7 +1271,7 @@ static struct i2c_driver apds990x_driver = { .name = "apds990x", .pm = &apds990x_pm_ops, }, - .probe = apds990x_probe, + .probe_new = apds990x_probe, .remove = apds990x_remove, .id_table = apds990x_id, }; -- GitLab From 9f28b675c160519c79daed9f73bc38ab3d6c9015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:37 +0100 Subject: [PATCH 0828/1480] misc: apds9802als: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-484-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds9802als.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index a32431f4b370a..0526c55d5cd5c 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -212,8 +212,7 @@ static int als_set_default_config(struct i2c_client *client) return ret_val; } -static int apds9802als_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds9802als_probe(struct i2c_client *client) { int res; struct als_data *data; @@ -297,7 +296,7 @@ static struct i2c_driver apds9802als_driver = { .name = DRIVER_NAME, .pm = APDS9802ALS_PM_OPS, }, - .probe = apds9802als_probe, + .probe_new = apds9802als_probe, .remove = apds9802als_remove, .id_table = apds9802als_id, }; -- GitLab From 781edb0530a1009f89e7888726ca87b255d2526b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:39 +0100 Subject: [PATCH 0829/1480] misc: bh1770glc: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-486-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/bh1770glc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index d0dfa674414c3..bedbe0efb330e 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1162,8 +1162,7 @@ static const struct attribute_group bh1770_attribute_group = { .attrs = sysfs_attrs }; -static int bh1770_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bh1770_probe(struct i2c_client *client) { struct bh1770_chip *chip; int err; @@ -1379,7 +1378,7 @@ static struct i2c_driver bh1770_driver = { .name = "bh1770glc", .pm = &bh1770_pm_ops, }, - .probe = bh1770_probe, + .probe_new = bh1770_probe, .remove = bh1770_remove, .id_table = bh1770_id, }; -- GitLab From 3127a86a3702bd3a2ff43503d49919d666739ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:43:40 +0100 Subject: [PATCH 0830/1480] misc: ds1682: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-487-uwe@kleine-koenig.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ds1682.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index 0698ddc5f4d54..d517eed32971c 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -200,8 +200,7 @@ static const struct bin_attribute ds1682_eeprom_attr = { /* * Called when a ds1682 device is matched with this driver */ -static int ds1682_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ds1682_probe(struct i2c_client *client) { int rc; @@ -251,7 +250,7 @@ static struct i2c_driver ds1682_driver = { .name = "ds1682", .of_match_table = ds1682_of_match, }, - .probe = ds1682_probe, + .probe_new = ds1682_probe, .remove = ds1682_remove, .id_table = ds1682_id, }; -- GitLab From 7b51161696e803fd5f9ad55b20a64c2df313f95c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 17 Nov 2022 15:06:36 +0800 Subject: [PATCH 0831/1480] firmware: raspberrypi: fix possible memory leak in rpi_firmware_probe() In rpi_firmware_probe(), if mbox_request_channel() fails, the 'fw' will not be freed through rpi_firmware_delete(), fix this leak by calling kfree() in the error path. Fixes: 1e7c57355a3b ("firmware: raspberrypi: Keep count of all consumers") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221117070636.3849773-1-yangyingliang@huawei.com Acked-by: Joel Savitz Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/raspberrypi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 4b8978b254f9a..dba315f675bc7 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -272,6 +272,7 @@ static int rpi_firmware_probe(struct platform_device *pdev) int ret = PTR_ERR(fw->chan); if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to get mbox channel: %d\n", ret); + kfree(fw); return ret; } -- GitLab From ab760791c0cfbb1d7a668f46a135264f56c8f018 Mon Sep 17 00:00:00 2001 From: D Scott Phillips Date: Mon, 14 Nov 2022 13:22:12 -0800 Subject: [PATCH 0832/1480] char: misc: Increase the maximum number of dynamic misc devices to 1048448 On AmpereOne, 128 dynamic misc devices is not enough for the per-cpu coresight_tmc devices. Switch the dynamic minors allocator to an ida and add logic to allocate in the ranges [0..127] and [256..1048575], leaving [128..255] for static misc devices. Dynamic allocations start from 127 growing downwards and then increasing from 256, so device numbering for the first 128 devices remain the same as before. Signed-off-by: D Scott Phillips Link: https://lore.kernel.org/r/20221114212212.9279-1-scott@os.amperecomputing.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/misc.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index cba19bfdc44dd..05727f0daa6b5 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -61,7 +61,29 @@ static DEFINE_MUTEX(misc_mtx); * Assigned numbers, used for dynamic minors */ #define DYNAMIC_MINORS 128 /* like dynamic majors */ -static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS); +static DEFINE_IDA(misc_minors_ida); + +static int misc_minor_alloc(void) +{ + int ret; + + ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL); + if (ret >= 0) { + ret = DYNAMIC_MINORS - ret - 1; + } else { + ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1, + MINORMASK, GFP_KERNEL); + } + return ret; +} + +static void misc_minor_free(int minor) +{ + if (minor < DYNAMIC_MINORS) + ida_free(&misc_minors_ida, DYNAMIC_MINORS - minor - 1); + else if (minor > MISC_DYNAMIC_MINOR) + ida_free(&misc_minors_ida, minor); +} #ifdef CONFIG_PROC_FS static void *misc_seq_start(struct seq_file *seq, loff_t *pos) @@ -183,14 +205,13 @@ int misc_register(struct miscdevice *misc) mutex_lock(&misc_mtx); if (is_dynamic) { - int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); + int i = misc_minor_alloc(); - if (i >= DYNAMIC_MINORS) { + if (i < 0) { err = -EBUSY; goto out; } - misc->minor = DYNAMIC_MINORS - i - 1; - set_bit(i, misc_minors); + misc->minor = i; } else { struct miscdevice *c; @@ -209,10 +230,7 @@ int misc_register(struct miscdevice *misc) misc, misc->groups, "%s", misc->name); if (IS_ERR(misc->this_device)) { if (is_dynamic) { - int i = DYNAMIC_MINORS - misc->minor - 1; - - if (i < DYNAMIC_MINORS && i >= 0) - clear_bit(i, misc_minors); + misc_minor_free(misc->minor); misc->minor = MISC_DYNAMIC_MINOR; } err = PTR_ERR(misc->this_device); @@ -240,16 +258,13 @@ EXPORT_SYMBOL(misc_register); void misc_deregister(struct miscdevice *misc) { - int i = DYNAMIC_MINORS - misc->minor - 1; - if (WARN_ON(list_empty(&misc->list))) return; mutex_lock(&misc_mtx); list_del(&misc->list); device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); - if (i < DYNAMIC_MINORS && i >= 0) - clear_bit(i, misc_minors); + misc_minor_free(misc->minor); mutex_unlock(&misc_mtx); } EXPORT_SYMBOL(misc_deregister); -- GitLab From fa1ba41c17cd786925720bc1a9554d6c6624923d Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Tue, 15 Nov 2022 09:11:38 +0000 Subject: [PATCH 0833/1480] firmware: google: fix a NULL vs IS_ERR() check in cbmem_entry_probe() The devm_memremap() function returns error pointers on error, it doesn't return NULL. Fixes: 19d54020883c ("firmware: google: Implement cbmem in sysfs driver") Signed-off-by: Peng Wu Reviewed-by: Guenter Roeck Reviewed-by: Jack Rosenthal Link: https://lore.kernel.org/r/20221115091138.51614-1-wupeng58@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/google/cbmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/google/cbmem.c b/drivers/firmware/google/cbmem.c index 685f3070ce9d8..88e587ba1e0da 100644 --- a/drivers/firmware/google/cbmem.c +++ b/drivers/firmware/google/cbmem.c @@ -106,8 +106,8 @@ static int cbmem_entry_probe(struct coreboot_device *dev) entry->mem_file_buf = devm_memremap(&dev->dev, dev->cbmem_entry.address, dev->cbmem_entry.entry_size, MEMREMAP_WB); - if (!entry->mem_file_buf) - return -ENOMEM; + if (IS_ERR(entry->mem_file_buf)) + return PTR_ERR(entry->mem_file_buf); entry->size = dev->cbmem_entry.entry_size; -- GitLab From 61c80d1c3833e196256fb060382db94f24d3d9a7 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 11 Nov 2022 22:54:39 +0800 Subject: [PATCH 0834/1480] cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() If device_register() fails in cxl_register_afu|adapter(), the device is not added, device_unregister() can not be called in the error path, otherwise it will cause a null-ptr-deref because of removing not added device. As comment of device_register() says, it should use put_device() to give up the reference in the error path. So split device_unregister() into device_del() and put_device(), then goes to put dev when register fails. Fixes: 14baf4d9c739 ("cxl: Add guest-specific code") Signed-off-by: Yang Yingliang Acked-by: Andrew Donnellan Acked-by: Frederic Barrat Link: https://lore.kernel.org/r/20221111145440.2426970-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cxl/guest.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c index 375f692ae9d68..fb95a2d5cef48 100644 --- a/drivers/misc/cxl/guest.c +++ b/drivers/misc/cxl/guest.c @@ -965,10 +965,10 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n * if it returns an error! */ if ((rc = cxl_register_afu(afu))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_afu_add(afu))) - goto err_put1; + goto err_del_dev; /* * pHyp doesn't expose the programming models supported by the @@ -984,7 +984,7 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n afu->modes_supported = CXL_MODE_DIRECTED; if ((rc = cxl_afu_select_best_mode(afu))) - goto err_put2; + goto err_remove_sysfs; adapter->afu[afu->slice] = afu; @@ -1004,10 +1004,12 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n return 0; -err_put2: +err_remove_sysfs: cxl_sysfs_afu_remove(afu); -err_put1: - device_unregister(&afu->dev); +err_del_dev: + device_del(&afu->dev); +err_put_dev: + put_device(&afu->dev); free = false; guest_release_serr_irq(afu); err2: @@ -1141,18 +1143,20 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic * even if it returns an error! */ if ((rc = cxl_register_adapter(adapter))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_adapter_add(adapter))) - goto err_put1; + goto err_del_dev; /* release the context lock as the adapter is configured */ cxl_adapter_context_unlock(adapter); return adapter; -err_put1: - device_unregister(&adapter->dev); +err_del_dev: + device_del(&adapter->dev); +err_put_dev: + put_device(&adapter->dev); free = false; cxl_guest_remove_chardev(adapter); err1: -- GitLab From 02cd3032b154fa02fdf90e7467abaeed889330b2 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 11 Nov 2022 22:54:40 +0800 Subject: [PATCH 0835/1480] cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() If device_register() fails in cxl_pci_afu|adapter(), the device is not added, device_unregister() can not be called in the error path, otherwise it will cause a null-ptr-deref because of removing not added device. As comment of device_register() says, it should use put_device() to give up the reference in the error path. So split device_unregister() into device_del() and put_device(), then goes to put dev when register fails. Fixes: f204e0b8cedd ("cxl: Driver code for powernv PCIe based cards for userspace access") Signed-off-by: Yang Yingliang Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Link: https://lore.kernel.org/r/20221111145440.2426970-2-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cxl/pci.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 3de0aea62ade4..6d495d641c951 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -1164,10 +1164,10 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) * if it returns an error! */ if ((rc = cxl_register_afu(afu))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_afu_add(afu))) - goto err_put1; + goto err_del_dev; adapter->afu[afu->slice] = afu; @@ -1176,10 +1176,12 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) return 0; -err_put1: +err_del_dev: + device_del(&afu->dev); +err_put_dev: pci_deconfigure_afu(afu); cxl_debugfs_afu_remove(afu); - device_unregister(&afu->dev); + put_device(&afu->dev); return rc; err_free_native: @@ -1667,23 +1669,25 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev) * even if it returns an error! */ if ((rc = cxl_register_adapter(adapter))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_adapter_add(adapter))) - goto err_put1; + goto err_del_dev; /* Release the context lock as adapter is configured */ cxl_adapter_context_unlock(adapter); return adapter; -err_put1: +err_del_dev: + device_del(&adapter->dev); +err_put_dev: /* This should mirror cxl_remove_adapter, except without the * sysfs parts */ cxl_debugfs_adapter_remove(adapter); cxl_deconfigure_adapter(adapter); - device_unregister(&adapter->dev); + put_device(&adapter->dev); return ERR_PTR(rc); err_release: -- GitLab From 2613cc29c5723881ca603b1a3b50f0107010d5d6 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 16 Nov 2022 10:49:58 +0100 Subject: [PATCH 0836/1480] cacheinfo: Remove of_node_put() for fw_token fw_token is used for DT/ACPI systems to identify CPUs sharing caches. For DT based systems, fw_token is set to a pointer to a DT node. commit 3da72e18371c ("cacheinfo: Decrement refcount in cache_setup_of_node()") doesn't increment the refcount of fw_token anymore in cache_setup_of_node(). fw_token is indeed used as a token and not as a (struct device_node*), so no reference to fw_token should be kept. However, [1] is triggered when hotplugging a CPU multiple times since cache_shared_cpu_map_remove() decrements the refcount to fw_token at each CPU unplugging, eventually reaching 0. Remove of_node_put() for fw_token in cache_shared_cpu_map_remove(). [1] ------------[ cut here ]------------ refcount_t: saturated; leaking memory. WARNING: CPU: 4 PID: 32 at lib/refcount.c:22 refcount_warn_saturate (lib/refcount.c:22 (discriminator 3)) Modules linked in: CPU: 4 PID: 32 Comm: cpuhp/4 Tainted: G W 6.1.0-rc1-14091-g9fdf2ca7b9c8 #76 Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Oct 31 2022 pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : refcount_warn_saturate (lib/refcount.c:22 (discriminator 3)) lr : refcount_warn_saturate (lib/refcount.c:22 (discriminator 3)) [...] Call trace: [...] of_node_release (drivers/of/dynamic.c:335) kobject_put (lib/kobject.c:677 lib/kobject.c:704 ./include/linux/kref.h:65 lib/kobject.c:721) of_node_put (drivers/of/dynamic.c:49) free_cache_attributes.part.0 (drivers/base/cacheinfo.c:712) cacheinfo_cpu_pre_down (drivers/base/cacheinfo.c:718) cpuhp_invoke_callback (kernel/cpu.c:247 (discriminator 4)) cpuhp_thread_fun (kernel/cpu.c:785) smpboot_thread_fn (kernel/smpboot.c:164 (discriminator 3)) kthread (kernel/kthread.c:376) ret_from_fork (arch/arm64/kernel/entry.S:861) ---[ end trace 0000000000000000 ]--- Fixes: 3da72e18371c ("cacheinfo: Decrement refcount in cache_setup_of_node()") Reported-by: Geert Uytterhoeven Reported-by: Marek Szyprowski Tested-by: Geert Uytterhoeven Tested-by: Sudeep Holla Reviewed-by: Sudeep Holla Signed-off-by: Pierre Gondois Link: https://lore.kernel.org/r/20221116094958.2141072-1-pierre.gondois@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 04317cde800cb..950b22cdb5f7c 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -317,8 +317,6 @@ static void cache_shared_cpu_map_remove(unsigned int cpu) cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); } - if (of_have_populated_dt()) - of_node_put(this_leaf->fw_token); } } -- GitLab From 20228a1d5a55e7db0c6720840f2c7d2b48c55f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 20 Sep 2022 13:28:07 +0200 Subject: [PATCH 0837/1480] iio: adc: ad_sigma_delta: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop 'mlock' usage by making use of iio_device_claim_direct_mode(). This change actually makes sure we cannot do a single conversion while buffering is enable. Note there was a potential race in the previous code since we were only acquiring the lock after checking if the bus is enabled. Fixes: af3008485ea0 ("iio:adc: Add common code for ADI Sigma Delta devices") Signed-off-by: Nuno Sá Reviewed-by: Miquel Raynal Cc: #No rush as race is very old. Link: https://lore.kernel.org/r/20220920112821.975359-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad_sigma_delta.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 261a9a6b45e15..d8570f620785a 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -281,10 +281,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, unsigned int data_reg; int ret = 0; - if (iio_buffer_enabled(indio_dev)) - return -EBUSY; + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; - mutex_lock(&indio_dev->mlock); ad_sigma_delta_set_channel(sigma_delta, chan->address); spi_bus_lock(sigma_delta->spi->master); @@ -323,7 +323,7 @@ out: ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); sigma_delta->bus_locked = false; spi_bus_unlock(sigma_delta->spi->master); - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); if (ret) return ret; -- GitLab From 2a22b40aea42dd516e669257ab5faf10396c2fad Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Wed, 21 Sep 2022 02:39:15 +0000 Subject: [PATCH 0838/1480] iio: accel: bma400: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replace with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. Signed-off-by: Yuan Can Link: https://lore.kernel.org/r/20220921023915.47300-1-yuancan@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma400_core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index ad8fce3e08cd0..e8de88e6cfb97 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -886,14 +886,10 @@ static int bma400_init(struct bma400_data *data) ret = devm_regulator_bulk_get(data->dev, ARRAY_SIZE(data->regulators), data->regulators); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(data->dev, - "Failed to get regulators: %d\n", - ret); + if (ret) + return dev_err_probe(data->dev, ret, "Failed to get regulators: %d\n", + ret); - return ret; - } ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), data->regulators); if (ret) { -- GitLab From 2aebc223fc7ce613140ef2b64ca3c0f1a4f458cb Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:22 +0200 Subject: [PATCH 0839/1480] iio: temperature: mlx90632 Add runtime powermanagement modes The sensor can operate in lower power modes and even make measurements when in those lower powered modes. The decision was taken that if measurement is not requested within 2 seconds the sensor will remain in SLEEP_STEP power mode, where measurements are triggered on request with setting the start of measurement bit (SOB). In this mode the measurements are taking a bit longer because we need to start it and complete it. Currently, in continuous mode we read ready data and this mode is activated if sensor measurement is requested within 2 seconds. The suspend timeout is increased to 6 seconds (instead of 3 before), because that enables more measurements in lower power mode (SLEEP_STEP), with the lowest refresh rate (2 seconds). Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/be405068f081f2d518843897b13cd0289c280b5d.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 377 +++++++++++++++++++++++------ 1 file changed, 309 insertions(+), 68 deletions(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index f6dec0e5f0973..71130d237a691 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -6,11 +6,14 @@ * * Driver for the Melexis MLX90632 I2C 16-bit IR thermopile sensor */ +#include #include +#include #include #include #include #include +#include #include #include #include @@ -55,6 +58,12 @@ #define MLX90632_EE_Ha 0x2481 /* Ha customer calib value reg 16bit */ #define MLX90632_EE_Hb 0x2482 /* Hb customer calib value reg 16bit */ +#define MLX90632_EE_MEDICAL_MEAS1 0x24E1 /* Medical measurement 1 16bit */ +#define MLX90632_EE_MEDICAL_MEAS2 0x24E2 /* Medical measurement 2 16bit */ +#define MLX90632_EE_EXTENDED_MEAS1 0x24F1 /* Extended measurement 1 16bit */ +#define MLX90632_EE_EXTENDED_MEAS2 0x24F2 /* Extended measurement 2 16bit */ +#define MLX90632_EE_EXTENDED_MEAS3 0x24F3 /* Extended measurement 3 16bit */ + /* Register addresses - volatile */ #define MLX90632_REG_I2C_ADDR 0x3000 /* Chip I2C address register */ @@ -62,13 +71,16 @@ #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ #define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */ +#define MLX90632_CFG_SOB_MASK BIT(11) /* PowerModes statuses */ #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ -#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step*/ +#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step */ #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ -#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ +#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous */ + +#define MLX90632_EE_RR GENMASK(10, 8) /* Only Refresh Rate bits */ /* Measurement types */ #define MLX90632_MTYP_MEDICAL 0 @@ -116,8 +128,9 @@ #define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */ #define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */ #define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */ -#define MLX90632_SLEEP_DELAY_MS 3000 /* Autosleep delay */ +#define MLX90632_SLEEP_DELAY_MS 6000 /* Autosleep delay */ #define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */ +#define MLX90632_MEAS_MAX_TIME 2000 /* Max measurement time in ms for the lowest refresh rate */ /** * struct mlx90632_data - private data for the MLX90632 device @@ -130,6 +143,9 @@ * @object_ambient_temperature: Ambient temperature at object (might differ of * the ambient temperature of sensor. * @regulator: Regulator of the device + * @powerstatus: Current POWER status of the device + * @interaction_ts: Timestamp of the last temperature read that is used + * for power management in jiffies */ struct mlx90632_data { struct i2c_client *client; @@ -139,6 +155,8 @@ struct mlx90632_data { u8 mtyp; u32 object_ambient_temperature; struct regulator *regulator; + int powerstatus; + unsigned long interaction_ts; }; static const struct regmap_range mlx90632_volatile_reg_range[] = { @@ -158,6 +176,8 @@ static const struct regmap_range mlx90632_read_reg_range[] = { regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka), regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), + regmap_reg_range(MLX90632_EE_MEDICAL_MEAS1, MLX90632_EE_MEDICAL_MEAS2), + regmap_reg_range(MLX90632_EE_EXTENDED_MEAS1, MLX90632_EE_EXTENDED_MEAS3), regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), @@ -198,16 +218,38 @@ static const struct regmap_config mlx90632_regmap = { static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) { - return regmap_update_bits(regmap, MLX90632_REG_CONTROL, - MLX90632_CFG_PWR_MASK, - MLX90632_PWR_STATUS_SLEEP_STEP); + struct mlx90632_data *data = + iio_priv(dev_get_drvdata(regmap_get_device(regmap))); + s32 ret; + + if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) + return 0; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK, + MLX90632_PWR_STATUS_SLEEP_STEP); + if (ret < 0) + return ret; + + data->powerstatus = MLX90632_PWR_STATUS_SLEEP_STEP; + return ret; } static s32 mlx90632_pwr_continuous(struct regmap *regmap) { - return regmap_update_bits(regmap, MLX90632_REG_CONTROL, - MLX90632_CFG_PWR_MASK, - MLX90632_PWR_STATUS_CONTINUOUS); + struct mlx90632_data *data = + iio_priv(dev_get_drvdata(regmap_get_device(regmap))); + s32 ret; + + if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) + return 0; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK, + MLX90632_PWR_STATUS_CONTINUOUS); + if (ret < 0) + return ret; + + data->powerstatus = MLX90632_PWR_STATUS_CONTINUOUS; + return ret; } /** @@ -219,6 +261,63 @@ static void mlx90632_reset_delay(void) usleep_range(150, 200); } +static int mlx90632_get_measurement_time(struct regmap *regmap, u16 meas) +{ + unsigned int reg; + int ret; + + ret = regmap_read(regmap, meas, ®); + if (ret < 0) + return ret; + + return MLX90632_MEAS_MAX_TIME >> FIELD_GET(MLX90632_EE_RR, reg); +} + +static int mlx90632_calculate_dataset_ready_time(struct mlx90632_data *data) +{ + unsigned int refresh_time; + int ret; + + if (data->mtyp == MLX90632_MTYP_MEDICAL) { + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_MEDICAL_MEAS1); + if (ret < 0) + return ret; + + refresh_time = ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_MEDICAL_MEAS2); + if (ret < 0) + return ret; + + refresh_time += ret; + } else { + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS1); + if (ret < 0) + return ret; + + refresh_time = ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS2); + if (ret < 0) + return ret; + + refresh_time += ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS3); + if (ret < 0) + return ret; + + refresh_time += ret; + } + + return refresh_time; +} + /** * mlx90632_perform_measurement() - Trigger and retrieve current measurement cycle * @data: pointer to mlx90632_data object containing regmap information @@ -249,26 +348,75 @@ static int mlx90632_perform_measurement(struct mlx90632_data *data) return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; } -static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) +/** + * mlx90632_perform_measurement_burst() - Trigger and retrieve current measurement + * cycle in step sleep mode + * @data: pointer to mlx90632_data object containing regmap information + * + * Perform a measurement and return 2 as measurement cycle position reported + * by sensor. This is a blocking function for amount dependent on the sensor + * refresh rate. + */ +static int mlx90632_perform_measurement_burst(struct mlx90632_data *data) { + unsigned int reg_status; int ret; - if ((type != MLX90632_MTYP_MEDICAL) && (type != MLX90632_MTYP_EXTENDED)) - return -EINVAL; + ret = regmap_write_bits(data->regmap, MLX90632_REG_CONTROL, + MLX90632_CFG_SOB_MASK, MLX90632_CFG_SOB_MASK); + if (ret < 0) + return ret; + + ret = mlx90632_calculate_dataset_ready_time(data); + if (ret < 0) + return ret; - ret = regmap_write(regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); + msleep(ret); /* Wait minimum time for dataset to be ready */ + + ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, + reg_status, + (reg_status & MLX90632_STAT_BUSY) == 0, + 10000, 100 * 10000); + if (ret < 0) { + dev_err(&data->client->dev, "data not ready"); + return -ETIMEDOUT; + } + + return 2; +} + +static int mlx90632_set_meas_type(struct mlx90632_data *data, u8 type) +{ + int current_powerstatus; + int ret; + + if (data->mtyp == type) + return 0; + + current_powerstatus = data->powerstatus; + ret = mlx90632_pwr_continuous(data->regmap); + if (ret < 0) + return ret; + + ret = regmap_write(data->regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); if (ret < 0) return ret; mlx90632_reset_delay(); - ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, + ret = regmap_update_bits(data->regmap, MLX90632_REG_CONTROL, (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); if (ret < 0) return ret; - return mlx90632_pwr_continuous(regmap); + data->mtyp = type; + data->powerstatus = MLX90632_PWR_STATUS_HALT; + + if (current_powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) + return mlx90632_pwr_set_sleep_step(data->regmap); + + return mlx90632_pwr_continuous(data->regmap); } static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, @@ -355,11 +503,30 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, s32 ret, measurement; mutex_lock(&data->lock); - measurement = mlx90632_perform_measurement(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_set_meas_type(data, MLX90632_MTYP_MEDICAL); + if (ret < 0) + goto read_unlock; + + switch (data->powerstatus) { + case MLX90632_PWR_STATUS_CONTINUOUS: + measurement = mlx90632_perform_measurement(data); + if (measurement < 0) { + ret = measurement; + goto read_unlock; + } + break; + case MLX90632_PWR_STATUS_SLEEP_STEP: + measurement = mlx90632_perform_measurement_burst(data); + if (measurement < 0) { + ret = measurement; + goto read_unlock; + } + break; + default: + ret = -EOPNOTSUPP; goto read_unlock; } + ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw, ambient_old_raw); if (ret < 0) @@ -441,14 +608,20 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o s32 ret, meas; mutex_lock(&data->lock); - ret = mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_EXTENDED); + ret = mlx90632_set_meas_type(data, MLX90632_MTYP_EXTENDED); if (ret < 0) goto read_unlock; - ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, - 50000, 800000, false, data); - if (ret != 0) - goto read_unlock; + if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) { + ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, + 50000, 800000, false, data); + if (ret) + goto read_unlock; + } else if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + ret = mlx90632_perform_measurement_burst(data); + if (ret < 0) + goto read_unlock; + } ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); if (ret < 0) @@ -457,8 +630,6 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw); read_unlock: - (void) mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_MEDICAL); - mutex_unlock(&data->lock); return ret; } @@ -743,12 +914,47 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) return ret; } +/** + * mlx90632_pm_interraction_wakeup() - Measure time between user interactions to change powermode + * @data: pointer to mlx90632_data object containing interaction_ts information + * + * Switch to continuous mode when interaction is faster than MLX90632_MEAS_MAX_TIME. Update the + * interaction_ts for each function call with the jiffies to enable measurement between function + * calls. Initial value of the interaction_ts needs to be set before this function call. + */ +static int mlx90632_pm_interraction_wakeup(struct mlx90632_data *data) +{ + unsigned long now; + int ret; + + now = jiffies; + if (time_in_range(now, data->interaction_ts, + data->interaction_ts + + msecs_to_jiffies(MLX90632_MEAS_MAX_TIME + 100))) { + if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + ret = mlx90632_pwr_continuous(data->regmap); + if (ret < 0) + return ret; + } + } + + data->interaction_ts = now; + + return 0; +} + static int mlx90632_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *channel, int *val, int *val2, long mask) { struct mlx90632_data *data = iio_priv(indio_dev); int ret; + int cr; + + pm_runtime_get_sync(&data->client->dev); + ret = mlx90632_pm_interraction_wakeup(data); + if (ret < 0) + goto mlx90632_read_raw_pm; switch (mask) { case IIO_CHAN_INFO_PROCESSED: @@ -756,16 +962,22 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, case IIO_MOD_TEMP_AMBIENT: ret = mlx90632_calc_ambient_dsp105(data, val); if (ret < 0) - return ret; - return IIO_VAL_INT; + goto mlx90632_read_raw_pm; + + ret = IIO_VAL_INT; + break; case IIO_MOD_TEMP_OBJECT: ret = mlx90632_calc_object_dsp105(data, val); if (ret < 0) - return ret; - return IIO_VAL_INT; + goto mlx90632_read_raw_pm; + + ret = IIO_VAL_INT; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + break; case IIO_CHAN_INFO_CALIBEMISSIVITY: if (data->emissivity == 1000) { *val = 1; @@ -774,13 +986,21 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val = 0; *val2 = data->emissivity * 1000; } - return IIO_VAL_INT_PLUS_MICRO; + ret = IIO_VAL_INT_PLUS_MICRO; + break; case IIO_CHAN_INFO_CALIBAMBIENT: *val = data->object_ambient_temperature; - return IIO_VAL_INT; + ret = IIO_VAL_INT; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + +mlx90632_read_raw_pm: + pm_runtime_mark_last_busy(&data->client->dev); + pm_runtime_put_autosuspend(&data->client->dev); + return ret; } static int mlx90632_write_raw(struct iio_dev *indio_dev, @@ -826,11 +1046,18 @@ static const struct iio_info mlx90632_info = { .write_raw = mlx90632_write_raw, }; -static int mlx90632_sleep(struct mlx90632_data *data) +static void mlx90632_sleep(void *_data) +{ + struct mlx90632_data *data = _data; + + mlx90632_pwr_set_sleep_step(data->regmap); +} + +static int mlx90632_suspend(struct mlx90632_data *data) { regcache_mark_dirty(data->regmap); - dev_dbg(&data->client->dev, "Requesting sleep"); + dev_dbg(&data->client->dev, "Requesting suspend"); return mlx90632_pwr_set_sleep_step(data->regmap); } @@ -902,6 +1129,7 @@ static int mlx90632_probe(struct i2c_client *client, mlx90632->client = client; mlx90632->regmap = regmap; mlx90632->mtyp = MLX90632_MTYP_MEDICAL; + mlx90632->powerstatus = MLX90632_PWR_STATUS_HALT; mutex_init(&mlx90632->lock); indio_dev->name = id->name; @@ -933,6 +1161,13 @@ static int mlx90632_probe(struct i2c_client *client, return ret; } + ret = devm_add_action_or_reset(&client->dev, mlx90632_sleep, mlx90632); + if (ret < 0) { + dev_err(&client->dev, "Failed to setup low power cleanup action %d\n", + ret); + return ret; + } + ret = regmap_read(mlx90632->regmap, MLX90632_EE_VERSION, &read); if (ret < 0) { dev_err(&client->dev, "read of version failed: %d\n", ret); @@ -961,32 +1196,17 @@ static int mlx90632_probe(struct i2c_client *client, mlx90632->emissivity = 1000; mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */ + mlx90632->interaction_ts = jiffies; /* Set initial value */ - pm_runtime_disable(&client->dev); - ret = pm_runtime_set_active(&client->dev); - if (ret < 0) { - mlx90632_sleep(mlx90632); - return ret; - } - pm_runtime_enable(&client->dev); + pm_runtime_get_noresume(&client->dev); + pm_runtime_set_active(&client->dev); + + devm_pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); + pm_runtime_put_autosuspend(&client->dev); - return iio_device_register(indio_dev); -} - -static void mlx90632_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct mlx90632_data *data = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - pm_runtime_disable(&client->dev); - pm_runtime_set_suspended(&client->dev); - pm_runtime_put_noidle(&client->dev); - - mlx90632_sleep(data); + return devm_iio_device_register(&client->dev, indio_dev); } static const struct i2c_device_id mlx90632_id[] = { @@ -1001,33 +1221,54 @@ static const struct of_device_id mlx90632_of_match[] = { }; MODULE_DEVICE_TABLE(of, mlx90632_of_match); -static int __maybe_unused mlx90632_pm_suspend(struct device *dev) +static int mlx90632_pm_suspend(struct device *dev) { - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct mlx90632_data *data = iio_priv(indio_dev); + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = mlx90632_suspend(data); + if (ret < 0) + return ret; - return mlx90632_sleep(data); + ret = regulator_disable(data->regulator); + if (ret < 0) + dev_err(regmap_get_device(data->regmap), + "Failed to disable power regulator: %d\n", ret); + + return ret; } -static int __maybe_unused mlx90632_pm_resume(struct device *dev) +static int mlx90632_pm_resume(struct device *dev) { - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct mlx90632_data *data = iio_priv(indio_dev); + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = mlx90632_enable_regulator(data); + if (ret < 0) + return ret; return mlx90632_wakeup(data); } -static UNIVERSAL_DEV_PM_OPS(mlx90632_pm_ops, mlx90632_pm_suspend, - mlx90632_pm_resume, NULL); +static int mlx90632_pm_runtime_suspend(struct device *dev) +{ + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + + return mlx90632_pwr_set_sleep_step(data->regmap); +} + +const struct dev_pm_ops mlx90632_pm_ops = { + SYSTEM_SLEEP_PM_OPS(mlx90632_pm_suspend, mlx90632_pm_resume) + RUNTIME_PM_OPS(mlx90632_pm_runtime_suspend, NULL, NULL) +}; static struct i2c_driver mlx90632_driver = { .driver = { .name = "mlx90632", .of_match_table = mlx90632_of_match, - .pm = &mlx90632_pm_ops, + .pm = pm_ptr(&mlx90632_pm_ops), }, .probe = mlx90632_probe, - .remove = mlx90632_remove, .id_table = mlx90632_id, }; module_i2c_driver(mlx90632_driver); -- GitLab From eff07b20700a55e5b39e76960934d6eeb56a12d9 Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:23 +0200 Subject: [PATCH 0840/1480] iio: temperature: mlx90632 Read sampling frequency Allow users to read sensor sampling frequency to better plan the application measurement requests. Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/0bd6d6d665b4bd39e4565f6f44cb1bdc03386e23.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 71130d237a691..0818039402616 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -81,6 +81,9 @@ #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous */ #define MLX90632_EE_RR GENMASK(10, 8) /* Only Refresh Rate bits */ +#define MLX90632_REFRESH_RATE(ee_val) FIELD_GET(MLX90632_EE_RR, ee_val) + /* Extract Refresh Rate from ee register */ +#define MLX90632_REFRESH_RATE_STATUS(refresh_rate) (refresh_rate << 8) /* Measurement types */ #define MLX90632_MTYP_MEDICAL 0 @@ -914,6 +917,32 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) return ret; } +static int mlx90632_get_refresh_rate(struct mlx90632_data *data, + int *refresh_rate) +{ + unsigned int meas1; + int ret; + + ret = regmap_read(data->regmap, MLX90632_EE_MEDICAL_MEAS1, &meas1); + if (ret < 0) + return ret; + + *refresh_rate = MLX90632_REFRESH_RATE(meas1); + + return ret; +} + +static const int mlx90632_freqs[][2] = { + {0, 500000}, + {1, 0}, + {2, 0}, + {4, 0}, + {8, 0}, + {16, 0}, + {32, 0}, + {64, 0} +}; + /** * mlx90632_pm_interraction_wakeup() - Measure time between user interactions to change powermode * @data: pointer to mlx90632_data object containing interaction_ts information @@ -992,6 +1021,15 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val = data->object_ambient_temperature; ret = IIO_VAL_INT; break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = mlx90632_get_refresh_rate(data, &cr); + if (ret < 0) + goto mlx90632_read_raw_pm; + + *val = mlx90632_freqs[cr][0]; + *val2 = mlx90632_freqs[cr][1]; + ret = IIO_VAL_INT_PLUS_MICRO; + break; default: ret = -EINVAL; break; @@ -1025,12 +1063,30 @@ static int mlx90632_write_raw(struct iio_dev *indio_dev, } } +static int mlx90632_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (int *)mlx90632_freqs; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = 2 * ARRAY_SIZE(mlx90632_freqs); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static const struct iio_chan_spec mlx90632_channels[] = { { .type = IIO_TEMP, .modified = 1, .channel2 = IIO_MOD_TEMP_AMBIENT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, @@ -1038,12 +1094,15 @@ static const struct iio_chan_spec mlx90632_channels[] = { .channel2 = IIO_MOD_TEMP_OBJECT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, }; static const struct iio_info mlx90632_info = { .read_raw = mlx90632_read_raw, .write_raw = mlx90632_write_raw, + .read_avail = mlx90632_read_avail, }; static void mlx90632_sleep(void *_data) -- GitLab From 4e6151403631255828a5530d9d6233caedcd2976 Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:24 +0200 Subject: [PATCH 0841/1480] iio: temperature: mlx90632 Change return value of sensor measurement channel The current EINVAL value is more applicable to embedded library, where user can actually put the fixed value to the sensor. In case of the driver if the value of the channel is invalid it is better in inform userspace that Channel was out of range as that implies more to internal driver error than invalid input. It also makes for easier debugging of where the error comes from during the development. Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/565d4df2592d751dc0f40908f2569b7c9af8e56e.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 0818039402616..224db7513baa7 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -435,7 +435,7 @@ static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, *channel_old = 1; break; default: - return -EINVAL; + return -ECHRNG; } return 0; -- GitLab From 8cf5f0329128efdfe18f12a8697752d39821fbdf Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Thu, 22 Sep 2022 21:46:39 +0200 Subject: [PATCH 0842/1480] iio: adc: mcp3911: add support to set PGA Add support for setting the Programmable Gain Amplifiers by adjust the scale value. Signed-off-by: Marcus Folkesson Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220922194639.1118971-1-marcus.folkesson@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3911.c | 104 +++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c index 76b334f5ac616..974c5bd923a68 100644 --- a/drivers/iio/adc/mcp3911.c +++ b/drivers/iio/adc/mcp3911.c @@ -29,6 +29,8 @@ #define MCP3911_REG_MOD 0x06 #define MCP3911_REG_PHASE 0x07 #define MCP3911_REG_GAIN 0x09 +#define MCP3911_GAIN_MASK(ch) (GENMASK(2, 0) << 3 * ch) +#define MCP3911_GAIN_VAL(ch, val) ((val << 3 * ch) & MCP3911_GAIN_MASK(ch)) #define MCP3911_REG_STATUSCOM 0x0a #define MCP3911_STATUSCOM_DRHIZ BIT(12) @@ -60,8 +62,10 @@ #define MCP3911_REG_MASK GENMASK(4, 1) #define MCP3911_NUM_CHANNELS 2 +#define MCP3911_NUM_SCALES 6 static const int mcp3911_osr_table[] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 }; +static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2]; struct mcp3911 { struct spi_device *spi; @@ -70,6 +74,7 @@ struct mcp3911 { struct clk *clki; u32 dev_addr; struct iio_trigger *trig; + u32 gain[MCP3911_NUM_CHANNELS]; struct { u32 channels[MCP3911_NUM_CHANNELS]; s64 ts __aligned(8); @@ -146,6 +151,11 @@ static int mcp3911_read_avail(struct iio_dev *indio_dev, *vals = mcp3911_osr_table; *length = ARRAY_SIZE(mcp3911_osr_table); return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_INT_PLUS_NANO; + *vals = (int *)mcp3911_scale_table; + *length = ARRAY_SIZE(mcp3911_scale_table) * 2; + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -190,29 +200,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_SCALE: - if (adc->vref) { - ret = regulator_get_voltage(adc->vref); - if (ret < 0) { - dev_err(indio_dev->dev.parent, - "failed to get vref voltage: %d\n", - ret); - goto out; - } - - *val = ret / 1000; - } else { - *val = MCP3911_INT_VREF_MV; - } - - /* - * For 24bit Conversion - * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 - * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) - */ - - /* val2 = (2^23 * 1.5) */ - *val2 = 12582912; - ret = IIO_VAL_FRACTIONAL; + *val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0]; + *val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1]; + ret = IIO_VAL_INT_PLUS_NANO; break; } @@ -230,6 +220,18 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev, mutex_lock(&adc->lock); switch (mask) { + case IIO_CHAN_INFO_SCALE: + for (int i = 0; i < MCP3911_NUM_SCALES; i++) { + if (val == mcp3911_scale_table[i][0] && + val2 == mcp3911_scale_table[i][1]) { + + adc->gain[channel->channel] = BIT(i); + ret = mcp3911_update(adc, MCP3911_REG_GAIN, + MCP3911_GAIN_MASK(channel->channel), + MCP3911_GAIN_VAL(channel->channel, i), 1); + } + } + break; case IIO_CHAN_INFO_OFFSET: if (val2 != 0) { ret = -EINVAL; @@ -265,6 +267,44 @@ out: return ret; } +static int mcp3911_calc_scale_table(struct mcp3911 *adc) +{ + u32 ref = MCP3911_INT_VREF_MV; + u32 div; + int ret; + u64 tmp; + + if (adc->vref) { + ret = regulator_get_voltage(adc->vref); + if (ret < 0) { + dev_err(&adc->spi->dev, + "failed to get vref voltage: %d\n", + ret); + return ret; + } + + ref = ret / 1000; + } + + /* + * For 24-bit Conversion + * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 + * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) + * + * ref = Reference voltage + * div = (2^23 * 1.5 * gain) = 12582912 * gain + */ + for (int i = 0; i < MCP3911_NUM_SCALES; i++) { + div = 12582912 * BIT(i); + tmp = div_s64((s64)ref * 1000000000LL, div); + + mcp3911_scale_table[i][0] = 0; + mcp3911_scale_table[i][1] = tmp; + } + + return 0; +} + #define MCP3911_CHAN(idx) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -274,8 +314,10 @@ out: .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_OFFSET) | \ BIT(IIO_CHAN_INFO_SCALE), \ - .info_mask_shared_by_type_available = \ + .info_mask_shared_by_type_available = \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = { \ .sign = 's', \ .realbits = 24, \ @@ -482,6 +524,20 @@ static int mcp3911_probe(struct spi_device *spi) if (ret) return ret; + ret = mcp3911_calc_scale_table(adc); + if (ret) + return ret; + + /* Set gain to 1 for all channels */ + for (int i = 0; i < MCP3911_NUM_CHANNELS; i++) { + adc->gain[i] = 1; + ret = mcp3911_update(adc, MCP3911_REG_GAIN, + MCP3911_GAIN_MASK(i), + MCP3911_GAIN_VAL(i, 0), 1); + if (ret) + return ret; + } + indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp3911_info; -- GitLab From 3f4033a811bcd1a1f077ce5297488a5c4dd30eb1 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 22 Sep 2022 11:58:48 +0000 Subject: [PATCH 0843/1480] iio: filter: admv8818: close potential out-of-bounds read in __admv8818_read_[h|l]pf_freq() ADMV8818_SW_IN_WR0_MSK and ADMV8818_SW_OUT_WR0_MSK have 3 bits, which means a length of 8, but freq_range_hpf and freq_range_lpf array size is 4, may end up reading 4 elements beyond the end of those arrays. Check value first before access freq_range_hpf and freq_range_lpf to harden against the hardware allowing out of range values. Signed-off-by: Wei Yongjun Reviewed-by: Antoniu Miclaus Link: https://lore.kernel.org/r/20220922115848.1800021-1-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/filter/admv8818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index 68de45fe21b44..fe8d46cb7f1d1 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -265,7 +265,7 @@ static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq) return ret; hpf_band = FIELD_GET(ADMV8818_SW_IN_WR0_MSK, data); - if (!hpf_band) { + if (!hpf_band || hpf_band > 4) { *hpf_freq = 0; return ret; } @@ -303,7 +303,7 @@ static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) return ret; lpf_band = FIELD_GET(ADMV8818_SW_OUT_WR0_MSK, data); - if (!lpf_band) { + if (!lpf_band || lpf_band > 4) { *lpf_freq = 0; return ret; } -- GitLab From e21b5b1f26694a4498ca11a15e09ccc0a72abb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= Date: Mon, 26 Sep 2022 11:18:59 +0200 Subject: [PATCH 0844/1480] iio: light: vcnl4000: Preserve conf bits when toggle power MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the vcnl4040 and vcnl4200 chip uses runtime power management for turning the ambient light and proximity sensors on/off, it overwrites the entire register each time. In ALS_CONF register bit fields ALS_IT, ALS_PERS, ALS_INT_EN are overwritten. In PS_CONF1 register bit fields PS_DUTY, PS_PERS, PS_IT, PS_HD, and PS_INT are overwritten. Add functions for preserving the affected bit fields when changing power state. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20220926091900.1724105-2-marten.lindahl@axis.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 54 ++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index f6c83ecaad8b5..bc8c974cd8b85 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -74,6 +74,9 @@ #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */ #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */ +#define VCNL4040_ALS_CONF_ALS_SHUTDOWN BIT(0) +#define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) + /* Bit masks for interrupt registers. */ #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */ @@ -188,16 +191,61 @@ static int vcnl4000_init(struct vcnl4000_data *data) return data->chip_spec->set_power_state(data, true); }; +static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en) +{ + int ret; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); + if (ret < 0) + goto out; + + if (en) + ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN; + else + ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN; + + ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret); + +out: + mutex_unlock(&data->vcnl4000_lock); + + return ret; +} + +static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en) +{ + int ret; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + goto out; + + if (en) + ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN; + else + ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN; + + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret); + +out: + mutex_unlock(&data->vcnl4000_lock); + + return ret; +} + static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on) { - u16 val = on ? 0 /* power on */ : 1 /* shut down */; int ret; - ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val); + ret = vcnl4000_write_als_enable(data, on); if (ret < 0) return ret; - ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val); + ret = vcnl4000_write_ps_enable(data, on); if (ret < 0) return ret; -- GitLab From 85e2c6a23f851f65b2b14c1d87685168be620f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= Date: Mon, 26 Sep 2022 11:19:00 +0200 Subject: [PATCH 0845/1480] iio: light: vcnl4000: Add ps_it attributes for vcnl4040 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add read/write attribute for proximity integration time, and read attribute for available proximity integration times for the vcnl4040 chip. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20220926091900.1724105-3-marten.lindahl@axis.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 131 ++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index bc8c974cd8b85..fdb3922ae4acd 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -17,6 +17,7 @@ * interrupts (VCNL4040, VCNL4200) */ +#include #include #include #include @@ -76,6 +77,7 @@ #define VCNL4040_ALS_CONF_ALS_SHUTDOWN BIT(0) #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) +#define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ /* Bit masks for interrupt registers. */ #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ @@ -104,6 +106,17 @@ static const int vcnl4010_prox_sampling_frequency[][2] = { {250, 0}, }; +static const int vcnl4040_ps_it_times[][2] = { + {0, 100}, + {0, 150}, + {0, 200}, + {0, 250}, + {0, 300}, + {0, 350}, + {0, 400}, + {0, 800}, +}; + #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */ enum vcnl4000_device_ids { @@ -470,6 +483,57 @@ static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on) return ret; } +static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2) +{ + int ret; + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + return ret; + + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret); + + if (ret >= ARRAY_SIZE(vcnl4040_ps_it_times)) + return -EINVAL; + + *val = vcnl4040_ps_it_times[ret][0]; + *val2 = vcnl4040_ps_it_times[ret][1]; + + return 0; +} + +static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val) +{ + unsigned int i; + int ret, index = -1; + u16 regval; + + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_it_times); i++) { + if (val == vcnl4040_ps_it_times[i][1]) { + index = i; + break; + } + } + + if (index < 0) + return -EINVAL; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + goto out; + + regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) | + FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index); + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, + regval); + +out: + mutex_unlock(&data->vcnl4000_lock); + return ret; +} + static int vcnl4000_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -506,6 +570,47 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, *val = 0; *val2 = data->al_scale; return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_INT_TIME: + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + ret = vcnl4040_read_ps_it(data, val, val2); + if (ret < 0) + return ret; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int vcnl4040_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct vcnl4000_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + if (val != 0) + return -EINVAL; + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + return vcnl4040_write_ps_it(data, val2); + default: + return -EINVAL; + } +} + +static int vcnl4040_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + *vals = (int *)vcnl4040_ps_it_times; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = 2 * ARRAY_SIZE(vcnl4040_ps_it_times); + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -844,6 +949,20 @@ static const struct iio_chan_spec vcnl4010_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1), }; +static const struct iio_chan_spec vcnl4040_channels[] = { + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, { + .type = IIO_PROXIMITY, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME), + .ext_info = vcnl4000_ext_info, + } +}; + static const struct iio_info vcnl4000_info = { .read_raw = vcnl4000_read_raw, }; @@ -858,6 +977,12 @@ static const struct iio_info vcnl4010_info = { .write_event_config = vcnl4010_write_event_config, }; +static const struct iio_info vcnl4040_info = { + .read_raw = vcnl4000_read_raw, + .write_raw = vcnl4040_write_raw, + .read_avail = vcnl4040_read_avail, +}; + static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { [VCNL4000] = { .prod = "VCNL4000", @@ -887,9 +1012,9 @@ static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { .measure_light = vcnl4200_measure_light, .measure_proximity = vcnl4200_measure_proximity, .set_power_state = vcnl4200_set_power_state, - .channels = vcnl4000_channels, - .num_channels = ARRAY_SIZE(vcnl4000_channels), - .info = &vcnl4000_info, + .channels = vcnl4040_channels, + .num_channels = ARRAY_SIZE(vcnl4040_channels), + .info = &vcnl4040_info, .irq_support = false, }, [VCNL4200] = { -- GitLab From 55e00b871ce2fc5689af7991638e5889dcd2ea7a Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 27 Sep 2022 14:48:41 +0800 Subject: [PATCH 0846/1480] iio: multiplexer: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replaced with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. It also sets the defer probe reason which can be checked later through debugfs. It's more simple in error path. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220927064841.319291-1-yangyingliang@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/multiplexer/iio-mux.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 93558fddfa9b4..edd8c69f6d2e1 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -416,11 +416,9 @@ static int mux_probe(struct platform_device *pdev) } mux->control = devm_mux_control_get(dev, NULL); - if (IS_ERR(mux->control)) { - if (PTR_ERR(mux->control) != -EPROBE_DEFER) - dev_err(dev, "failed to get control-mux\n"); - return PTR_ERR(mux->control); - } + if (IS_ERR(mux->control)) + return dev_err_probe(dev, PTR_ERR(mux->control), + "failed to get control-mux\n"); i = 0; for (state = 0; state < all_children; state++) { -- GitLab From 4eb61e1a3338d0f8c9f7a28b72f3289cc92133c6 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:16 +0000 Subject: [PATCH 0847/1480] iio: adc: ti-ads131e08: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ads131e08 has no spi_device_id for ti,ads131e04 SPI driver ads131e08 has no spi_device_id for ti,ads131e06 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-2-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads131e08.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 5235a93f28bc6..fcfc462543133 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -807,6 +807,8 @@ static int ads131e08_probe(struct spi_device *spi) int ret; info = device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) { dev_err(&spi->dev, "failed to get match data\n"); return -ENODEV; @@ -926,12 +928,21 @@ static const struct of_device_id ads131e08_of_match[] = { }; MODULE_DEVICE_TABLE(of, ads131e08_of_match); +static const struct spi_device_id ads131e08_ids[] = { + { "ads131e04", (kernel_ulong_t)&ads131e08_info_tbl[ads131e04] }, + { "ads131e06", (kernel_ulong_t)&ads131e08_info_tbl[ads131e06] }, + { "ads131e08", (kernel_ulong_t)&ads131e08_info_tbl[ads131e08] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ads131e08_ids); + static struct spi_driver ads131e08_driver = { .driver = { .name = "ads131e08", .of_match_table = ads131e08_of_match, }, .probe = ads131e08_probe, + .id_table = ads131e08_ids, }; module_spi_driver(ads131e08_driver); -- GitLab From 35dab731c4d2b1e71827a56826ef60f53e97fc32 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:17 +0000 Subject: [PATCH 0848/1480] iio: accel: sca3300: Silence no spi_device_id warning SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver sca3300 has no spi_device_id for murata,scl3300 Add spi_device_id entries to silence the warning, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Reviewed-by: Tomas Melin Link: https://lore.kernel.org/r/20220921163620.805879-3-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/sca3300.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c index eaa0c9cfda44c..306482b70fad7 100644 --- a/drivers/iio/accel/sca3300.c +++ b/drivers/iio/accel/sca3300.c @@ -679,12 +679,20 @@ static const struct of_device_id sca3300_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, sca3300_dt_ids); +static const struct spi_device_id sca3300_ids[] = { + { "sca3300" }, + { "scl3300" }, + {} +}; +MODULE_DEVICE_TABLE(spi, sca3300_ids); + static struct spi_driver sca3300_driver = { - .driver = { + .driver = { .name = SCA3300_ALIAS, .of_match_table = sca3300_dt_ids, }, - .probe = sca3300_probe, + .probe = sca3300_probe, + .id_table = sca3300_ids, }; module_spi_driver(sca3300_driver); -- GitLab From 283026528e0ee8ea89a60f9addaf0f2eda167c42 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:18 +0000 Subject: [PATCH 0849/1480] iio: adc: ad9467: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad9467 has no spi_device_id for adi,ad9265 SPI driver ad9467 has no spi_device_id for adi,ad9434 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-4-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad9467.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 7534572f74757..0621cf59d6146 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -387,6 +387,8 @@ static int ad9467_probe(struct spi_device *spi) int ret; info = of_device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) return -ENODEV; @@ -447,12 +449,21 @@ static const struct of_device_id ad9467_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad9467_of_match); +static const struct spi_device_id ad9467_ids[] = { + { "ad9265", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9265] }, + { "ad9434", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9434] }, + { "ad9467", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9467] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9467_ids); + static struct spi_driver ad9467_driver = { .driver = { .name = "ad9467", .of_match_table = ad9467_of_match, }, .probe = ad9467_probe, + .id_table = ad9467_ids, }; module_spi_driver(ad9467_driver); -- GitLab From 935779eac00aaae02fa61e12c81775e165b11164 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:19 +0000 Subject: [PATCH 0850/1480] iio: adc: ad7192: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad7192 has no spi_device_id for adi,ad7190 SPI driver ad7192 has no spi_device_id for adi,ad7193 SPI driver ad7192 has no spi_device_id for adi,ad7195 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-5-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7192.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index d71977be7d228..f5067173deb62 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -1037,6 +1037,8 @@ static int ad7192_probe(struct spi_device *spi) st->int_vref_mv = ret / 1000; st->chip_info = of_device_get_match_data(&spi->dev); + if (!st->chip_info) + st->chip_info = (void *)spi_get_device_id(spi)->driver_data; indio_dev->name = st->chip_info->name; indio_dev->modes = INDIO_DIRECT_MODE; @@ -1098,12 +1100,22 @@ static const struct of_device_id ad7192_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad7192_of_match); +static const struct spi_device_id ad7192_ids[] = { + { "ad7190", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7190] }, + { "ad7192", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7192] }, + { "ad7193", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7193] }, + { "ad7195", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7195] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7192_ids); + static struct spi_driver ad7192_driver = { .driver = { .name = "ad7192", .of_match_table = ad7192_of_match, }, .probe = ad7192_probe, + .id_table = ad7192_ids, }; module_spi_driver(ad7192_driver); -- GitLab From 3a258747a01f1f21fd4c10a07499bde684f8ca2a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:20 +0000 Subject: [PATCH 0851/1480] iio: adc: ad7124: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad7124 has no spi_device_id for adi,ad7124-4 SPI driver ad7124 has no spi_device_id for adi,ad7124-8 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-6-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7124.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 4088786e1026d..050a2fbf5c493 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -944,6 +944,8 @@ static int ad7124_probe(struct spi_device *spi) int i, ret; info = of_device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) return -ENODEV; @@ -1021,12 +1023,20 @@ static const struct of_device_id ad7124_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad7124_of_match); +static const struct spi_device_id ad71124_ids[] = { + { "ad7124-4", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_4] }, + { "ad7124-8", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_8] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad71124_ids); + static struct spi_driver ad71124_driver = { .driver = { .name = "ad7124", .of_match_table = ad7124_of_match, }, .probe = ad7124_probe, + .id_table = ad71124_ids, }; module_spi_driver(ad71124_driver); -- GitLab From 8f347c565df4e8dd2c862a48a3056bfe59d315e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:54 +0200 Subject: [PATCH 0852/1480] iio: adc: ad799x: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'mlock' was being grabbed when setting the device frequency. In order to not introduce any functional change a new lock is added. With that in mind, the lock also needs to be grabbed in the places where 'mlock' is since it was also being used to protect st->config against the current device state. On the other places the lock was being used, we can just drop it since we are only doing one i2c bus read/write which is already safe. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad799x.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 6dbe9d5e08a2b..4730d8d0f4c3f 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,8 @@ struct ad799x_state { const struct ad799x_chip_config *chip_config; struct regulator *reg; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; unsigned id; u16 config; @@ -290,7 +293,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, ret = iio_device_claim_direct_mode(indio_dev); if (ret) return ret; + mutex_lock(&st->lock); ret = ad799x_scan_direct(st, chan->scan_index); + mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); if (ret < 0) @@ -351,7 +356,8 @@ static ssize_t ad799x_write_frequency(struct device *dev, if (ret) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); + ret = i2c_smbus_read_byte_data(st->client, AD7998_CYCLE_TMR_REG); if (ret < 0) goto error_ret_mutex; @@ -373,7 +379,7 @@ static ssize_t ad799x_write_frequency(struct device *dev, ret = len; error_ret_mutex: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -407,6 +413,8 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev, if (ret) return ret; + mutex_lock(&st->lock); + if (state) st->config |= BIT(chan->scan_index) << AD799X_CHANNEL_SHIFT; else @@ -418,6 +426,7 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev, st->config &= ~AD7998_ALERT_EN; ret = ad799x_write_config(st, st->config); + mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); return ret; } @@ -454,11 +463,9 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev, if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0)) return -EINVAL; - mutex_lock(&indio_dev->mlock); ret = i2c_smbus_write_word_swapped(st->client, ad799x_threshold_reg(chan, dir, info), val << chan->scan_type.shift); - mutex_unlock(&indio_dev->mlock); return ret; } @@ -473,10 +480,8 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev, int ret; struct ad799x_state *st = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); ret = i2c_smbus_read_word_swapped(st->client, ad799x_threshold_reg(chan, dir, info)); - mutex_unlock(&indio_dev->mlock); if (ret < 0) return ret; *val = (ret >> chan->scan_type.shift) & @@ -863,6 +868,9 @@ static int ad799x_probe(struct i2c_client *client, if (ret) goto error_cleanup_ring; } + + mutex_init(&st->lock); + ret = iio_device_register(indio_dev); if (ret) goto error_cleanup_ring; -- GitLab From ed3aa67167bed8825993e6483c6dbeae607c1ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:55 +0200 Subject: [PATCH 0853/1480] iio: adc: axp288_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-3-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/axp288_adc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 580361bd98492..49fff1cabd0dc 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,8 @@ enum axp288_adc_id { struct axp288_adc_info { int irq; struct regmap *regmap; + /* lock to protect against multiple access to the device */ + struct mutex lock; bool ts_enabled; }; @@ -161,7 +164,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, int ret; struct axp288_adc_info *info = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); switch (mask) { case IIO_CHAN_INFO_RAW: if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND, @@ -178,7 +181,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, default: ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -289,6 +292,8 @@ static int axp288_adc_probe(struct platform_device *pdev) if (ret < 0) return ret; + mutex_init(&info->lock); + return devm_iio_device_register(&pdev->dev, indio_dev); } -- GitLab From 7dde7ec2a84d598eb755883540d48a5ee73948ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:56 +0200 Subject: [PATCH 0854/1480] iio: adc: imx7d_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-4-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/imx7d_adc.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index 86caff1d006b9..22da81bac97f1 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -108,7 +109,8 @@ struct imx7d_adc { struct device *dev; void __iomem *regs; struct clk *clk; - + /* lock to protect against multiple access to the device */ + struct mutex lock; u32 vref_uv; u32 value; u32 channel; @@ -293,7 +295,7 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); reinit_completion(&info->completion); channel = chan->channel & 0x03; @@ -303,16 +305,16 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev, ret = wait_for_completion_interruptible_timeout (&info->completion, IMX7D_ADC_TIMEOUT); if (ret == 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return -ETIMEDOUT; } if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } *val = info->value; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -531,6 +533,8 @@ static int imx7d_adc_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&info->lock); + ret = devm_iio_device_register(dev, indio_dev); if (ret) { dev_err(&pdev->dev, "Couldn't register the device.\n"); -- GitLab From 98c4fb93d1d448db191eea795a40072dc61da07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:57 +0200 Subject: [PATCH 0855/1480] iio: adc: lpc32xx_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-5-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/lpc32xx_adc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index b56ce15255cfb..732c924a976dd 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,8 @@ struct lpc32xx_adc_state { struct clk *clk; struct completion completion; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; u32 value; }; @@ -64,10 +67,10 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = clk_prepare_enable(st->clk); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } /* Measurement setup */ @@ -80,7 +83,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, wait_for_completion(&st->completion); /* set by ISR */ clk_disable_unprepare(st->clk); *val = st->value; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return IIO_VAL_INT; @@ -201,6 +204,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) iodev->modes = INDIO_DIRECT_MODE; iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels); + mutex_init(&st->lock); + retval = devm_iio_device_register(&pdev->dev, iodev); if (retval) return retval; -- GitLab From da8091f8acfa953ac55e2aa8d4218e49b18206a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:58 +0200 Subject: [PATCH 0856/1480] iio: adc: ltc2947-core: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-6-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2497-core.c | 7 +++++-- drivers/iio/adc/ltc2497.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c index f52d37af4d1f1..996f6cbbed3ce 100644 --- a/drivers/iio/adc/ltc2497-core.c +++ b/drivers/iio/adc/ltc2497-core.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "ltc2497.h" @@ -81,9 +82,9 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&ddata->lock); ret = ltc2497core_read(ddata, chan->address, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&ddata->lock); if (ret < 0) return ret; @@ -214,6 +215,8 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) ddata->addr_prev = LTC2497_CONFIG_DEFAULT; ddata->time_prev = ktime_get(); + mutex_init(&ddata->lock); + ret = iio_device_register(indio_dev); if (ret < 0) goto err_array_unregister; diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h index e023de0d88c46..781519b524756 100644 --- a/drivers/iio/adc/ltc2497.h +++ b/drivers/iio/adc/ltc2497.h @@ -12,6 +12,8 @@ struct ltc2497_chip_info { struct ltc2497core_driverdata { struct regulator *ref; ktime_t time_prev; + /* lock to protect against multiple access to the device */ + struct mutex lock; const struct ltc2497_chip_info *chip_info; u8 addr_prev; int (*result_and_measure)(struct ltc2497core_driverdata *ddata, -- GitLab From d0c09264f1a64ba8435acfaa70380f61239fc0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:48:59 +0200 Subject: [PATCH 0857/1480] iio: adc: meson_saradc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20221004134909.1692021-7-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/meson_saradc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 1a68b099d323c..85b6826cc10cf 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,8 @@ struct meson_sar_adc_priv { struct clk *adc_div_clk; struct clk_divider clk_div; struct completion done; + /* lock to protect against multiple access to the device */ + struct mutex lock; int calibbias; int calibscale; struct regmap *tsc_regmap; @@ -486,7 +489,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) struct meson_sar_adc_priv *priv = iio_priv(indio_dev); int val, ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&priv->lock); if (priv->param->has_bl30_integration) { /* prevent BL30 from using the SAR ADC while we are using it */ @@ -504,7 +507,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) !(val & MESON_SAR_ADC_DELAY_BL30_BUSY), 1, 10000); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); return ret; } } @@ -521,7 +524,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev) regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); } static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) @@ -1250,6 +1253,8 @@ static int meson_sar_adc_probe(struct platform_device *pdev) if (ret) goto err; + mutex_init(&priv->lock); + ret = meson_sar_adc_hw_enable(indio_dev); if (ret) goto err; -- GitLab From bb690935df8dd8f97612b422c669bd1a5fe87096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:00 +0200 Subject: [PATCH 0858/1480] iio: adc: rockchip_saradc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Acked-by: Heiko Stuebner Link: https://lore.kernel.org/r/20221004134909.1692021-8-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/rockchip_saradc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index b87ea7148b586..79448c5ffc2ae 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -49,6 +50,8 @@ struct rockchip_saradc { struct clk *clk; struct completion completion; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; int uv_vref; struct reset_control *reset; const struct rockchip_saradc_data *data; @@ -94,17 +97,17 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); ret = rockchip_saradc_conversion(info, chan); if (ret) { rockchip_saradc_power_down(info); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } *val = info->last_val; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = info->uv_vref / 1000; @@ -270,7 +273,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) int ret; int i, j = 0; - mutex_lock(&i_dev->mlock); + mutex_lock(&info->lock); for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) { const struct iio_chan_spec *chan = &i_dev->channels[i]; @@ -287,7 +290,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev)); out: - mutex_unlock(&i_dev->mlock); + mutex_unlock(&info->lock); iio_trigger_notify_done(i_dev->trig); @@ -478,6 +481,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&info->lock); + return devm_iio_device_register(&pdev->dev, indio_dev); } -- GitLab From 8433aa3591afff6f4dc641a2e274e6171f66a4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:01 +0200 Subject: [PATCH 0859/1480] iio: adc: sc27xx_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-9-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/sc27xx_adc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index f8421cbba8fa5..ff1fc329bb9b7 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,8 @@ struct sc27xx_adc_data { struct device *dev; struct regulator *volref; struct regmap *regmap; + /* lock to protect against multiple access to the device */ + struct mutex lock; /* * One hardware spinlock to synchronize between the multiple * subsystems which will access the unique ADC controller. @@ -664,9 +667,9 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&data->lock); ret = sc27xx_adc_read(data, chan->channel, scale, &tmp); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&data->lock); if (ret) return ret; @@ -675,10 +678,10 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&indio_dev->mlock); + mutex_lock(&data->lock); ret = sc27xx_adc_read_processed(data, chan->channel, scale, &tmp); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&data->lock); if (ret) return ret; @@ -934,6 +937,9 @@ static int sc27xx_adc_probe(struct platform_device *pdev) indio_dev->info = &sc27xx_info; indio_dev->channels = sc27xx_channels; indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels); + + mutex_init(&sc27xx_data->lock); + ret = devm_iio_device_register(dev, indio_dev); if (ret) dev_err(dev, "could not register iio (ADC)"); -- GitLab From f2bdea865e776b571557035eac2e8afde8ea7844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:02 +0200 Subject: [PATCH 0860/1480] iio: adc: vf610_adc: add helper function to read samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a precursor change to make it simpler to remove the 'mlock' usage. Having the code in it's own helper function, also makes it easier to read the error paths. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-10-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 94 +++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index c6b16cf6e3675..a6f9182d7766a 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -622,6 +622,58 @@ static const struct attribute_group vf610_attribute_group = { .attrs = vf610_attributes, }; +static int vf610_read_sample(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val) +{ + struct vf610_adc *info = iio_priv(indio_dev); + unsigned int hc_cfg; + int ret; + + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto out_unlock; + } + + reinit_completion(&info->completion); + hc_cfg = VF610_ADC_ADCHC(chan->channel); + hc_cfg |= VF610_ADC_AIEN; + writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); + ret = wait_for_completion_interruptible_timeout(&info->completion, + VF610_ADC_TIMEOUT); + if (ret == 0) { + ret = -ETIMEDOUT; + goto out_unlock; + } + + if (ret < 0) + goto out_unlock; + + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->value; + break; + case IIO_TEMP: + /* + * Calculate in degree Celsius times 1000 + * Using the typical sensor slope of 1.84 mV/°C + * and VREFH_ADC at 3.3V, V at 25°C of 699 mV + */ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 1000000 / VF610_TEMP_SLOPE_COEFF; + + break; + default: + ret = -EINVAL; + break; + } + +out_unlock: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + static int vf610_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -629,53 +681,15 @@ static int vf610_read_raw(struct iio_dev *indio_dev, long mask) { struct vf610_adc *info = iio_priv(indio_dev); - unsigned int hc_cfg; long ret; switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } - - reinit_completion(&info->completion); - hc_cfg = VF610_ADC_ADCHC(chan->channel); - hc_cfg |= VF610_ADC_AIEN; - writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); - ret = wait_for_completion_interruptible_timeout - (&info->completion, VF610_ADC_TIMEOUT); - if (ret == 0) { - mutex_unlock(&indio_dev->mlock); - return -ETIMEDOUT; - } - if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + ret = vf610_read_sample(indio_dev, chan, val); + if (ret < 0) return ret; - } - - switch (chan->type) { - case IIO_VOLTAGE: - *val = info->value; - break; - case IIO_TEMP: - /* - * Calculate in degree Celsius times 1000 - * Using the typical sensor slope of 1.84 mV/°C - * and VREFH_ADC at 3.3V, V at 25°C of 699 mV - */ - *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * - 1000000 / VF610_TEMP_SLOPE_COEFF; - - break; - default: - mutex_unlock(&indio_dev->mlock); - return -EINVAL; - } - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: -- GitLab From 4e15cad8dbf9991d430c31166040575bf972b179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:03 +0200 Subject: [PATCH 0861/1480] iio: adc: vf610_adc: vf610_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to drop the internal lock usage we needed two different things: 1) The first place where 'mlock' was being used was a typical case where iio_device_claim_direct_mode() fits perfectly. 2) In the second case, it was being used to prevent concurrent accesses to the device and shared data but nothing was being enforced with regards to buffering (i.e, there was nothing preventing from changing the conversion mode while buffering). Hence, in this case, a new lock was introduced in the state structure. Note that the goal is not to introduce any functional change and that is the reason why a new lock was introduced to guarantee 2). While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-11-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index a6f9182d7766a..ae31aafd26538 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -156,6 +157,9 @@ struct vf610_adc { void __iomem *regs; struct clk *clk; + /* lock to protect against multiple access to the device */ + struct mutex lock; + u32 vref_uv; u32 value; struct regulator *vref; @@ -467,11 +471,11 @@ static int vf610_set_conversion_mode(struct iio_dev *indio_dev, { struct vf610_adc *info = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); info->adc_feature.conv_mode = mode; vf610_adc_calculate_rates(info); vf610_adc_hw_init(info); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return 0; } @@ -629,12 +633,11 @@ static int vf610_read_sample(struct iio_dev *indio_dev, unsigned int hc_cfg; int ret; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto out_unlock; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&info->lock); reinit_completion(&info->completion); hc_cfg = VF610_ADC_ADCHC(chan->channel); hc_cfg |= VF610_ADC_AIEN; @@ -669,7 +672,8 @@ static int vf610_read_sample(struct iio_dev *indio_dev, } out_unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); + iio_device_release_direct_mode(indio_dev); return ret; } @@ -892,6 +896,8 @@ static int vf610_adc_probe(struct platform_device *pdev) goto error_iio_device_register; } + mutex_init(&info->lock); + ret = iio_device_register(indio_dev); if (ret) { dev_err(&pdev->dev, "Couldn't register the device.\n"); -- GitLab From d711a5a7eff4855deb0e2c2663e679dc205e2d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:04 +0200 Subject: [PATCH 0862/1480] iio: common: scmi_iio: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-12-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/common/scmi_sensors/scmi_iio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c index 54ccf19ab2bb1..d92f7f651f7b3 100644 --- a/drivers/iio/common/scmi_sensors/scmi_iio.c +++ b/drivers/iio/common/scmi_sensors/scmi_iio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,8 @@ struct scmi_iio_priv { struct scmi_protocol_handle *ph; const struct scmi_sensor_info *sensor_info; struct iio_dev *indio_dev; + /* lock to protect against multiple access to the device */ + struct mutex lock; /* adding one additional channel for timestamp */ s64 iio_buf[SCMI_IIO_NUM_OF_AXIS + 1]; struct notifier_block sensor_update_nb; @@ -198,13 +201,14 @@ static int scmi_iio_write_raw(struct iio_dev *iio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { + struct scmi_iio_priv *sensor = iio_priv(iio_dev); int err; switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: - mutex_lock(&iio_dev->mlock); + mutex_lock(&sensor->lock); err = scmi_iio_set_odr_val(iio_dev, val, val2); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&sensor->lock); return err; default: return -EINVAL; @@ -586,6 +590,7 @@ scmi_alloc_iiodev(struct scmi_device *sdev, sensor->sensor_info = sensor_info; sensor->sensor_update_nb.notifier_call = scmi_iio_sensor_update_cb; sensor->indio_dev = iiodev; + mutex_init(&sensor->lock); /* adding one additional channel for timestamp */ iiodev->num_channels = sensor_info->num_axis + 1; -- GitLab From 3cc36cabc669fffa7f04931e3dd25dc47314ec06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 4 Oct 2022 15:49:05 +0200 Subject: [PATCH 0863/1480] iio: gyro: itg3200_core: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-13-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_core.c | 10 +++++++--- include/linux/iio/gyro/itg3200.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 4215015845875..74ca224684968 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -131,6 +132,7 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct itg3200 *st = iio_priv(indio_dev); int ret; u8 t; @@ -139,11 +141,11 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, if (val == 0 || val2 != 0) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; @@ -152,7 +154,7 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; default: @@ -336,6 +338,8 @@ static int itg3200_probe(struct i2c_client *client, if (ret) goto error_remove_trigger; + mutex_init(&st->lock); + ret = iio_device_register(indio_dev); if (ret) goto error_remove_trigger; diff --git a/include/linux/iio/gyro/itg3200.h b/include/linux/iio/gyro/itg3200.h index a602fe7b84fa4..74b6d1cadc868 100644 --- a/include/linux/iio/gyro/itg3200.h +++ b/include/linux/iio/gyro/itg3200.h @@ -102,6 +102,8 @@ struct itg3200 { struct i2c_client *i2c; struct iio_trigger *trig; struct iio_mount_matrix orientation; + /* lock to protect against multiple access to the device */ + struct mutex lock; }; enum ITG3200_SCAN_INDEX { -- GitLab From 4b0c44bdb72e99f17b600ba5ba9acc81cf67e335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 5 Oct 2022 10:50:43 +0200 Subject: [PATCH 0864/1480] dt-bindings: iio: dac: change ad5766 maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the maintainer email no longer exists, change it to myself. Signed-off-by: Nuno Sá Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221005085044.204701-1-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml index 29bd16dab5464..3c8784a54d2ce 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Analog Devices AD5766 DAC device driver maintainers: - - Cristian Pop + - Nuno Sá description: | Bindings for the Analog Devices AD5766 current DAC device. Datasheet can be -- GitLab From 8add74e75ea2a2356d5b4579cacbaef7f4828e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 5 Oct 2022 10:50:44 +0200 Subject: [PATCH 0865/1480] dt-bindings: iio: frequency: change admv4420 maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the maintainer email no longer exists, change it to myself. Signed-off-by: Nuno Sá Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221005085044.204701-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/frequency/adi,admv4420.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml index da7fe85ec92ef..071cda64865d3 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ADMV4420 K Band Downconverter maintainers: - - Cristian Pop + - Nuno Sá description: The ADMV4420 is a highly integrated, double balanced, active -- GitLab From d26b79732d27ff45c83109e2484b96dcac223355 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:35 +0200 Subject: [PATCH 0866/1480] dt-bindings: iio: addac: adi,ad74413r: use spi-peripheral-props.yaml Reference the spi-peripheral-props.yaml schema to allow using all properties typical for SPI-connected devices, even these which device bindings author did not tried yet. While changing additionalProperties->unevaluatedProperties, put it in typical place, just before example DTS. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-1-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/addac/adi,ad74413r.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml index 03bb90a7f4f88..2e8dad9278f21 100644 --- a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml +++ b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml @@ -58,8 +58,6 @@ required: - spi-cpol - refin-supply -additionalProperties: false - patternProperties: "^channel@[0-3]$": type: object @@ -103,6 +101,11 @@ patternProperties: required: - reg +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + examples: - | #include -- GitLab From 1b96d663d97da5205526d7020dad5258b88baee2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:36 +0200 Subject: [PATCH 0867/1480] dt-bindings: iio: addac: adi,ad74413r: improve example Improve example by: dropping unrelated properties (status and cs-gpios) and using generic node name. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-2-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/addac/adi,ad74413r.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml index 2e8dad9278f21..58b3ae14ccaa6 100644 --- a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml +++ b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml @@ -116,10 +116,7 @@ examples: #address-cells = <1>; #size-cells = <0>; - cs-gpios = <&gpio 17 GPIO_ACTIVE_LOW>; - status = "okay"; - - ad74413r@0 { + addac@0 { compatible = "adi,ad74413r"; reg = <0>; spi-max-frequency = <1000000>; -- GitLab From 00407a680e86db4d2fee43250849b7fa205507d3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:37 +0200 Subject: [PATCH 0868/1480] dt-bindings: iio: frequency: use spi-peripheral-props.yaml For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. While changing additionalProperties->unevaluatedProperties, put it in typical place, just before example DTS. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-3-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/frequency/adi,adf4350.yaml | 7 +++++-- .../devicetree/bindings/iio/frequency/adi,admv1013.yaml | 5 ++++- .../devicetree/bindings/iio/frequency/adi,admv1014.yaml | 5 ++++- .../devicetree/bindings/iio/frequency/adi,admv4420.yaml | 6 +++++- .../devicetree/bindings/iio/frequency/adi,adrf6780.yaml | 5 ++++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,adf4350.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,adf4350.yaml index d7f20b8518e06..43cbf27114c7b 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,adf4350.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,adf4350.yaml @@ -160,13 +160,16 @@ properties: 2: +2dBm 3: +5dBm -additionalProperties: false - required: - compatible - reg - clocks +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + examples: - | spi { diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admv1013.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admv1013.yaml index 23f1f3b55abb3..fc813bcb65320 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,admv1013.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admv1013.yaml @@ -70,7 +70,10 @@ required: - clock-names - vcm-supply -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml index 2716c1e8fe316..ab86daa2c56ec 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml @@ -104,7 +104,10 @@ required: - clock-names - vcm-supply -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml index 071cda64865d3..64f2352aac3d5 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml @@ -37,7 +37,11 @@ required: - compatible - reg -additionalProperties: false + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,adrf6780.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,adrf6780.yaml index 3a8ea93f4e0c1..f11391ab4b622 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,adrf6780.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,adrf6780.yaml @@ -113,7 +113,10 @@ required: - clocks - clock-names -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- GitLab From d29c7f8ce90d549727d7a07b6096615f26b38e85 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:38 +0200 Subject: [PATCH 0869/1480] dt-bindings: iio: gyroscope: use spi-peripheral-props.yaml For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-4-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml | 5 ++++- .../devicetree/bindings/iio/gyroscope/nxp,fxas21002c.yaml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml index 662ec59ca0af5..0ae2464b9bc42 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml @@ -38,7 +38,10 @@ required: - spi-cpol - spi-cpha -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/iio/gyroscope/nxp,fxas21002c.yaml b/Documentation/devicetree/bindings/iio/gyroscope/nxp,fxas21002c.yaml index 3f57a1b813e69..2c900e9dddc62 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/nxp,fxas21002c.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/nxp,fxas21002c.yaml @@ -56,7 +56,10 @@ required: - compatible - reg -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- GitLab From acce6052cdf9f9fc03f2668f63a1d9e42dc8a424 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:39 +0200 Subject: [PATCH 0870/1480] dt-bindings: iio: imu: adi,adis16475: use spi-peripheral-props.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221004115642.63749-5-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml b/Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml index a7574210175a9..5dbfae80bb281 100644 --- a/Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml +++ b/Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml @@ -79,6 +79,7 @@ required: - spi-cpol allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# - if: properties: compatible: @@ -107,7 +108,7 @@ allOf: dependencies: adi,sync-mode: [ clocks ] -additionalProperties: false +unevaluatedProperties: false examples: - | -- GitLab From 87748b25c65a0fda5f605b7cf07cf9b79b257308 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:40 +0200 Subject: [PATCH 0871/1480] dt-bindings: iio: pressure: use spi-peripheral-props.yaml For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-6-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/pressure/meas,ms5611.yaml | 5 ++++- .../devicetree/bindings/iio/pressure/murata,zpa2326.yaml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml b/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml index 4f06707450bf5..7fed750fa3ff7 100644 --- a/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml @@ -30,7 +30,10 @@ required: - compatible - reg -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml b/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml index d6103be03460b..c33640ddde586 100644 --- a/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml @@ -33,7 +33,10 @@ required: - compatible - reg -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- GitLab From e91d40216890874791ee43ef40cc883ba412a84f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:41 +0200 Subject: [PATCH 0872/1480] dt-bindings: iio: proximity: ams,as3935: use spi-peripheral-props.yaml For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-7-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/proximity/ams,as3935.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/proximity/ams,as3935.yaml b/Documentation/devicetree/bindings/iio/proximity/ams,as3935.yaml index 7fcba5d6d508e..710d3b9a86d90 100644 --- a/Documentation/devicetree/bindings/iio/proximity/ams,as3935.yaml +++ b/Documentation/devicetree/bindings/iio/proximity/ams,as3935.yaml @@ -49,7 +49,10 @@ required: - spi-cpha - interrupts -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- GitLab From 85250a2400ad43542d02b46b6e269343ea835331 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Oct 2022 13:56:42 +0200 Subject: [PATCH 0873/1480] dt-bindings: iio: resolver: adi,ad2s90: use spi-peripheral-props.yaml For devices connectable by SPI bus (e.g. already using "spi-max-frequency" property), reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties, even these which device bindings author did not tried yet. While changing additionalProperties->unevaluatedProperties, put it in typical place, just before example DTS. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221004115642.63749-8-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/resolver/adi,ad2s90.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/resolver/adi,ad2s90.yaml b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s90.yaml index 81e4bdfc17c43..b24e5a202a48a 100644 --- a/Documentation/devicetree/bindings/iio/resolver/adi,ad2s90.yaml +++ b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s90.yaml @@ -33,8 +33,6 @@ properties: spi-cpha: true -additionalProperties: false - required: - compatible - reg @@ -43,6 +41,11 @@ dependencies: spi-cpol: [ spi-cpha ] spi-cpha: [ spi-cpol ] +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + examples: - | spi { -- GitLab From a44ef7c4609724e2f395d8a24d4a863cd860bbba Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Mon, 3 Oct 2022 13:59:01 +0300 Subject: [PATCH 0874/1480] iio: adc: add max11410 adc driver Adding support for max11410 24-bit, 1.9ksps delta-sigma adc which has 3 differential reference and 10 differential channel inputs. Inputs and references can be buffered internally. Inputs can also be amplified with internal PGA. Device has four digital filter modes: FIR50/60, FIR50, FIR60 and SINC4. FIR 50Hz and 60Hz rejections can be enabled/disabled separately. Digital filter selection affects sampling frequency range so driver has to consider the configured filter when configuring sampling frequency. Signed-off-by: Ibrahim Tilki Link: https://lore.kernel.org/r/20221003105903.229-2-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 13 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/max11410.c | 1050 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1064 insertions(+) create mode 100644 drivers/iio/adc/max11410.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 791612ca60120..544986fd456de 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -667,6 +667,19 @@ config MAX11205 To compile this driver as a module, choose M here: the module will be called max11205. +config MAX11410 + tristate "Analog Devices MAX11410 ADC driver" + depends on SPI + select REGMAP_SPI + select IIO_BUFFER + select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices MAX11410 ADCs. + + To compile this driver as a module, choose M here: the module will be + called max11410. + config MAX1241 tristate "Maxim max1241 ADC driver" depends on SPI_MASTER diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 46caba7a010c9..4d803413425c4 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX11100) += max11100.o obj-$(CONFIG_MAX1118) += max1118.o obj-$(CONFIG_MAX11205) += max11205.o +obj-$(CONFIG_MAX11410) += max11410.o obj-$(CONFIG_MAX1241) += max1241.o obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_MAX9611) += max9611.o diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c new file mode 100644 index 0000000000000..8cd5663671874 --- /dev/null +++ b/drivers/iio/adc/max11410.c @@ -0,0 +1,1050 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MAX11410 SPI ADC driver + * + * Copyright 2022 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAX11410_REG_CONV_START 0x01 +#define MAX11410_CONV_TYPE_SINGLE 0x00 +#define MAX11410_CONV_TYPE_CONTINUOUS 0x01 +#define MAX11410_REG_CAL_START 0x03 +#define MAX11410_CAL_START_SELF 0x00 +#define MAX11410_CAL_START_PGA 0x01 +#define MAX11410_REG_GPIO_CTRL(ch) ((ch) ? 0x05 : 0x04) +#define MAX11410_GPIO_INTRB 0xC1 +#define MAX11410_REG_FILTER 0x08 +#define MAX11410_FILTER_RATE_MASK GENMASK(3, 0) +#define MAX11410_FILTER_RATE_MAX 0x0F +#define MAX11410_FILTER_LINEF_MASK GENMASK(5, 4) +#define MAX11410_FILTER_50HZ BIT(5) +#define MAX11410_FILTER_60HZ BIT(4) +#define MAX11410_REG_CTRL 0x09 +#define MAX11410_CTRL_REFSEL_MASK GENMASK(2, 0) +#define MAX11410_CTRL_VREFN_BUF_BIT BIT(3) +#define MAX11410_CTRL_VREFP_BUF_BIT BIT(4) +#define MAX11410_CTRL_FORMAT_BIT BIT(5) +#define MAX11410_CTRL_UNIPOLAR_BIT BIT(6) +#define MAX11410_REG_MUX_CTRL0 0x0B +#define MAX11410_REG_PGA 0x0E +#define MAX11410_PGA_GAIN_MASK GENMASK(2, 0) +#define MAX11410_PGA_SIG_PATH_MASK GENMASK(5, 4) +#define MAX11410_PGA_SIG_PATH_BUFFERED 0x00 +#define MAX11410_PGA_SIG_PATH_BYPASS 0x01 +#define MAX11410_PGA_SIG_PATH_PGA 0x02 +#define MAX11410_REG_DATA0 0x30 +#define MAX11410_REG_STATUS 0x38 +#define MAX11410_STATUS_CONV_READY_BIT BIT(0) +#define MAX11410_STATUS_CAL_READY_BIT BIT(2) + +#define MAX11410_REFSEL_AVDD_AGND 0x03 +#define MAX11410_REFSEL_MAX 0x06 +#define MAX11410_SIG_PATH_MAX 0x02 +#define MAX11410_CHANNEL_INDEX_MAX 0x0A +#define MAX11410_AINP_AVDD 0x0A +#define MAX11410_AINN_GND 0x0A + +#define MAX11410_CONVERSION_TIMEOUT_MS 2000 +#define MAX11410_CALIB_TIMEOUT_MS 2000 + +#define MAX11410_SCALE_AVAIL_SIZE 8 + +enum max11410_filter { + MAX11410_FILTER_FIR5060, + MAX11410_FILTER_FIR50, + MAX11410_FILTER_FIR60, + MAX11410_FILTER_SINC4, +}; + +static const u8 max11410_sampling_len[] = { + [MAX11410_FILTER_FIR5060] = 5, + [MAX11410_FILTER_FIR50] = 6, + [MAX11410_FILTER_FIR60] = 6, + [MAX11410_FILTER_SINC4] = 10, +}; + +static const int max11410_sampling_rates[4][10][2] = { + [MAX11410_FILTER_FIR5060] = { + { 1, 100000 }, + { 2, 100000 }, + { 4, 200000 }, + { 8, 400000 }, + { 16, 800000 } + }, + [MAX11410_FILTER_FIR50] = { + { 1, 300000 }, + { 2, 700000 }, + { 5, 300000 }, + { 10, 700000 }, + { 21, 300000 }, + { 40 } + }, + [MAX11410_FILTER_FIR60] = { + { 1, 300000 }, + { 2, 700000 }, + { 5, 300000 }, + { 10, 700000 }, + { 21, 300000 }, + { 40 } + }, + [MAX11410_FILTER_SINC4] = { + { 4 }, + { 10 }, + { 20 }, + { 40 }, + { 60 }, + { 120 }, + { 240 }, + { 480 }, + { 960 }, + { 1920 } + } +}; + +struct max11410_channel_config { + u32 settling_time_us; + u32 *scale_avail; + u8 refsel; + u8 sig_path; + u8 gain; + bool bipolar; + bool buffered_vrefp; + bool buffered_vrefn; +}; + +struct max11410_state { + struct spi_device *spi_dev; + struct iio_trigger *trig; + struct completion completion; + struct mutex lock; /* Prevent changing channel config during sampling */ + struct regmap *regmap; + struct regulator *avdd; + struct regulator *vrefp[3]; + struct regulator *vrefn[3]; + struct max11410_channel_config *channels; + int irq; + struct { + u32 data __aligned(IIO_DMA_MINALIGN); + s64 ts __aligned(8); + } scan; +}; + +static const struct iio_chan_spec chanspec_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + .endianness = IIO_LE, + }, +}; + +static unsigned int max11410_reg_size(unsigned int reg) +{ + /* Registers from 0x00 to 0x10 are 1 byte, the rest are 3 bytes long. */ + return reg <= 0x10 ? 1 : 3; +} + +static int max11410_write_reg(struct max11410_state *st, unsigned int reg, + unsigned int val) +{ + /* This driver only needs to write 8-bit registers */ + if (max11410_reg_size(reg) != 1) + return -EINVAL; + + return regmap_write(st->regmap, reg, val); +} + +static int max11410_read_reg(struct max11410_state *st, unsigned int reg, + int *val) +{ + int ret; + + if (max11410_reg_size(reg) == 3) { + ret = regmap_bulk_read(st->regmap, reg, &st->scan.data, 3); + if (ret) + return ret; + + *val = get_unaligned_be24(&st->scan.data); + return 0; + } + + return regmap_read(st->regmap, reg, val); +} + +static struct regulator *max11410_get_vrefp(struct max11410_state *st, + u8 refsel) +{ + refsel = refsel % 4; + if (refsel == 3) + return st->avdd; + + return st->vrefp[refsel]; +} + +static struct regulator *max11410_get_vrefn(struct max11410_state *st, + u8 refsel) +{ + if (refsel > 2) + return NULL; + + return st->vrefn[refsel]; +} + +static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x39, +}; + +static ssize_t max11410_notch_en_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); + unsigned int val; + int ret; + + ret = max11410_read_reg(state, MAX11410_REG_FILTER, &val); + if (ret) + return ret; + + switch (iio_attr->address) { + case 0: + val = !FIELD_GET(MAX11410_FILTER_50HZ, val); + break; + case 1: + val = !FIELD_GET(MAX11410_FILTER_60HZ, val); + break; + case 2: + val = FIELD_GET(MAX11410_FILTER_LINEF_MASK, val) == 3; + break; + default: + return -EINVAL; + } + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t max11410_notch_en_store(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + unsigned int filter_bits; + bool enable; + int ret; + + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + switch (iio_attr->address) { + case 0: + filter_bits = MAX11410_FILTER_50HZ; + break; + case 1: + filter_bits = MAX11410_FILTER_60HZ; + break; + case 2: + default: + filter_bits = MAX11410_FILTER_50HZ | MAX11410_FILTER_60HZ; + enable = !enable; + break; + } + + if (enable) + ret = regmap_clear_bits(state->regmap, MAX11410_REG_FILTER, + filter_bits); + else + ret = regmap_set_bits(state->regmap, MAX11410_REG_FILTER, + filter_bits); + + if (ret) + return ret; + + return count; +} + +static ssize_t in_voltage_filter2_notch_center_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + int ret, reg, rate, filter; + + ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®); + if (ret) + return ret; + + rate = FIELD_GET(MAX11410_FILTER_RATE_MASK, reg); + rate = clamp_val(rate, 0, + max11410_sampling_len[MAX11410_FILTER_SINC4] - 1); + filter = max11410_sampling_rates[MAX11410_FILTER_SINC4][rate][0]; + + return sysfs_emit(buf, "%d\n", filter); +} + +static IIO_CONST_ATTR(in_voltage_filter0_notch_center, "50"); +static IIO_CONST_ATTR(in_voltage_filter1_notch_center, "60"); +static IIO_DEVICE_ATTR_RO(in_voltage_filter2_notch_center, 2); + +static IIO_DEVICE_ATTR(in_voltage_filter0_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 0); +static IIO_DEVICE_ATTR(in_voltage_filter1_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 1); +static IIO_DEVICE_ATTR(in_voltage_filter2_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 2); + +static struct attribute *max11410_attributes[] = { + &iio_const_attr_in_voltage_filter0_notch_center.dev_attr.attr, + &iio_const_attr_in_voltage_filter1_notch_center.dev_attr.attr, + &iio_dev_attr_in_voltage_filter2_notch_center.dev_attr.attr, + &iio_dev_attr_in_voltage_filter0_notch_en.dev_attr.attr, + &iio_dev_attr_in_voltage_filter1_notch_en.dev_attr.attr, + &iio_dev_attr_in_voltage_filter2_notch_en.dev_attr.attr, + NULL +}; + +static const struct attribute_group max11410_attribute_group = { + .attrs = max11410_attributes, +}; + +static int max11410_set_input_mux(struct max11410_state *st, u8 ainp, u8 ainn) +{ + if (ainp > MAX11410_CHANNEL_INDEX_MAX || + ainn > MAX11410_CHANNEL_INDEX_MAX) + return -EINVAL; + + return max11410_write_reg(st, MAX11410_REG_MUX_CTRL0, + (ainp << 4) | ainn); +} + +static int max11410_configure_channel(struct max11410_state *st, + struct iio_chan_spec const *chan) +{ + struct max11410_channel_config cfg = st->channels[chan->address]; + unsigned int regval; + int ret; + + if (chan->differential) + ret = max11410_set_input_mux(st, chan->channel, chan->channel2); + else + ret = max11410_set_input_mux(st, chan->channel, + MAX11410_AINN_GND); + + if (ret) + return ret; + + regval = FIELD_PREP(MAX11410_CTRL_VREFP_BUF_BIT, cfg.buffered_vrefp) | + FIELD_PREP(MAX11410_CTRL_VREFN_BUF_BIT, cfg.buffered_vrefn) | + FIELD_PREP(MAX11410_CTRL_REFSEL_MASK, cfg.refsel) | + FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); + ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, + MAX11410_CTRL_REFSEL_MASK | + MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_UNIPOLAR_BIT, regval); + if (ret) + return ret; + + regval = FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, cfg.sig_path) | + FIELD_PREP(MAX11410_PGA_GAIN_MASK, cfg.gain); + ret = regmap_write(st->regmap, MAX11410_REG_PGA, regval); + if (ret) + return ret; + + if (cfg.settling_time_us) + fsleep(cfg.settling_time_us); + + return 0; +} + +static int max11410_sample(struct max11410_state *st, int *sample_raw, + struct iio_chan_spec const *chan) +{ + int val, ret; + + ret = max11410_configure_channel(st, chan); + if (ret) + return ret; + + if (st->irq > 0) + reinit_completion(&st->completion); + + /* Start Conversion */ + ret = max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_SINGLE); + if (ret) + return ret; + + if (st->irq > 0) { + /* Wait for an interrupt. */ + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(MAX11410_CONVERSION_TIMEOUT_MS)); + if (!ret) + return -ETIMEDOUT; + } else { + /* Wait for status register Conversion Ready flag */ + ret = read_poll_timeout(max11410_read_reg, ret, + ret || (val & MAX11410_STATUS_CONV_READY_BIT), + 5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000, + true, st, MAX11410_REG_STATUS, &val); + if (ret) + return ret; + } + + /* Read ADC Data */ + return max11410_read_reg(st, MAX11410_REG_DATA0, sample_raw); +} + +static int max11410_get_scale(struct max11410_state *state, + struct max11410_channel_config cfg) +{ + struct regulator *vrefp, *vrefn; + int scale; + + vrefp = max11410_get_vrefp(state, cfg.refsel); + + scale = regulator_get_voltage(vrefp) / 1000; + vrefn = max11410_get_vrefn(state, cfg.refsel); + if (vrefn) + scale -= regulator_get_voltage(vrefn) / 1000; + + if (cfg.bipolar) + scale *= 2; + + return scale >> cfg.gain; +} + +static int max11410_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct max11410_state *state = iio_priv(indio_dev); + struct max11410_channel_config cfg = state->channels[chan->address]; + int ret, reg_val, filter, rate; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + *val = max11410_get_scale(state, cfg); + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_OFFSET: + if (cfg.bipolar) + *val = -BIT(chan->scan_type.realbits - 1); + else + *val = 0; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&state->lock); + + ret = max11410_sample(state, ®_val, chan); + + mutex_unlock(&state->lock); + + iio_device_release_direct_mode(indio_dev); + + if (ret) + return ret; + + *val = reg_val; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + return ret; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + rate = reg_val & MAX11410_FILTER_RATE_MASK; + if (rate >= max11410_sampling_len[filter]) + rate = max11410_sampling_len[filter] - 1; + + *val = max11410_sampling_rates[filter][rate][0]; + *val2 = max11410_sampling_rates[filter][rate][1]; + + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +static int max11410_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct max11410_state *st = iio_priv(indio_dev); + int i, ret, reg_val, filter, gain; + u32 *scale_avail; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + scale_avail = st->channels[chan->address].scale_avail; + if (!scale_avail) + return -EOPNOTSUPP; + + /* Accept values in range 0.000001 <= scale < 1.000000 */ + if (val != 0 || val2 == 0) + return -EINVAL; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + /* Convert from INT_PLUS_MICRO to FRACTIONAL_LOG2 */ + val2 = val2 * DIV_ROUND_CLOSEST(BIT(24), 1000000); + val2 = DIV_ROUND_CLOSEST(scale_avail[0], val2); + gain = order_base_2(val2); + + st->channels[chan->address].gain = clamp_val(gain, 0, 7); + + iio_device_release_direct_mode(indio_dev); + + return 0; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + + ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + goto out; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + + for (i = 0; i < max11410_sampling_len[filter]; ++i) { + if (val == max11410_sampling_rates[filter][i][0] && + val2 == max11410_sampling_rates[filter][i][1]) + break; + } + if (i == max11410_sampling_len[filter]) { + ret = -EINVAL; + goto out; + } + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, i); + +out: + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); + + return ret; + default: + return -EINVAL; + } +} + +static int max11410_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct max11410_state *st = iio_priv(indio_dev); + struct max11410_channel_config cfg; + int ret, reg_val, filter; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + return ret; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + + *vals = (const int *)max11410_sampling_rates[filter]; + *length = max11410_sampling_len[filter] * 2; + *type = IIO_VAL_INT_PLUS_MICRO; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + cfg = st->channels[chan->address]; + + if (!cfg.scale_avail) + return -EINVAL; + + *vals = cfg.scale_avail; + *length = MAX11410_SCALE_AVAIL_SIZE * 2; + *type = IIO_VAL_FRACTIONAL_LOG2; + + return IIO_AVAIL_LIST; + } + return -EINVAL; +} + +static const struct iio_info max11410_info = { + .read_raw = max11410_read_raw, + .write_raw = max11410_write_raw, + .read_avail = max11410_read_avail, + .attrs = &max11410_attribute_group, +}; + +static irqreturn_t max11410_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct max11410_state *st = iio_priv(indio_dev); + int ret; + + ret = max11410_read_reg(st, MAX11410_REG_DATA0, &st->scan.data); + if (ret) { + dev_err(&indio_dev->dev, "cannot read data\n"); + goto out; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, + iio_get_time_ns(indio_dev)); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int max11410_buffer_postenable(struct iio_dev *indio_dev) +{ + struct max11410_state *st = iio_priv(indio_dev); + int scan_ch, ret; + + scan_ch = ffs(*indio_dev->active_scan_mask) - 1; + + ret = max11410_configure_channel(st, &indio_dev->channels[scan_ch]); + if (ret) + return ret; + + /* Start continuous conversion. */ + return max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_CONTINUOUS); +} + +static int max11410_buffer_predisable(struct iio_dev *indio_dev) +{ + struct max11410_state *st = iio_priv(indio_dev); + + /* Stop continuous conversion. */ + return max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_SINGLE); +} + +static const struct iio_buffer_setup_ops max11410_buffer_ops = { + .postenable = &max11410_buffer_postenable, + .predisable = &max11410_buffer_predisable, + .validate_scan_mask = &iio_validate_scan_mask_onehot, +}; + +static const struct iio_trigger_ops max11410_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static irqreturn_t max11410_interrupt(int irq, void *dev_id) +{ + struct iio_dev *indio_dev = dev_id; + struct max11410_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll_chained(st->trig); + else + complete(&st->completion); + + return IRQ_HANDLED; +}; + +static int max11410_parse_channels(struct max11410_state *st, + struct iio_dev *indio_dev) +{ + struct iio_chan_spec chanspec = chanspec_template; + struct device *dev = &st->spi_dev->dev; + struct max11410_channel_config *cfg; + struct iio_chan_spec *channels; + struct fwnode_handle *child; + u32 reference, sig_path; + const char *node_name; + u32 inputs[2], scale; + unsigned int num_ch; + int chan_idx = 0; + int ret, i; + + num_ch = device_get_child_node_count(dev); + if (num_ch == 0) + return dev_err_probe(&indio_dev->dev, -ENODEV, + "FW has no channels defined\n"); + + /* Reserve space for soft timestamp channel */ + num_ch++; + channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + st->channels = devm_kcalloc(dev, num_ch, sizeof(*st->channels), + GFP_KERNEL); + if (!st->channels) + return -ENOMEM; + + device_for_each_child_node(dev, child) { + node_name = fwnode_get_name(child); + if (fwnode_property_present(child, "diff-channels")) { + ret = fwnode_property_read_u32_array(child, + "diff-channels", + inputs, + ARRAY_SIZE(inputs)); + + chanspec.differential = 1; + } else { + ret = fwnode_property_read_u32(child, "reg", &inputs[0]); + + inputs[1] = 0; + chanspec.differential = 0; + } + if (ret) { + fwnode_handle_put(child); + return ret; + } + + if (inputs[0] > MAX11410_CHANNEL_INDEX_MAX || + inputs[1] > MAX11410_CHANNEL_INDEX_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid channel index for %s, should be less than %d\n", + node_name, + MAX11410_CHANNEL_INDEX_MAX + 1); + } + + cfg = &st->channels[chan_idx]; + + reference = MAX11410_REFSEL_AVDD_AGND; + fwnode_property_read_u32(child, "adi,reference", &reference); + if (reference > MAX11410_REFSEL_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid adi,reference value for %s, should be less than %d.\n", + node_name, MAX11410_REFSEL_MAX + 1); + } + + if (!max11410_get_vrefp(st, reference) || + (!max11410_get_vrefn(st, reference) && reference <= 2)) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid VREF configuration for %s, either specify corresponding VREF regulators or change adi,reference property.\n", + node_name); + } + + sig_path = MAX11410_PGA_SIG_PATH_BUFFERED; + fwnode_property_read_u32(child, "adi,input-mode", &sig_path); + if (sig_path > MAX11410_SIG_PATH_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid adi,input-mode value for %s, should be less than %d.\n", + node_name, MAX11410_SIG_PATH_MAX + 1); + } + + fwnode_property_read_u32(child, "settling-time-us", + &cfg->settling_time_us); + cfg->bipolar = fwnode_property_read_bool(child, "bipolar"); + cfg->buffered_vrefp = fwnode_property_read_bool(child, "adi,buffered-vrefp"); + cfg->buffered_vrefn = fwnode_property_read_bool(child, "adi,buffered-vrefn"); + cfg->refsel = reference; + cfg->sig_path = sig_path; + cfg->gain = 0; + + /* Enable scale_available property if input mode is PGA */ + if (sig_path == MAX11410_PGA_SIG_PATH_PGA) { + __set_bit(IIO_CHAN_INFO_SCALE, + &chanspec.info_mask_separate_available); + cfg->scale_avail = devm_kcalloc(dev, MAX11410_SCALE_AVAIL_SIZE * 2, + sizeof(*cfg->scale_avail), + GFP_KERNEL); + if (!cfg->scale_avail) { + fwnode_handle_put(child); + return -ENOMEM; + } + + scale = max11410_get_scale(st, *cfg); + for (i = 0; i < MAX11410_SCALE_AVAIL_SIZE; i++) { + cfg->scale_avail[2 * i] = scale >> i; + cfg->scale_avail[2 * i + 1] = chanspec.scan_type.realbits; + } + } else { + __clear_bit(IIO_CHAN_INFO_SCALE, + &chanspec.info_mask_separate_available); + } + + chanspec.address = chan_idx; + chanspec.scan_index = chan_idx; + chanspec.channel = inputs[0]; + chanspec.channel2 = inputs[1]; + + channels[chan_idx] = chanspec; + chan_idx++; + } + + channels[chan_idx] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(chan_idx); + + indio_dev->num_channels = chan_idx + 1; + indio_dev->channels = channels; + + return 0; +} + +static void max11410_disable_reg(void *reg) +{ + regulator_disable(reg); +} + +static int max11410_init_vref(struct device *dev, + struct regulator **vref, + const char *id) +{ + struct regulator *reg; + int ret; + + reg = devm_regulator_get_optional(dev, id); + if (PTR_ERR(reg) == -ENODEV) { + *vref = NULL; + return 0; + } else if (IS_ERR(reg)) { + return PTR_ERR(reg); + } + ret = regulator_enable(reg); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable regulator %s\n", id); + + *vref = reg; + return devm_add_action_or_reset(dev, max11410_disable_reg, reg); +} + +static int max11410_calibrate(struct max11410_state *st, u32 cal_type) +{ + int ret, val; + + ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type); + if (ret) + return ret; + + /* Wait for status register Calibration Ready flag */ + return read_poll_timeout(max11410_read_reg, ret, + ret || (val & MAX11410_STATUS_CAL_READY_BIT), + 50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true, + st, MAX11410_REG_STATUS, &val); +} + +static int max11410_self_calibrate(struct max11410_state *st) +{ + int ret, i; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, + FIELD_PREP(MAX11410_FILTER_RATE_MASK, + MAX11410_FILTER_RATE_MAX)); + if (ret) + return ret; + + ret = max11410_calibrate(st, MAX11410_CAL_START_SELF); + if (ret) + return ret; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_SIG_PATH_MASK, + FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, + MAX11410_PGA_SIG_PATH_PGA)); + if (ret) + return ret; + + /* PGA calibrations */ + for (i = 1; i < 8; ++i) { + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_GAIN_MASK, i); + if (ret) + return ret; + + ret = max11410_calibrate(st, MAX11410_CAL_START_PGA); + if (ret) + return ret; + } + + /* Cleanup */ + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_GAIN_MASK, 0); + if (ret) + return ret; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, 0); + if (ret) + return ret; + + return regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_SIG_PATH_MASK, + FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, + MAX11410_PGA_SIG_PATH_BUFFERED)); +} + +static int max11410_probe(struct spi_device *spi) +{ + const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" }; + const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" }; + struct device *dev = &spi->dev; + struct max11410_state *st; + struct iio_dev *indio_dev; + int ret, irqs[2]; + int i; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi_dev = spi; + init_completion(&st->completion); + mutex_init(&st->lock); + + indio_dev->name = "max11410"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &max11410_info; + + st->regmap = devm_regmap_init_spi(spi, ®map_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "regmap initialization failed\n"); + + ret = max11410_init_vref(dev, &st->avdd, "avdd"); + if (ret) + return ret; + + for (i = 0; i < ARRAY_SIZE(vrefp_regs); i++) { + ret = max11410_init_vref(dev, &st->vrefp[i], vrefp_regs[i]); + if (ret) + return ret; + + ret = max11410_init_vref(dev, &st->vrefn[i], vrefn_regs[i]); + if (ret) + return ret; + } + + /* + * Regulators must be configured before parsing channels for + * validating "adi,reference" property of each channel. + */ + ret = max11410_parse_channels(st, indio_dev); + if (ret) + return ret; + + irqs[0] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio0"); + irqs[1] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio1"); + + if (irqs[0] > 0) { + st->irq = irqs[0]; + ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(0), + MAX11410_GPIO_INTRB); + } else if (irqs[1] > 0) { + st->irq = irqs[1]; + ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(1), + MAX11410_GPIO_INTRB); + } else if (spi->irq > 0) { + return dev_err_probe(dev, -ENODEV, + "no interrupt name specified"); + } + + if (ret) + return ret; + + ret = regmap_set_bits(st->regmap, MAX11410_REG_CTRL, + MAX11410_CTRL_FORMAT_BIT); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &max11410_trigger_handler, + &max11410_buffer_ops); + if (ret) + return ret; + + if (st->irq > 0) { + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &max11410_trigger_ops; + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, st->irq, NULL, + &max11410_interrupt, + IRQF_ONESHOT, "max11410", + indio_dev); + if (ret) + return ret; + } + + ret = max11410_self_calibrate(st); + if (ret) + return dev_err_probe(dev, ret, + "cannot perform device self calibration\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id max11410_spi_of_id[] = { + { .compatible = "adi,max11410" }, + { } +}; +MODULE_DEVICE_TABLE(of, max11410_spi_of_id); + +static const struct spi_device_id max11410_id[] = { + { "max11410" }, + { } +}; +MODULE_DEVICE_TABLE(spi, max11410_id); + +static struct spi_driver max11410_driver = { + .driver = { + .name = "max11410", + .of_match_table = max11410_spi_of_id, + }, + .probe = max11410_probe, + .id_table = max11410_id, +}; +module_spi_driver(max11410_driver); + +MODULE_AUTHOR("David Jung "); +MODULE_AUTHOR("Ibrahim Tilki "); +MODULE_DESCRIPTION("Analog Devices MAX11410 ADC"); +MODULE_LICENSE("GPL"); -- GitLab From 089ec09f4973898c60c6781c448384bf828e7f45 Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Mon, 3 Oct 2022 13:59:02 +0300 Subject: [PATCH 0875/1480] dt-bindings: iio: adc: add adi,max11410.yaml Adding devicetree binding documentation for max11410 adc. Signed-off-by: Ibrahim Tilki Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221003105903.229-3-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/adi,max11410.yaml | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml b/Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml new file mode 100644 index 0000000000000..53f9feff137ba --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2022 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,max11410.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX11410 ADC device driver + +maintainers: + - Ibrahim Tilki + +description: | + Bindings for the Analog Devices MAX11410 ADC device. Datasheet can be + found here: + https://datasheets.maximintegrated.com/en/ds/MAX11410.pdf + +properties: + compatible: + enum: + - adi,max11410 + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + description: Name of the gpio pin of max11410 used for IRQ + minItems: 1 + items: + - enum: [gpio0, gpio1] + - const: gpio1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + avdd-supply: + description: Optional avdd supply. Used as reference when no explicit reference supplied. + + vref0p-supply: + description: vref0p supply can be used as reference for conversion. + + vref1p-supply: + description: vref1p supply can be used as reference for conversion. + + vref2p-supply: + description: vref2p supply can be used as reference for conversion. + + vref0n-supply: + description: vref0n supply can be used as reference for conversion. + + vref1n-supply: + description: vref1n supply can be used as reference for conversion. + + vref2n-supply: + description: vref2n supply can be used as reference for conversion. + + spi-max-frequency: + maximum: 8000000 + +patternProperties: + "^channel(@[0-9])?$": + $ref: adc.yaml + type: object + description: Represents the external channels which are connected to the ADC. + + properties: + reg: + description: The channel number in single-ended mode. + minimum: 0 + maximum: 9 + + adi,reference: + description: | + Select the reference source to use when converting on + the specific channel. Valid values are: + 0: VREF0P/VREF0N + 1: VREF1P/VREF1N + 2: VREF2P/VREF2N + 3: AVDD/AGND + 4: VREF0P/AGND + 5: VREF1P/AGND + 6: VREF2P/AGND + If this field is left empty, AVDD/AGND is selected. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6] + default: 3 + + adi,input-mode: + description: | + Select signal path of input channels. Valid values are: + 0: Buffered, low-power, unity-gain path (default) + 1: Bypass path + 2: PGA path + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + default: 0 + + diff-channels: true + + bipolar: true + + settling-time-us: true + + adi,buffered-vrefp: + description: Enable buffered mode for positive reference. + type: boolean + + adi,buffered-vrefn: + description: Enable buffered mode for negative reference. + type: boolean + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + reg = <0>; + compatible = "adi,max11410"; + spi-max-frequency = <8000000>; + + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "gpio1"; + + avdd-supply = <&adc_avdd>; + + vref1p-supply = <&adc_vref1p>; + vref1n-supply = <&adc_vref1n>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + }; + + channel@1 { + reg = <1>; + diff-channels = <2 3>; + adi,reference = <1>; + bipolar; + settling-time-us = <100000>; + }; + + channel@2 { + reg = <2>; + diff-channels = <7 9>; + adi,reference = <5>; + adi,input-mode = <2>; + settling-time-us = <50000>; + }; + }; + }; -- GitLab From 8d2caf8b98f17f44f76a002ced7c7ce6425652bc Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Mon, 3 Oct 2022 13:59:03 +0300 Subject: [PATCH 0876/1480] Documentation: ABI: testing: add max11410 doc Adding documentation for Analog Devices max11410 adc userspace sysfs. Signed-off-by: Ibrahim Tilki Link: https://lore.kernel.org/r/20221003105903.229-4-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-adc-max11410 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-max11410 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-max11410 b/Documentation/ABI/testing/sysfs-bus-iio-adc-max11410 new file mode 100644 index 0000000000000..2a53c6b373603 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-max11410 @@ -0,0 +1,13 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_filterY_notch_en +Date: September 2022 +KernelVersion: 6.0 +Contact: linux-iio@vger.kernel.org +Description: + Enable or disable a notch filter. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_filterY_notch_center +Date: September 2022 +KernelVersion: 6.0 +Contact: linux-iio@vger.kernel.org +Description: + Center frequency of the notch filter in Hz. -- GitLab From c1404d1b659fe3d7d13bdbd59e5161ab508dc101 Mon Sep 17 00:00:00 2001 From: ChiaEn Wu Date: Tue, 11 Oct 2022 12:05:45 +0800 Subject: [PATCH 0877/1480] iio: adc: mt6370: Add MediaTek MT6370 support MediaTek MT6370 is a SubPMIC consisting of a single cell battery charger with ADC monitoring, RGB LEDs, dual channel flashlight, WLED backlight driver, display bias voltage supply, one general purpose LDO, and the USB Type-C & PD controller complies with the latest USB Type-C and PD standards. Add support for the MT6370 ADC driver for system monitoring, including charger current, voltage, and temperature. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Andy Shevchenko Signed-off-by: ChiaEn Wu Link: https://lore.kernel.org/r/81ec58ae89030e48508d6810396de2679c40d26c.1665488982.git.chiaen_wu@richtek.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 12 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/mt6370-adc.c | 305 +++++++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 drivers/iio/adc/mt6370-adc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 544986fd456de..5386d862def9c 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -765,6 +765,18 @@ config MEDIATEK_MT6360_ADC is used in smartphones and tablets and supports a 11 channel general purpose ADC. +config MEDIATEK_MT6370_ADC + tristate "MediaTek MT6370 ADC driver" + depends on MFD_MT6370 + help + Say yes here to enable MediaTek MT6370 ADC support. + + This ADC driver provides 9 channels for system monitoring (charger + current, voltage, and temperature). + + This driver can also be built as a module. If so, the module + will be called "mt6370-adc". + config MEDIATEK_MT6577_AUXADC tristate "MediaTek AUXADC driver" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 4d803413425c4..1571e891828eb 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MCP3911) += mcp3911.o obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o +obj-$(CONFIG_MEDIATEK_MT6370_ADC) += mt6370-adc.o obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_MESON_SARADC) += meson_saradc.o diff --git a/drivers/iio/adc/mt6370-adc.c b/drivers/iio/adc/mt6370-adc.c new file mode 100644 index 0000000000000..bc62e5a9d50d1 --- /dev/null +++ b/drivers/iio/adc/mt6370-adc.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Richtek Technology Corp. + * + * Author: ChiaEn Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MT6370_REG_CHG_CTRL3 0x113 +#define MT6370_REG_CHG_CTRL7 0x117 +#define MT6370_REG_CHG_ADC 0x121 +#define MT6370_REG_ADC_DATA_H 0x14C + +#define MT6370_ADC_START_MASK BIT(0) +#define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4) +#define MT6370_AICR_ICHG_MASK GENMASK(7, 2) + +#define MT6370_AICR_100_mA 0x0 +#define MT6370_AICR_150_mA 0x1 +#define MT6370_AICR_200_mA 0x2 +#define MT6370_AICR_250_mA 0x3 +#define MT6370_AICR_300_mA 0x4 +#define MT6370_AICR_350_mA 0x5 + +#define MT6370_ICHG_100_mA 0x0 +#define MT6370_ICHG_200_mA 0x1 +#define MT6370_ICHG_300_mA 0x2 +#define MT6370_ICHG_400_mA 0x3 +#define MT6370_ICHG_500_mA 0x4 +#define MT6370_ICHG_600_mA 0x5 +#define MT6370_ICHG_700_mA 0x6 +#define MT6370_ICHG_800_mA 0x7 + +#define ADC_CONV_TIME_MS 35 +#define ADC_CONV_POLLING_TIME_US 1000 + +struct mt6370_adc_data { + struct device *dev; + struct regmap *regmap; + /* + * This mutex lock is for preventing the different ADC channels + * from being read at the same time. + */ + struct mutex adc_lock; +}; + +static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan, + unsigned long addr, int *val) +{ + unsigned int reg_val; + __be16 be_val; + int ret; + + mutex_lock(&priv->adc_lock); + + reg_val = MT6370_ADC_START_MASK | + FIELD_PREP(MT6370_ADC_IN_SEL_MASK, addr); + ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val); + if (ret) + goto adc_unlock; + + msleep(ADC_CONV_TIME_MS); + + ret = regmap_read_poll_timeout(priv->regmap, + MT6370_REG_CHG_ADC, reg_val, + !(reg_val & MT6370_ADC_START_MASK), + ADC_CONV_POLLING_TIME_US, + ADC_CONV_TIME_MS * MILLI * 3); + if (ret) { + dev_err(priv->dev, "Failed to read ADC register (%d)\n", ret); + goto adc_unlock; + } + + ret = regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H, + &be_val, sizeof(be_val)); + if (ret) + goto adc_unlock; + + *val = be16_to_cpu(be_val); + ret = IIO_VAL_INT; + +adc_unlock: + mutex_unlock(&priv->adc_lock); + + return ret; +} + +static int mt6370_adc_read_scale(struct mt6370_adc_data *priv, + int chan, int *val1, int *val2) +{ + unsigned int reg_val; + int ret; + + switch (chan) { + case MT6370_CHAN_VBAT: + case MT6370_CHAN_VSYS: + case MT6370_CHAN_CHG_VDDP: + *val1 = 5; + return IIO_VAL_INT; + case MT6370_CHAN_IBUS: + ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, ®_val); + if (ret) + return ret; + + reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); + switch (reg_val) { + case MT6370_AICR_100_mA: + case MT6370_AICR_150_mA: + case MT6370_AICR_200_mA: + case MT6370_AICR_250_mA: + case MT6370_AICR_300_mA: + case MT6370_AICR_350_mA: + *val1 = 3350; + break; + default: + *val1 = 5000; + break; + } + + *val2 = 100; + + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_IBAT: + ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, ®_val); + if (ret) + return ret; + + reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); + switch (reg_val) { + case MT6370_ICHG_100_mA: + case MT6370_ICHG_200_mA: + case MT6370_ICHG_300_mA: + case MT6370_ICHG_400_mA: + *val1 = 2375; + break; + case MT6370_ICHG_500_mA: + case MT6370_ICHG_600_mA: + case MT6370_ICHG_700_mA: + case MT6370_ICHG_800_mA: + *val1 = 2680; + break; + default: + *val1 = 5000; + break; + } + + *val2 = 100; + + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_VBUSDIV5: + *val1 = 25; + return IIO_VAL_INT; + case MT6370_CHAN_VBUSDIV2: + *val1 = 10; + return IIO_VAL_INT; + case MT6370_CHAN_TS_BAT: + *val1 = 25; + *val2 = 10000; + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_TEMP_JC: + *val1 = 2000; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int mt6370_adc_read_offset(struct mt6370_adc_data *priv, + int chan, int *val) +{ + *val = -20; + + return IIO_VAL_INT; +} + +static int mt6370_adc_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct mt6370_adc_data *priv = iio_priv(iio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return mt6370_adc_read_channel(priv, chan->channel, + chan->address, val); + case IIO_CHAN_INFO_SCALE: + return mt6370_adc_read_scale(priv, chan->channel, val, val2); + case IIO_CHAN_INFO_OFFSET: + return mt6370_adc_read_offset(priv, chan->channel, val); + default: + return -EINVAL; + } +} + +static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] = { + [MT6370_CHAN_VBUSDIV5] = "vbusdiv5", + [MT6370_CHAN_VBUSDIV2] = "vbusdiv2", + [MT6370_CHAN_VSYS] = "vsys", + [MT6370_CHAN_VBAT] = "vbat", + [MT6370_CHAN_TS_BAT] = "ts_bat", + [MT6370_CHAN_IBUS] = "ibus", + [MT6370_CHAN_IBAT] = "ibat", + [MT6370_CHAN_CHG_VDDP] = "chg_vddp", + [MT6370_CHAN_TEMP_JC] = "temp_jc", +}; + +static int mt6370_adc_read_label(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, char *label) +{ + return sysfs_emit(label, "%s\n", mt6370_channel_labels[chan->channel]); +} + +static const struct iio_info mt6370_adc_iio_info = { + .read_raw = mt6370_adc_read_raw, + .read_label = mt6370_adc_read_label, +}; + +#define MT6370_ADC_CHAN(_idx, _type, _addr, _extra_info) { \ + .type = _type, \ + .channel = MT6370_CHAN_##_idx, \ + .address = _addr, \ + .scan_index = MT6370_CHAN_##_idx, \ + .indexed = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + _extra_info, \ +} + +static const struct iio_chan_spec mt6370_adc_channels[] = { + MT6370_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE, 1, 0), + MT6370_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE, 2, 0), + MT6370_ADC_CHAN(VSYS, IIO_VOLTAGE, 3, 0), + MT6370_ADC_CHAN(VBAT, IIO_VOLTAGE, 4, 0), + MT6370_ADC_CHAN(TS_BAT, IIO_VOLTAGE, 6, 0), + MT6370_ADC_CHAN(IBUS, IIO_CURRENT, 8, 0), + MT6370_ADC_CHAN(IBAT, IIO_CURRENT, 9, 0), + MT6370_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE, 11, 0), + MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12, BIT(IIO_CHAN_INFO_OFFSET)), +}; + +static int mt6370_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mt6370_adc_data *priv; + struct iio_dev *indio_dev; + struct regmap *regmap; + int ret; + + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) + return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n"); + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + priv = iio_priv(indio_dev); + priv->dev = dev; + priv->regmap = regmap; + mutex_init(&priv->adc_lock); + + ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0); + if (ret) + return dev_err_probe(dev, ret, "Failed to reset ADC\n"); + + indio_dev->name = "mt6370-adc"; + indio_dev->info = &mt6370_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mt6370_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(mt6370_adc_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id mt6370_adc_of_id[] = { + { .compatible = "mediatek,mt6370-adc", }, + {} +}; +MODULE_DEVICE_TABLE(of, mt6370_adc_of_id); + +static struct platform_driver mt6370_adc_driver = { + .driver = { + .name = "mt6370-adc", + .of_match_table = mt6370_adc_of_id, + }, + .probe = mt6370_adc_probe, +}; +module_platform_driver(mt6370_adc_driver); + +MODULE_AUTHOR("ChiaEn Wu "); +MODULE_DESCRIPTION("MT6370 ADC Driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From cd83c5c10036a2a156d725725daf3409832c8a24 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 10 Oct 2022 13:07:26 +0200 Subject: [PATCH 0878/1480] iio: imu: st_lsm6dsx: introduce st_lsm6dsx_device_set_enable routine Introduce st_lsm6dsx_device_set_enable utility routine and remove duplicated code used to enable/disable sensors Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/e3fbe5d4a3bed41130908669f745f78c8505cf47.1665399959.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 +++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 14 +++----------- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 14 ++------------ 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6b57d47be69ea..d3a4e21bc1149 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -509,6 +509,17 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, return &hw->orientation; } +static inline int +st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) +{ + if (sensor->id == ST_LSM6DSX_ID_EXT0 || + sensor->id == ST_LSM6DSX_ID_EXT1 || + sensor->id == ST_LSM6DSX_ID_EXT2) + return st_lsm6dsx_shub_set_enable(sensor, enable); + + return st_lsm6dsx_sensor_set_enable(sensor, enable); +} + static const struct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_accel_ext_info[] = { IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index e49f2d120ed38..48fe6a45671bd 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -673,17 +673,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) goto out; } - if (sensor->id == ST_LSM6DSX_ID_EXT0 || - sensor->id == ST_LSM6DSX_ID_EXT1 || - sensor->id == ST_LSM6DSX_ID_EXT2) { - err = st_lsm6dsx_shub_set_enable(sensor, enable); - if (err < 0) - goto out; - } else { - err = st_lsm6dsx_sensor_set_enable(sensor, enable); - if (err < 0) - goto out; - } + err = st_lsm6dsx_device_set_enable(sensor, enable); + if (err < 0) + goto out; err = st_lsm6dsx_set_fifo_odr(sensor, enable); if (err < 0) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index f8bbb005718ed..6af2e905c1612 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2317,12 +2317,7 @@ static int st_lsm6dsx_suspend(struct device *dev) continue; } - if (sensor->id == ST_LSM6DSX_ID_EXT0 || - sensor->id == ST_LSM6DSX_ID_EXT1 || - sensor->id == ST_LSM6DSX_ID_EXT2) - err = st_lsm6dsx_shub_set_enable(sensor, false); - else - err = st_lsm6dsx_sensor_set_enable(sensor, false); + err = st_lsm6dsx_device_set_enable(sensor, false); if (err < 0) return err; @@ -2353,12 +2348,7 @@ static int st_lsm6dsx_resume(struct device *dev) if (!(hw->suspend_mask & BIT(sensor->id))) continue; - if (sensor->id == ST_LSM6DSX_ID_EXT0 || - sensor->id == ST_LSM6DSX_ID_EXT1 || - sensor->id == ST_LSM6DSX_ID_EXT2) - err = st_lsm6dsx_shub_set_enable(sensor, true); - else - err = st_lsm6dsx_sensor_set_enable(sensor, true); + err = st_lsm6dsx_device_set_enable(sensor, true); if (err < 0) return err; -- GitLab From 6cafcdb19ee4a0a073e4a8b0828698f8816c800c Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Wed, 12 Oct 2022 16:21:59 +0200 Subject: [PATCH 0879/1480] dt-bindings: iio: adc: stm32-adc: add stm32mp13 compatibles Add st,stm32mp13-adc-core and st,stm32mp13-adc compatibles to support STM32MPU13 SoC. On STM32MP13x, each ADC peripheral has a single ADC block. These ADC peripherals, ADC1 and ADC2, are fully independent. Main characteristics of STM32MP13x ADC: - One interrupt line per ADC - 6 to 12 bits resolution - 19 channels ADC2 instance supports two extra internal channels VDDCPU and VDDQ_DDR. Add "vddcpu" and "vddq_ddr" internal channels names to the reserved labels list. Signed-off-by: Olivier Moysan Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221012142205.13041-3-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/st,stm32-adc.yaml | 68 ++++++++++++++++++- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml index fa8da42cb1e6b..05265f381fde9 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml @@ -27,6 +27,7 @@ properties: - st,stm32f4-adc-core - st,stm32h7-adc-core - st,stm32mp1-adc-core + - st,stm32mp13-adc-core reg: maxItems: 1 @@ -37,6 +38,7 @@ properties: - stm32f4 and stm32h7 share a common ADC interrupt line. - stm32mp1 has two separate interrupt lines, one for each ADC within ADC block. + - stm32mp13 has an interrupt line per ADC block. minItems: 1 maxItems: 2 @@ -180,6 +182,33 @@ allOf: maximum: 36000000 default: 36000000 + - if: + properties: + compatible: + contains: + const: st,stm32mp13-adc-core + + then: + properties: + clocks: + minItems: 1 + maxItems: 2 + + clock-names: + items: + - const: bus + - const: adc + minItems: 1 + + interrupts: + items: + - description: ADC interrupt line + + st,max-clk-rate-hz: + minimum: 150000 + maximum: 75000000 + default: 75000000 + additionalProperties: false required: @@ -208,6 +237,7 @@ patternProperties: - st,stm32f4-adc - st,stm32h7-adc - st,stm32mp1-adc + - st,stm32mp13-adc reg: description: | @@ -229,7 +259,7 @@ patternProperties: interrupts: description: | IRQ Line for the ADC instance. Valid values are: - - 0 for adc@0 + - 0 for adc@0 (single adc for stm32mp13) - 1 for adc@100 - 2 for adc@200 (stm32f4 only) maxItems: 1 @@ -250,13 +280,14 @@ patternProperties: assigned-resolution-bits: description: | Resolution (bits) to use for conversions: - - can be 6, 8, 10 or 12 on stm32f4 + - can be 6, 8, 10 or 12 on stm32f4 and stm32mp13 - can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1 st,adc-channels: description: | List of single-ended channels muxed for this ADC. It can have up to: - 16 channels, numbered from 0 to 15 (for in0..in15) on stm32f4 + - 19 channels, numbered from 0 to 18 (for in0..in18) on stm32mp13. - 20 channels, numbered from 0 to 19 (for in0..in19) on stm32h7 and stm32mp1. $ref: /schemas/types.yaml#/definitions/uint32-array @@ -322,7 +353,7 @@ patternProperties: label: description: | Unique name to identify which channel this is. - Reserved label names "vddcore", "vrefint" and "vbat" + Reserved label names "vddcore", "vddcpu", "vddq_ddr", "vrefint" and "vbat" are used to identify internal channels with matching names. diff-channels: @@ -419,6 +450,37 @@ patternProperties: items: minimum: 40 + + - if: + properties: + compatible: + contains: + const: st,stm32mp13-adc + + then: + properties: + reg: + const: 0x0 + + interrupts: + const: 0 + + assigned-resolution-bits: + enum: [6, 8, 10, 12] + default: 12 + + st,adc-channels: + minItems: 1 + maxItems: 19 + items: + minimum: 0 + maximum: 18 + + st,min-sample-time-nsecs: + minItems: 1 + maxItems: 19 + items: + minimum: 40 additionalProperties: false required: -- GitLab From cf0fb80ae1675179620d964d629b43ca57219ced Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Wed, 12 Oct 2022 16:22:00 +0200 Subject: [PATCH 0880/1480] iio: adc: stm32-adc: add stm32mp13 support Add STM32 ADC support for STM32MP13x SOCs family. On STM32MP13x, each ADC peripheral has a single ADC block. These ADC peripherals, ADC1 and ADC2, are fully independent. This introduces changes in common registers handling. Some features such as boost mode, channel preselection and linear calibration are not supported by the STM32MP13x ADC. Add diversity management for these features. The STM32MP13x ADC introduces registers and bitfield variants on existing features such as calibration factors and internal channels. Add register diversity management. Add also support for new internal channels VDDCPU and VDDQ_DDR. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012142205.13041-4-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc-core.c | 30 ++++- drivers/iio/adc/stm32-adc-core.h | 30 +++++ drivers/iio/adc/stm32-adc.c | 210 +++++++++++++++++++++++++++---- 3 files changed, 239 insertions(+), 31 deletions(-) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 81d5db91c67bf..48f02dcc81c1b 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "stm32-adc-core.h" @@ -306,8 +307,8 @@ out: static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { .csr = STM32F4_ADC_CSR, .ccr = STM32F4_ADC_CCR, - .eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3}, - .ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3}, + .eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3 }, + .ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3 }, .ier = STM32F4_ADC_CR1, .eocie_msk = STM32F4_EOCIE, }; @@ -316,8 +317,18 @@ static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { static const struct stm32_adc_common_regs stm32h7_adc_common_regs = { .csr = STM32H7_ADC_CSR, .ccr = STM32H7_ADC_CCR, - .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV}, - .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV}, + .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV }, + .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV }, + .ier = STM32H7_ADC_IER, + .eocie_msk = STM32H7_EOCIE, +}; + +/* STM32MP13 common registers definitions */ +static const struct stm32_adc_common_regs stm32mp13_adc_common_regs = { + .csr = STM32H7_ADC_CSR, + .ccr = STM32H7_ADC_CCR, + .eoc_msk = { STM32H7_EOC_MST }, + .ovr_msk = { STM32H7_OVR_MST }, .ier = STM32H7_ADC_IER, .eocie_msk = STM32H7_EOCIE, }; @@ -868,6 +879,14 @@ static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { .num_irqs = 2, }; +static const struct stm32_adc_priv_cfg stm32mp13_adc_priv_cfg = { + .regs = &stm32mp13_adc_common_regs, + .clk_sel = stm32h7_adc_clk_sel, + .max_clk_rate_hz = 75 * HZ_PER_MHZ, + .ipid = STM32MP13_IPIDR_NUMBER, + .num_irqs = 1, +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc-core", @@ -878,6 +897,9 @@ static const struct of_device_id stm32_adc_of_match[] = { }, { .compatible = "st,stm32mp1-adc-core", .data = (void *)&stm32mp1_adc_priv_cfg + }, { + .compatible = "st,stm32mp13-adc-core", + .data = (void *)&stm32mp13_adc_priv_cfg }, { }, }; diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h index 2118ef63843d2..9d6dfa1c03faf 100644 --- a/drivers/iio/adc/stm32-adc-core.h +++ b/drivers/iio/adc/stm32-adc-core.h @@ -112,6 +112,11 @@ #define STM32MP1_ADC_IPDR 0x3F8 #define STM32MP1_ADC_SIDR 0x3FC +/* STM32MP13 - Registers for each ADC instance */ +#define STM32MP13_ADC_DIFSEL 0xB0 +#define STM32MP13_ADC_CALFACT 0xB4 +#define STM32MP13_ADC2_OR 0xC8 + /* STM32H7 - common registers for all ADC instances */ #define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) #define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) @@ -161,6 +166,9 @@ enum stm32h7_adc_dmngt { STM32H7_DMNGT_DMA_CIRC, /* DMA circular mode */ }; +/* STM32H7_ADC_DIFSEL - bit fields */ +#define STM32H7_DIFSEL_MASK GENMASK(19, 0) + /* STM32H7_ADC_CALFACT - bit fields */ #define STM32H7_CALFACT_D_SHIFT 16 #define STM32H7_CALFACT_D_MASK GENMASK(26, 16) @@ -210,7 +218,29 @@ enum stm32h7_adc_dmngt { /* STM32MP1_ADC_SIDR - bit fields */ #define STM32MP1_SIDR_MASK GENMASK(31, 0) +/* STM32MP13_ADC_CFGR specific bit fields */ +#define STM32MP13_DMAEN BIT(0) +#define STM32MP13_DMACFG BIT(1) +#define STM32MP13_DFSDMCFG BIT(2) +#define STM32MP13_RES_SHIFT 3 +#define STM32MP13_RES_MASK GENMASK(4, 3) + +/* STM32MP13_ADC_DIFSEL - bit fields */ +#define STM32MP13_DIFSEL_MASK GENMASK(18, 0) + +/* STM32MP13_ADC_CALFACT - bit fields */ +#define STM32MP13_CALFACT_D_SHIFT 16 +#define STM32MP13_CALFACT_D_MASK GENMASK(22, 16) +#define STM32MP13_CALFACT_S_SHIFT 0 +#define STM32MP13_CALFACT_S_MASK GENMASK(6, 0) + +/* STM32MP13_ADC2_OR - bit fields */ +#define STM32MP13_OP2 BIT(2) +#define STM32MP13_OP1 BIT(1) +#define STM32MP13_OP0 BIT(0) + #define STM32MP15_IPIDR_NUMBER 0x00110005 +#define STM32MP13_IPIDR_NUMBER 0x00110006 /** * struct stm32_adc_common - stm32 ADC driver common data (for all instances) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 3cda529f081db..d36c024526f29 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -82,6 +82,8 @@ enum stm32_adc_extsel { enum stm32_adc_int_ch { STM32_ADC_INT_CH_NONE = -1, STM32_ADC_INT_CH_VDDCORE, + STM32_ADC_INT_CH_VDDCPU, + STM32_ADC_INT_CH_VDDQ_DDR, STM32_ADC_INT_CH_VREFINT, STM32_ADC_INT_CH_VBAT, STM32_ADC_INT_CH_NB, @@ -99,6 +101,8 @@ struct stm32_adc_ic { static const struct stm32_adc_ic stm32_adc_ic[STM32_ADC_INT_CH_NB] = { { "vddcore", STM32_ADC_INT_CH_VDDCORE }, + { "vddcpu", STM32_ADC_INT_CH_VDDCPU }, + { "vddq_ddr", STM32_ADC_INT_CH_VDDQ_DDR }, { "vrefint", STM32_ADC_INT_CH_VREFINT }, { "vbat", STM32_ADC_INT_CH_VBAT }, }; @@ -160,9 +164,14 @@ struct stm32_adc_vrefint { * @exten: trigger control register & bitfield * @extsel: trigger selection register & bitfield * @res: resolution selection register & bitfield + * @difsel: differential mode selection register & bitfield + * @calfact_s: single-ended calibration factors register & bitfield + * @calfact_d: differential calibration factors register & bitfield * @smpr: smpr1 & smpr2 registers offset array * @smp_bits: smpr1 & smpr2 index and bitfields - * @or_vdd: option register & vddcore bitfield + * @or_vddcore: option register & vddcore bitfield + * @or_vddcpu: option register & vddcpu bitfield + * @or_vddq_ddr: option register & vddq_ddr bitfield * @ccr_vbat: common register & vbat bitfield * @ccr_vref: common register & vrefint bitfield */ @@ -176,9 +185,14 @@ struct stm32_adc_regspec { const struct stm32_adc_regs exten; const struct stm32_adc_regs extsel; const struct stm32_adc_regs res; + const struct stm32_adc_regs difsel; + const struct stm32_adc_regs calfact_s; + const struct stm32_adc_regs calfact_d; const u32 smpr[2]; const struct stm32_adc_regs *smp_bits; - const struct stm32_adc_regs or_vdd; + const struct stm32_adc_regs or_vddcore; + const struct stm32_adc_regs or_vddcpu; + const struct stm32_adc_regs or_vddq_ddr; const struct stm32_adc_regs ccr_vbat; const struct stm32_adc_regs ccr_vref; }; @@ -192,6 +206,9 @@ struct stm32_adc; * @trigs: external trigger sources * @clk_required: clock is required * @has_vregready: vregready status flag presence + * @has_boostmode: boost mode support flag + * @has_linearcal: linear calibration support flag + * @has_presel: channel preselection support flag * @prepare: optional prepare routine (power-up, enable) * @start_conv: routine to start conversions * @stop_conv: routine to stop conversions @@ -206,6 +223,9 @@ struct stm32_adc_cfg { struct stm32_adc_trig_info *trigs; bool clk_required; bool has_vregready; + bool has_boostmode; + bool has_linearcal; + bool has_presel; int (*prepare)(struct iio_dev *); void (*start_conv)(struct iio_dev *, bool dma); void (*stop_conv)(struct iio_dev *); @@ -312,6 +332,13 @@ static const struct stm32_adc_info stm32h7_adc_info = { .num_res = ARRAY_SIZE(stm32h7_adc_resolutions), }; +/* stm32mp13 can have up to 19 channels */ +static const struct stm32_adc_info stm32mp13_adc_info = { + .max_channels = 19, + .resolutions = stm32f4_adc_resolutions, + .num_res = ARRAY_SIZE(stm32f4_adc_resolutions), +}; + /* * stm32f4_sq - describe regular sequence registers * - L: sequence len (register & bit field) @@ -497,10 +524,45 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, + STM32H7_CALFACT_S_SHIFT }, + .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, + STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, }; +/* STM32MP13 programmable sampling time (ADC clock cycles, rounded down) */ +static const unsigned int stm32mp13_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { + 2, 6, 12, 24, 47, 92, 247, 640, +}; + +static const struct stm32_adc_regspec stm32mp13_adc_regspec = { + .dr = STM32H7_ADC_DR, + .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, + .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, + .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, + .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, + .sqr = stm32h7_sq, + .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, + .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, + STM32H7_EXTSEL_SHIFT }, + .res = { STM32H7_ADC_CFGR, STM32MP13_RES_MASK, STM32MP13_RES_SHIFT }, + .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK}, + .calfact_s = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_S_MASK, + STM32MP13_CALFACT_S_SHIFT }, + .calfact_d = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_D_MASK, + STM32MP13_CALFACT_D_SHIFT }, + .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, + .smp_bits = stm32h7_smp_bits, + .or_vddcore = { STM32MP13_ADC2_OR, STM32MP13_OP0 }, + .or_vddcpu = { STM32MP13_ADC2_OR, STM32MP13_OP1 }, + .or_vddq_ddr = { STM32MP13_ADC2_OR, STM32MP13_OP2 }, + .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, + .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, +}; + static const struct stm32_adc_regspec stm32mp1_adc_regspec = { .dr = STM32H7_ADC_DR, .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, @@ -512,9 +574,14 @@ static const struct stm32_adc_regspec stm32mp1_adc_regspec = { .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, + STM32H7_CALFACT_S_SHIFT }, + .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, + STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, - .or_vdd = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, + .or_vddcore = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, }; @@ -675,8 +742,18 @@ static void stm32_adc_int_ch_enable(struct iio_dev *indio_dev) switch (i) { case STM32_ADC_INT_CH_VDDCORE: dev_dbg(&indio_dev->dev, "Enable VDDCore\n"); - stm32_adc_set_bits(adc, adc->cfg->regs->or_vdd.reg, - adc->cfg->regs->or_vdd.mask); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcore.reg, + adc->cfg->regs->or_vddcore.mask); + break; + case STM32_ADC_INT_CH_VDDCPU: + dev_dbg(&indio_dev->dev, "Enable VDDCPU\n"); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcpu.reg, + adc->cfg->regs->or_vddcpu.mask); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + dev_dbg(&indio_dev->dev, "Enable VDDQ_DDR\n"); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddq_ddr.reg, + adc->cfg->regs->or_vddq_ddr.mask); break; case STM32_ADC_INT_CH_VREFINT: dev_dbg(&indio_dev->dev, "Enable VREFInt\n"); @@ -702,8 +779,16 @@ static void stm32_adc_int_ch_disable(struct stm32_adc *adc) switch (i) { case STM32_ADC_INT_CH_VDDCORE: - stm32_adc_clr_bits(adc, adc->cfg->regs->or_vdd.reg, - adc->cfg->regs->or_vdd.mask); + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcore.reg, + adc->cfg->regs->or_vddcore.mask); + break; + case STM32_ADC_INT_CH_VDDCPU: + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcpu.reg, + adc->cfg->regs->or_vddcpu.mask); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddq_ddr.reg, + adc->cfg->regs->or_vddq_ddr.mask); break; case STM32_ADC_INT_CH_VREFINT: stm32_adc_clr_bits_common(adc, adc->cfg->regs->ccr_vref.reg, @@ -801,6 +886,7 @@ static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev) if (ret) dev_warn(&indio_dev->dev, "stop failed\n"); + /* STM32H7_DMNGT_MASK covers STM32MP13_DMAEN & STM32MP13_DMACFG */ stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK); } @@ -811,6 +897,17 @@ static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); } +static void stm32mp13_adc_start_conv(struct iio_dev *indio_dev, bool dma) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + + if (dma) + stm32_adc_set_bits(adc, STM32H7_ADC_CFGR, + STM32MP13_DMAEN | STM32MP13_DMACFG); + + stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART); +} + static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); @@ -821,7 +918,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADVREGEN); - if (adc->common->rate > STM32H7_BOOST_CLKRATE) + if (adc->cfg->has_boostmode && + adc->common->rate > STM32H7_BOOST_CLKRATE) stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); /* Wait for startup time */ @@ -843,7 +941,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) static void stm32h7_adc_enter_pwr_down(struct stm32_adc *adc) { - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); + if (adc->cfg->has_boostmode) + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */ stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); @@ -901,6 +1000,9 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; + if (!adc->cfg->has_linearcal) + goto skip_linearcal; + /* Read linearity calibration */ lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -923,12 +1025,13 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) lincalrdyw_mask >>= 1; } +skip_linearcal: /* Read offset calibration */ - val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT); - adc->cal.calfact_s = (val & STM32H7_CALFACT_S_MASK); - adc->cal.calfact_s >>= STM32H7_CALFACT_S_SHIFT; - adc->cal.calfact_d = (val & STM32H7_CALFACT_D_MASK); - adc->cal.calfact_d >>= STM32H7_CALFACT_D_SHIFT; + val = stm32_adc_readl(adc, adc->cfg->regs->calfact_s.reg); + adc->cal.calfact_s = (val & adc->cfg->regs->calfact_s.mask); + adc->cal.calfact_s >>= adc->cfg->regs->calfact_s.shift; + adc->cal.calfact_d = (val & adc->cfg->regs->calfact_d.mask); + adc->cal.calfact_d >>= adc->cfg->regs->calfact_d.shift; adc->cal.calibrated = true; return 0; @@ -945,9 +1048,12 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - val = (adc->cal.calfact_s << STM32H7_CALFACT_S_SHIFT) | - (adc->cal.calfact_d << STM32H7_CALFACT_D_SHIFT); - stm32_adc_writel(adc, STM32H7_ADC_CALFACT, val); + val = (adc->cal.calfact_s << adc->cfg->regs->calfact_s.shift) | + (adc->cal.calfact_d << adc->cfg->regs->calfact_d.shift); + stm32_adc_writel(adc, adc->cfg->regs->calfact_s.reg, val); + + if (!adc->cfg->has_linearcal) + return 0; lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -1016,11 +1122,14 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); int ret; + u32 msk = STM32H7_ADCALDIF; u32 val; if (adc->cal.calibrated) return true; + if (adc->cfg->has_linearcal) + msk |= STM32H7_ADCALLIN; /* ADC must be disabled for calibration */ stm32h7_adc_disable(indio_dev); @@ -1029,8 +1138,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) * - Offset calibration for single ended inputs * - No linearity calibration (do it later, before reading it) */ - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF); - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALLIN); + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk); /* Start calibration, then wait for completion */ stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); @@ -1048,8 +1156,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) * - Linearity calibration (needs to be done only once for single/diff) * will run simultaneously with offset calibration. */ - stm32_adc_set_bits(adc, STM32H7_ADC_CR, - STM32H7_ADCALDIF | STM32H7_ADCALLIN); + stm32_adc_set_bits(adc, STM32H7_ADC_CR, msk); stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, !(val & STM32H7_ADCAL), 100, @@ -1060,8 +1167,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) } out: - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, - STM32H7_ADCALDIF | STM32H7_ADCALLIN); + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk); return ret; } @@ -1093,7 +1199,7 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) stm32_adc_int_ch_enable(indio_dev); - stm32_adc_writel(adc, STM32H7_ADC_DIFSEL, adc->difsel); + stm32_adc_writel(adc, adc->cfg->regs->difsel.reg, adc->difsel); ret = stm32h7_adc_enable(indio_dev); if (ret) @@ -1107,7 +1213,8 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) if (ret) goto disable; - stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); return 0; @@ -1125,7 +1232,8 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); - stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); stm32h7_adc_disable(indio_dev); stm32_adc_int_ch_disable(adc); stm32h7_adc_enter_pwr_down(adc); @@ -1857,7 +1965,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, adc->pcsel |= BIT(chan->channel); if (differential) { /* pre-build diff channels mask */ - adc->difsel |= BIT(chan->channel); + adc->difsel |= BIT(chan->channel) & adc->cfg->regs->difsel.mask; /* Also add negative input to pre-selected channels */ adc->pcsel |= BIT(chan->channel2); } @@ -1998,6 +2106,35 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { + /* Check internal channel availability */ + switch (i) { + case STM32_ADC_INT_CH_VDDCORE: + if (!adc->cfg->regs->or_vddcore.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VDDCPU: + if (!adc->cfg->regs->or_vddcpu.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + if (!adc->cfg->regs->or_vddq_ddr.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VREFINT: + if (!adc->cfg->regs->ccr_vref.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VBAT: + if (!adc->cfg->regs->ccr_vbat.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + } + if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) { adc->int_ch[i] = chan; break; @@ -2435,6 +2572,9 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { .regs = &stm32h7_adc_regspec, .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, @@ -2448,6 +2588,9 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, .has_vregready = true, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, @@ -2457,10 +2600,23 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .ts_vrefint_ns = 4300, }; +static const struct stm32_adc_cfg stm32mp13_adc_cfg = { + .regs = &stm32mp13_adc_regspec, + .adc_info = &stm32mp13_adc_info, + .trigs = stm32h7_adc_trigs, + .start_conv = stm32mp13_adc_start_conv, + .stop_conv = stm32h7_adc_stop_conv, + .prepare = stm32h7_adc_prepare, + .unprepare = stm32h7_adc_unprepare, + .smp_cycles = stm32mp13_adc_smp_cycles, + .irq_clear = stm32h7_adc_irq_clear, +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc", .data = (void *)&stm32f4_adc_cfg }, { .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg }, { .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg }, + { .compatible = "st,stm32mp13-adc", .data = (void *)&stm32mp13_adc_cfg }, {}, }; MODULE_DEVICE_TABLE(of, stm32_adc_of_match); -- GitLab From 7cb2303dd02487cc18bc9ff0fc1338e8c78ae846 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Wed, 12 Oct 2022 16:22:01 +0200 Subject: [PATCH 0881/1480] iio: adc: stm32: manage min sampling time on all internal channels Force minimum sampling time for all internal channels according to datasheet requirement. This value can be increased through DT st,min-sample-time-ns property. Signed-off-by: Olivier Moysan Reviewed-by: Andy Shevchenko Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221012142205.13041-5-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index d36c024526f29..8d03d21a33d60 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -215,7 +215,7 @@ struct stm32_adc; * @unprepare: optional unprepare routine (disable, power-down) * @irq_clear: routine to clear irqs * @smp_cycles: programmable sampling time (ADC clock cycles) - * @ts_vrefint_ns: vrefint minimum sampling time in ns + * @ts_int_ch: pointer to array of internal channels minimum sampling time in ns */ struct stm32_adc_cfg { const struct stm32_adc_regspec *regs; @@ -232,7 +232,7 @@ struct stm32_adc_cfg { void (*unprepare)(struct iio_dev *); void (*irq_clear)(struct iio_dev *indio_dev, u32 msk); const unsigned int *smp_cycles; - const unsigned int ts_vrefint_ns; + const unsigned int *ts_int_ch; }; /** @@ -1910,14 +1910,15 @@ static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns) { const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel]; u32 period_ns, shift = smpr->shift, mask = smpr->mask; - unsigned int smp, r = smpr->reg; + unsigned int i, smp, r = smpr->reg; /* - * For vrefint channel, ensure that the sampling time cannot + * For internal channels, ensure that the sampling time cannot * be lower than the one specified in the datasheet */ - if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT]) - smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns); + for (i = 0; i < STM32_ADC_INT_CH_NB; i++) + if (channel == adc->int_ch[i] && adc->int_ch[i] != STM32_ADC_INT_CH_NONE) + smp_ns = max(smp_ns, adc->cfg->ts_int_ch[i]); /* Determine sampling time (ADC clock cycles) */ period_ns = NSEC_PER_SEC / adc->common->rate; @@ -2568,6 +2569,9 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = { .irq_clear = stm32f4_adc_irq_clear, }; +const unsigned int stm32_adc_min_ts_h7[] = { 0, 0, 0, 4300, 9000 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_h7) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32h7_adc_cfg = { .regs = &stm32h7_adc_regspec, .adc_info = &stm32h7_adc_info, @@ -2581,8 +2585,12 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32h7_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, + .ts_int_ch = stm32_adc_min_ts_h7, }; +const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp1) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .regs = &stm32mp1_adc_regspec, .adc_info = &stm32h7_adc_info, @@ -2597,9 +2605,12 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32h7_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, - .ts_vrefint_ns = 4300, + .ts_int_ch = stm32_adc_min_ts_mp1, }; +const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp13) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32mp13_adc_cfg = { .regs = &stm32mp13_adc_regspec, .adc_info = &stm32mp13_adc_info, @@ -2610,6 +2621,7 @@ static const struct stm32_adc_cfg stm32mp13_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32mp13_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, + .ts_int_ch = stm32_adc_min_ts_mp13, }; static const struct of_device_id stm32_adc_of_match[] = { -- GitLab From 0a8565425afd8ba0e1a0ea73e21da119ee6dacea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 12 Oct 2022 17:16:17 +0200 Subject: [PATCH 0882/1480] iio: core: introduce iio_device_{claim|release}_buffer_mode() APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These APIs are analogous to iio_device_claim_direct_mode() and iio_device_release_direct_mode() but, as the name suggests, with the logic flipped. While this looks odd enough, it will have at least two users (in following changes) and it will be important to move the IIO mlock to the private struct. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 38 +++++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 151ff39933548..b2b7bd27adc77 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -2083,6 +2083,44 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); +/** + * iio_device_claim_buffer_mode - Keep device in buffer mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in buffer mode it is guaranteed to stay + * that way until iio_device_release_buffer_mode() is called. + * + * Use with iio_device_release_buffer_mode(). + * + * Returns: 0 on success, -EBUSY on failure. + */ +int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) +{ + mutex_lock(&indio_dev->mlock); + + if (iio_buffer_enabled(indio_dev)) + return 0; + + mutex_unlock(&indio_dev->mlock); + return -EBUSY; +} +EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); + +/** + * iio_device_release_buffer_mode - releases claim on buffer mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in buffer mode. + * + * Use with iio_device_claim_buffer_mode(). + */ +void iio_device_release_buffer_mode(struct iio_dev *indio_dev) +{ + mutex_unlock(&indio_dev->mlock); +} +EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); + /** * iio_device_get_current_mode() - helper function providing read-only access to * the opaque @currentmode variable diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index f0ec8a5e5a7a9..9d3bd6379eb87 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -629,6 +629,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); int iio_device_claim_direct_mode(struct iio_dev *indio_dev); void iio_device_release_direct_mode(struct iio_dev *indio_dev); +int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); +void iio_device_release_buffer_mode(struct iio_dev *indio_dev); extern struct bus_type iio_bus_type; -- GitLab From 1555790c86286933dc674fffe9c1104250d093ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 12 Oct 2022 17:16:18 +0200 Subject: [PATCH 0883/1480] iio: health: max30100: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern used in this device does not quite fit in the iio_device_claim_direct_mode() typical usage. In this case, iio_buffer_enabled() was being used not to prevent the raw access but to allow it. Hence, let's make use of the new iio_device_claim_buffer_mode() API to make sure we stay in buffered mode during the complete read. Note that we are shadowing the error code returned by iio_device_claim_buffer_mode() so that we keep the original one (-EAGAIN). The reason is that some userspace stack might already be relying on this particular code so that we are not taking chances and leave it alone. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221012151620.1725215-3-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30100.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 2cca5e0519f89..3aa5d037a1c35 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -387,18 +387,21 @@ static int max30100_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired while engine * is running */ - mutex_lock(&indio_dev->mlock); - - if (!iio_buffer_enabled(indio_dev)) + if (iio_device_claim_buffer_mode(indio_dev)) { + /* + * Replacing -EBUSY or other error code + * returned by iio_device_claim_buffer_mode() + * because user space may rely on the current + * one. + */ ret = -EAGAIN; - else { + } else { ret = max30100_get_temp(data, val); if (!ret) ret = IIO_VAL_INT; + iio_device_release_buffer_mode(indio_dev); } - - mutex_unlock(&indio_dev->mlock); break; case IIO_CHAN_INFO_SCALE: *val = 1; /* 0.0625 */ -- GitLab From 6b701cda3632c9cffaea6f79c5fe638800c8f7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 12 Oct 2022 17:16:19 +0200 Subject: [PATCH 0884/1480] iio: health: max30102: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern used in this device does not quite fit in the iio_device_claim_direct_mode() typical usage. In this case, we want to know if we are in buffered mode or not to know if the device is powered (buffer mode) or not. And depending on that max30102_get_temp() will power on the device if needed. Hence, in order to keep the same functionality, we try to: 1. Claim Buffered mode; 2: If 1) succeeds call max30102_get_temp() without powering on the device; 3: Release Buffered mode; 4: If 1) fails, Claim Direct mode; 5: If 4) succeeds call max30102_get_temp() with powering on the device; 6: Release Direct mode; 7: If 4) fails, goto to 1) and try again. This dance between buffered and direct mode is not particularly pretty (as well as the loop introduced by the goto statement) but it does allow us to get rid of the mlock usage while keeping the same behavior. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-4-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30102.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 437298a29f2d3..66df4aaa31a7b 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -477,12 +477,23 @@ static int max30102_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired when not in * shutdown; leave shutdown briefly when buffer not running */ - mutex_lock(&indio_dev->mlock); - if (!iio_buffer_enabled(indio_dev)) +any_mode_retry: + if (iio_device_claim_buffer_mode(indio_dev)) { + /* + * This one is a *bit* hacky. If we cannot claim buffer + * mode, then try direct mode so that we make sure + * things cannot concurrently change. And we just keep + * trying until we get one of the modes... + */ + if (iio_device_claim_direct_mode(indio_dev)) + goto any_mode_retry; + ret = max30102_get_temp(data, val, true); - else + iio_device_release_direct_mode(indio_dev); + } else { ret = max30102_get_temp(data, val, false); - mutex_unlock(&indio_dev->mlock); + iio_device_release_buffer_mode(indio_dev); + } if (ret) return ret; -- GitLab From 16afe125b53f88b855d2713c8ba253d905dcf3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Wed, 12 Oct 2022 17:16:20 +0200 Subject: [PATCH 0885/1480] iio: core: move 'mlock' to 'struct iio_dev_opaque' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that there are no more users accessing 'mlock' directly, we can move it to the iio_dev private structure. Hence, it's now explicit that new driver's should not directly use this lock. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-5-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/TODO | 3 --- drivers/iio/industrialio-buffer.c | 29 +++++++++++++++++------------ drivers/iio/industrialio-core.c | 26 +++++++++++++++----------- drivers/iio/industrialio-event.c | 4 ++-- drivers/iio/industrialio-trigger.c | 12 ++++++------ include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 3 --- 7 files changed, 42 insertions(+), 37 deletions(-) diff --git a/drivers/iio/TODO b/drivers/iio/TODO index 7d7326b7085a2..2ace27d1ac62a 100644 --- a/drivers/iio/TODO +++ b/drivers/iio/TODO @@ -7,9 +7,6 @@ tree - ABI Documentation - Audit driviers/iio/staging/Documentation -- Replace iio_dev->mlock by either a local lock or use -iio_claim_direct.(Requires analysis of the purpose of the lock.) - - Converting drivers from device tree centric to more generic property handlers. diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 228598b82a2f3..9cd7db549fcbc 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -507,13 +507,14 @@ static ssize_t iio_scan_el_store(struct device *dev, int ret; bool state; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_buffer *buffer = this_attr->buffer; ret = kstrtobool(buf, &state); if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; goto error_ret; @@ -532,7 +533,7 @@ static ssize_t iio_scan_el_store(struct device *dev, } error_ret: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret < 0 ? ret : len; @@ -554,6 +555,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool state; @@ -561,14 +563,14 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; goto error_ret; } buffer->scan_timestamp = state; error_ret: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } @@ -642,6 +644,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; unsigned int val; int ret; @@ -653,7 +656,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, if (val == buffer->length) return len; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; } else { @@ -665,7 +668,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, if (buffer->length && buffer->length < buffer->watermark) buffer->watermark = buffer->length; out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } @@ -1256,7 +1259,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, return -EINVAL; mutex_lock(&iio_dev_opaque->info_exist_lock); - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (insert_buffer && iio_buffer_is_active(insert_buffer)) insert_buffer = NULL; @@ -1277,7 +1280,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, ret = __iio_update_buffers(indio_dev, insert_buffer, remove_buffer); out_unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; @@ -1296,6 +1299,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, int ret; bool requested_state; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool inlist; @@ -1303,7 +1307,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); /* Find out if it is in the list */ inlist = iio_buffer_is_active(buffer); @@ -1317,7 +1321,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, ret = __iio_update_buffers(indio_dev, NULL, buffer); done: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return (ret < 0) ? ret : len; } @@ -1334,6 +1338,7 @@ static ssize_t watermark_store(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; unsigned int val; int ret; @@ -1344,7 +1349,7 @@ static ssize_t watermark_store(struct device *dev, if (!val) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (val > buffer->length) { ret = -EINVAL; @@ -1358,7 +1363,7 @@ static ssize_t watermark_store(struct device *dev, buffer->watermark = val; out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b2b7bd27adc77..52e690f031cb8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -285,16 +285,16 @@ int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); const struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; - ret = mutex_lock_interruptible(&indio_dev->mlock); + ret = mutex_lock_interruptible(&iio_dev_opaque->mlock); if (ret) return ret; if ((ev_int && iio_event_enabled(ev_int)) || iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } iio_dev_opaque->clock_id = clock_id; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return 0; } @@ -1674,7 +1674,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) indio_dev->dev.type = &iio_device_type; indio_dev->dev.bus = &iio_bus_type; device_initialize(&indio_dev->dev); - mutex_init(&indio_dev->mlock); + mutex_init(&iio_dev_opaque->mlock); mutex_init(&iio_dev_opaque->info_exist_lock); INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); @@ -1696,7 +1696,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); lockdep_register_key(&iio_dev_opaque->mlock_key); - lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key); + lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); return indio_dev; } @@ -2058,10 +2058,12 @@ EXPORT_SYMBOL_GPL(__devm_iio_device_register); */ int iio_device_claim_direct_mode(struct iio_dev *indio_dev) { - mutex_lock(&indio_dev->mlock); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } return 0; @@ -2079,7 +2081,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_direct_mode); */ void iio_device_release_direct_mode(struct iio_dev *indio_dev) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); } EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); @@ -2096,12 +2098,14 @@ EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); */ int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) { - mutex_lock(&indio_dev->mlock); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_enabled(indio_dev)) return 0; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); @@ -2117,7 +2121,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); */ void iio_device_release_buffer_mode(struct iio_dev *indio_dev) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); } EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 3d78da2531a9a..1a26393a7c0cf 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -198,7 +198,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev) if (ev_int == NULL) return -ENODEV; - fd = mutex_lock_interruptible(&indio_dev->mlock); + fd = mutex_lock_interruptible(&iio_dev_opaque->mlock); if (fd) return fd; @@ -219,7 +219,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev) } unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return fd; } diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 6885a186fe27a..a2f3cc2f65efb 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -120,12 +120,12 @@ int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *tri return -EINVAL; iio_dev_opaque = to_iio_dev_opaque(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); WARN_ON(iio_dev_opaque->trig_readonly); indio_dev->trig = iio_trigger_get(trig); iio_dev_opaque->trig_readonly = true; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return 0; } @@ -438,16 +438,16 @@ static ssize_t current_trigger_store(struct device *dev, struct iio_trigger *trig; int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } if (iio_dev_opaque->trig_readonly) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EPERM; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); trig = iio_trigger_acquire_by_name(buf); if (oldtrig == trig) { diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index d1f8b30a7c8b7..5aec3945555bf 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -11,6 +11,7 @@ * checked by device drivers but should be considered * read-only as this is a core internal bit * @driver_module: used to make it harder to undercut users + * @mlock: lock used to prevent simultaneous device state changes * @mlock_key: lockdep class for iio_dev lock * @info_exist_lock: lock to prevent use during removal * @trig_readonly: mark the current trigger immutable @@ -43,6 +44,7 @@ struct iio_dev_opaque { int currentmode; int id; struct module *driver_module; + struct mutex mlock; struct lock_class_key mlock_key; struct mutex info_exist_lock; bool trig_readonly; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 9d3bd6379eb87..8e0afaaa3f752 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -548,8 +548,6 @@ struct iio_buffer_setup_ops { * and owner * @buffer: [DRIVER] any buffer present * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux - * @mlock: [INTERN] lock used to prevent simultaneous device state - * changes * @available_scan_masks: [DRIVER] optional array of allowed bitmasks * @masklength: [INTERN] the length of the mask established from * channels @@ -574,7 +572,6 @@ struct iio_dev { struct iio_buffer *buffer; int scan_bytes; - struct mutex mlock; const unsigned long *available_scan_masks; unsigned masklength; -- GitLab From 0c3a333524a3e5ba4b6c7b2638faef8420cfdb2a Mon Sep 17 00:00:00 2001 From: Rajat Khandelwal Date: Mon, 10 Oct 2022 23:07:20 +0530 Subject: [PATCH 0886/1480] iio: pressure: mpl115: Implementing low power mode by shutdown gpio MPL115 supports shutdown gpio which can be used to set the state to low power mode. Power from all internal circuits and registers is removed. This is done by pulling the SHDN pin to low. This patch enables runtime PM on MPL115 to increase power savings. According to spec., a wakeup time period of ~5 ms exists between waking up and actually communicating with the device. This is implemented using sleep delay. Signed-off-by: Rajat Khandelwal Link: https://lore.kernel.org/r/20221010173720.568916-1-rajat.khandelwal@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl115.c | 62 ++++++++++++++++++++++++++++++- drivers/iio/pressure/mpl115.h | 5 +++ drivers/iio/pressure/mpl115_i2c.c | 1 + drivers/iio/pressure/mpl115_spi.c | 1 + 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c index 5bf5b9abe6f1a..02ea38c8a3e43 100644 --- a/drivers/iio/pressure/mpl115.c +++ b/drivers/iio/pressure/mpl115.c @@ -4,12 +4,13 @@ * * Copyright (c) 2014 Peter Meerwald * - * TODO: shutdown pin + * TODO: synchronization with system suspend */ #include #include #include +#include #include "mpl115.h" @@ -27,6 +28,7 @@ struct mpl115_data { s16 a0; s16 b1, b2; s16 c12; + struct gpio_desc *shutdown; const struct mpl115_ops *ops; }; @@ -102,16 +104,24 @@ static int mpl115_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_PROCESSED: + pm_runtime_get_sync(data->dev); ret = mpl115_comp_pressure(data, val, val2); if (ret < 0) return ret; + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_RAW: + pm_runtime_get_sync(data->dev); /* temperature -5.35 C / LSB, 472 LSB is 25 C */ ret = mpl115_read_temp(data); if (ret < 0) return ret; + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); *val = ret >> 6; + return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: *val = -605; @@ -168,6 +178,8 @@ int mpl115_probe(struct device *dev, const char *name, if (ret) return ret; + dev_set_drvdata(dev, indio_dev); + ret = data->ops->read(data->dev, MPL115_A0); if (ret < 0) return ret; @@ -185,10 +197,58 @@ int mpl115_probe(struct device *dev, const char *name, return ret; data->c12 = ret; + data->shutdown = devm_gpiod_get_optional(dev, "shutdown", + GPIOD_OUT_LOW); + if (IS_ERR(data->shutdown)) + return dev_err_probe(dev, PTR_ERR(data->shutdown), + "cannot get shutdown gpio\n"); + + if (data->shutdown) { + /* Enable runtime PM */ + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + /* + * As the device takes 3 ms to come up with a fresh + * reading after power-on and 5 ms to actually power-on, + * do not shut it down unnecessarily. Set autosuspend to + * 2000 ms. + */ + pm_runtime_set_autosuspend_delay(dev, 2000); + pm_runtime_use_autosuspend(dev); + pm_runtime_put(dev); + + dev_dbg(dev, "low-power mode enabled"); + } else + dev_dbg(dev, "low-power mode disabled"); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(mpl115_probe, IIO_MPL115); +static int mpl115_runtime_suspend(struct device *dev) +{ + struct mpl115_data *data = iio_priv(dev_get_drvdata(dev)); + + gpiod_set_value(data->shutdown, 1); + + return 0; +} + +static int mpl115_runtime_resume(struct device *dev) +{ + struct mpl115_data *data = iio_priv(dev_get_drvdata(dev)); + + gpiod_set_value(data->shutdown, 0); + usleep_range(5000, 6000); + + return 0; +} + +EXPORT_NS_RUNTIME_DEV_PM_OPS(mpl115_dev_pm_ops, mpl115_runtime_suspend, + mpl115_runtime_resume, NULL, IIO_MPL115); + MODULE_AUTHOR("Peter Meerwald "); MODULE_DESCRIPTION("Freescale MPL115 pressure/temperature driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/mpl115.h b/drivers/iio/pressure/mpl115.h index 57d55eb8e6617..78a0068a17bbc 100644 --- a/drivers/iio/pressure/mpl115.h +++ b/drivers/iio/pressure/mpl115.h @@ -6,6 +6,8 @@ * Copyright (c) 2016 Akinobu Mita */ +#include + #ifndef _MPL115_H_ #define _MPL115_H_ @@ -18,4 +20,7 @@ struct mpl115_ops { int mpl115_probe(struct device *dev, const char *name, const struct mpl115_ops *ops); +/*PM ops */ +extern const struct dev_pm_ops mpl115_dev_pm_ops; + #endif diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index 099ab1c6832c5..555bda1146fb9 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -53,6 +53,7 @@ MODULE_DEVICE_TABLE(i2c, mpl115_i2c_id); static struct i2c_driver mpl115_i2c_driver = { .driver = { .name = "mpl115", + .pm = pm_ptr(&mpl115_dev_pm_ops), }, .probe = mpl115_i2c_probe, .id_table = mpl115_i2c_id, diff --git a/drivers/iio/pressure/mpl115_spi.c b/drivers/iio/pressure/mpl115_spi.c index 7feec87e2704e..58d218fd90dcb 100644 --- a/drivers/iio/pressure/mpl115_spi.c +++ b/drivers/iio/pressure/mpl115_spi.c @@ -92,6 +92,7 @@ MODULE_DEVICE_TABLE(spi, mpl115_spi_ids); static struct spi_driver mpl115_spi_driver = { .driver = { .name = "mpl115", + .pm = pm_ptr(&mpl115_dev_pm_ops), }, .probe = mpl115_spi_probe, .id_table = mpl115_spi_ids, -- GitLab From 687c8848c642c093c190bb182e4a6ac2ed86b4eb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:16 +0100 Subject: [PATCH 0887/1480] iio: accel: fxls8962af: Use new EXPORT_NS_GPL_DEV_PM_OPS() Using this macro allows the compiler to remove unused structures and callbacks if we are not building with CONFIG_PM* without needing __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Sean Nyekjaer -- Switched to Paul Cercueil's more flexible implementation fo the macro. Dropped Sean's Ack given new form of macro being used. Acked-by: Sean Nyekjaer Link: https://lore.kernel.org/r/20220925155719.3316280-3-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/fxls8962af-core.c | 16 +++++++--------- drivers/iio/accel/fxls8962af-i2c.c | 2 +- drivers/iio/accel/fxls8962af-spi.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index 8874d6d617253..bf259db281f59 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -1241,7 +1241,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) } EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF); -static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev) +static int fxls8962af_runtime_suspend(struct device *dev) { struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1255,14 +1255,14 @@ static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused fxls8962af_runtime_resume(struct device *dev) +static int fxls8962af_runtime_resume(struct device *dev) { struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev)); return fxls8962af_active(data); } -static int __maybe_unused fxls8962af_suspend(struct device *dev) +static int fxls8962af_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct fxls8962af_data *data = iio_priv(indio_dev); @@ -1283,7 +1283,7 @@ static int __maybe_unused fxls8962af_suspend(struct device *dev) return 0; } -static int __maybe_unused fxls8962af_resume(struct device *dev) +static int fxls8962af_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct fxls8962af_data *data = iio_priv(indio_dev); @@ -1300,12 +1300,10 @@ static int __maybe_unused fxls8962af_resume(struct device *dev) return 0; } -const struct dev_pm_ops fxls8962af_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume) - SET_RUNTIME_PM_OPS(fxls8962af_runtime_suspend, - fxls8962af_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(fxls8962af_pm_ops, IIO_FXLS8962AF) = { + SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume) + RUNTIME_PM_OPS(fxls8962af_runtime_suspend, fxls8962af_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS_GPL(fxls8962af_pm_ops, IIO_FXLS8962AF); MODULE_AUTHOR("Sean Nyekjaer "); MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer driver"); diff --git a/drivers/iio/accel/fxls8962af-i2c.c b/drivers/iio/accel/fxls8962af-i2c.c index 8fbadfea1620b..22640eaebac73 100644 --- a/drivers/iio/accel/fxls8962af-i2c.c +++ b/drivers/iio/accel/fxls8962af-i2c.c @@ -45,7 +45,7 @@ static struct i2c_driver fxls8962af_driver = { .driver = { .name = "fxls8962af_i2c", .of_match_table = fxls8962af_of_match, - .pm = &fxls8962af_pm_ops, + .pm = pm_ptr(&fxls8962af_pm_ops), }, .probe_new = fxls8962af_probe, .id_table = fxls8962af_id, diff --git a/drivers/iio/accel/fxls8962af-spi.c b/drivers/iio/accel/fxls8962af-spi.c index 885b3ab7fcb58..a0d192211839f 100644 --- a/drivers/iio/accel/fxls8962af-spi.c +++ b/drivers/iio/accel/fxls8962af-spi.c @@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(spi, fxls8962af_spi_id_table); static struct spi_driver fxls8962af_driver = { .driver = { .name = "fxls8962af_spi", - .pm = &fxls8962af_pm_ops, + .pm = pm_ptr(&fxls8962af_pm_ops), .of_match_table = fxls8962af_spi_of_match, }, .probe = fxls8962af_probe, -- GitLab From 02e082c433c65f06f4cb359688993377c1d7b6d1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:17 +0100 Subject: [PATCH 0888/1480] iio: gyro: fxas210002c: Move exports to IIO_FXAS210002C namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Rui Miguel Silva Signed-off-by: Jonathan Cameron -- Dropped Rui's tag on basis this is rather different from v1 due to the different macro implementation. v2: Switch to Paul's more flexible approach to EXPORT_NS_GPL_DEV_PM_OPS() Acked-by: Rui Miguel Silva Link: https://lore.kernel.org/r/20220925155719.3316280-4-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/fxas21002c_core.c | 21 ++++++++++----------- drivers/iio/gyro/fxas21002c_i2c.c | 3 ++- drivers/iio/gyro/fxas21002c_spi.c | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index a36d71d9e3ea9..3ea1d46130808 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -998,7 +998,7 @@ pm_disable: return ret; } -EXPORT_SYMBOL_GPL(fxas21002c_core_probe); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_probe, IIO_FXAS21002C); void fxas21002c_core_remove(struct device *dev) { @@ -1009,9 +1009,9 @@ void fxas21002c_core_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); } -EXPORT_SYMBOL_GPL(fxas21002c_core_remove); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_remove, IIO_FXAS21002C); -static int __maybe_unused fxas21002c_suspend(struct device *dev) +static int fxas21002c_suspend(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); @@ -1021,7 +1021,7 @@ static int __maybe_unused fxas21002c_suspend(struct device *dev) return 0; } -static int __maybe_unused fxas21002c_resume(struct device *dev) +static int fxas21002c_resume(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1033,26 +1033,25 @@ static int __maybe_unused fxas21002c_resume(struct device *dev) return fxas21002c_mode_set(data, data->prev_mode); } -static int __maybe_unused fxas21002c_runtime_suspend(struct device *dev) +static int fxas21002c_runtime_suspend(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); return fxas21002c_mode_set(data, FXAS21002C_MODE_READY); } -static int __maybe_unused fxas21002c_runtime_resume(struct device *dev) +static int fxas21002c_runtime_resume(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); return fxas21002c_mode_set(data, FXAS21002C_MODE_ACTIVE); } -const struct dev_pm_ops fxas21002c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fxas21002c_suspend, fxas21002c_resume) - SET_RUNTIME_PM_OPS(fxas21002c_runtime_suspend, - fxas21002c_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(fxas21002c_pm_ops, IIO_FXAS21002C) = { + SYSTEM_SLEEP_PM_OPS(fxas21002c_suspend, fxas21002c_resume) + RUNTIME_PM_OPS(fxas21002c_runtime_suspend, fxas21002c_runtime_resume, + NULL) }; -EXPORT_SYMBOL_GPL(fxas21002c_pm_ops); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/gyro/fxas21002c_i2c.c b/drivers/iio/gyro/fxas21002c_i2c.c index 13bb52c594d12..9e2d0f34a672e 100644 --- a/drivers/iio/gyro/fxas21002c_i2c.c +++ b/drivers/iio/gyro/fxas21002c_i2c.c @@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE(of, fxas21002c_i2c_of_match); static struct i2c_driver fxas21002c_i2c_driver = { .driver = { .name = "fxas21002c_i2c", - .pm = &fxas21002c_pm_ops, + .pm = pm_ptr(&fxas21002c_pm_ops), .of_match_table = fxas21002c_i2c_of_match, }, .probe_new = fxas21002c_i2c_probe, @@ -65,3 +65,4 @@ module_i2c_driver(fxas21002c_i2c_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C I2C Gyro driver"); +MODULE_IMPORT_NS(IIO_FXAS21002C); diff --git a/drivers/iio/gyro/fxas21002c_spi.c b/drivers/iio/gyro/fxas21002c_spi.c index c3ac169facf9b..4f633826547c2 100644 --- a/drivers/iio/gyro/fxas21002c_spi.c +++ b/drivers/iio/gyro/fxas21002c_spi.c @@ -54,7 +54,7 @@ MODULE_DEVICE_TABLE(of, fxas21002c_spi_of_match); static struct spi_driver fxas21002c_spi_driver = { .driver = { .name = "fxas21002c_spi", - .pm = &fxas21002c_pm_ops, + .pm = pm_ptr(&fxas21002c_pm_ops), .of_match_table = fxas21002c_spi_of_match, }, .probe = fxas21002c_spi_probe, @@ -66,3 +66,4 @@ module_spi_driver(fxas21002c_spi_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C SPI Gyro driver"); +MODULE_IMPORT_NS(IIO_FXAS21002C); -- GitLab From ef5a5ef29c8f70ca640d785b7173101417c78d24 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:18 +0100 Subject: [PATCH 0889/1480] iio: imu: inv_icm42600: Move exports to IIO_ICM42600 namespace As these exports are only relevant to core module and users in the bus specific modules, move them out of the main kernel namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Jean-Baptiste Maneyrol -- EXPORT_NS_GPL_DEV_PM_OPS() v2: Switch to Paul's more flexible version of the Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20220925155719.3316280-5-jic23@kernel.org Signed-off-by: Jonathan Cameron --- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 21 +++++++++---------- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 ++- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index ca85fccc98393..b63c5dab1a562 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -41,7 +41,7 @@ const struct regmap_config inv_icm42600_regmap_config = { .ranges = inv_icm42600_regmap_ranges, .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges), }; -EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600); struct inv_icm42600_hw { uint8_t whoami; @@ -660,13 +660,13 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev); } -EXPORT_SYMBOL_GPL(inv_icm42600_core_probe); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, IIO_ICM42600); /* * Suspend saves sensors state and turns everything off. * Check first if runtime suspend has not already done the job. */ -static int __maybe_unused inv_icm42600_suspend(struct device *dev) +static int inv_icm42600_suspend(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -706,7 +706,7 @@ out_unlock: * System resume gets the system back on and restores the sensors state. * Manually put runtime power management in system active state. */ -static int __maybe_unused inv_icm42600_resume(struct device *dev) +static int inv_icm42600_resume(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -739,7 +739,7 @@ out_unlock: } /* Runtime suspend will turn off sensors that are enabled by iio devices. */ -static int __maybe_unused inv_icm42600_runtime_suspend(struct device *dev) +static int inv_icm42600_runtime_suspend(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -761,7 +761,7 @@ error_unlock: } /* Sensors are enabled by iio devices, no need to turn them back on here. */ -static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) +static int inv_icm42600_runtime_resume(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -774,12 +774,11 @@ static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) return ret; } -const struct dev_pm_ops inv_icm42600_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) - SET_RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, - inv_icm42600_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = { + SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) + RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, + inv_icm42600_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index d4a692b838d0f..4f96989ddf4a1 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -93,7 +93,7 @@ static struct i2c_driver inv_icm42600_driver = { .driver = { .name = "inv-icm42600-i2c", .of_match_table = inv_icm42600_of_matches, - .pm = &inv_icm42600_pm_ops, + .pm = pm_ptr(&inv_icm42600_pm_ops), }, .probe_new = inv_icm42600_probe, }; @@ -102,3 +102,4 @@ module_i2c_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_ICM42600); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index e6305e5fa9756..486b46e531131 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -89,7 +89,7 @@ static struct spi_driver inv_icm42600_driver = { .driver = { .name = "inv-icm42600-spi", .of_match_table = inv_icm42600_of_matches, - .pm = &inv_icm42600_pm_ops, + .pm = pm_ptr(&inv_icm42600_pm_ops), }, .probe = inv_icm42600_probe, }; @@ -98,3 +98,4 @@ module_spi_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_ICM42600); -- GitLab From 62bfa12c87ac7468a69e81ea870eb68b0adabf37 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:19 +0100 Subject: [PATCH 0890/1480] iio: imu: inv_mpu: Move exports to IIO_MPU6050 namespace As these exports are only relevant to core module and users in the bus specific modules, move them out of the main kernel namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Jean-Baptiste Maneyrol Cc: Linus Walleij -- Dropped Linus' tag as the new patch is significantly different. v2: Switch to more flexible version of EXPORT* macro from Paul. Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20220925155719.3316280-6-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 17 ++++++++--------- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 3 ++- drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 86fbbe9040503..8a129120b73dd 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1653,9 +1653,9 @@ error_power_off: inv_mpu6050_set_power_itg(st, false); return result; } -EXPORT_SYMBOL_GPL(inv_mpu_core_probe); +EXPORT_SYMBOL_NS_GPL(inv_mpu_core_probe, IIO_MPU6050); -static int __maybe_unused inv_mpu_resume(struct device *dev) +static int inv_mpu_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct inv_mpu6050_state *st = iio_priv(indio_dev); @@ -1687,7 +1687,7 @@ out_unlock: return result; } -static int __maybe_unused inv_mpu_suspend(struct device *dev) +static int inv_mpu_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct inv_mpu6050_state *st = iio_priv(indio_dev); @@ -1730,7 +1730,7 @@ out_unlock: return result; } -static int __maybe_unused inv_mpu_runtime_suspend(struct device *dev) +static int inv_mpu_runtime_suspend(struct device *dev) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev)); unsigned int sensors; @@ -1755,7 +1755,7 @@ out_unlock: return ret; } -static int __maybe_unused inv_mpu_runtime_resume(struct device *dev) +static int inv_mpu_runtime_resume(struct device *dev) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1767,11 +1767,10 @@ static int __maybe_unused inv_mpu_runtime_resume(struct device *dev) return inv_mpu6050_set_power_itg(st, true); } -const struct dev_pm_ops inv_mpu_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) - SET_RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(inv_mpu_pmops, IIO_MPU6050) = { + SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) + RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(inv_mpu_pmops); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 14255a918eb1d..7a8d60a5afa9a 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -267,7 +267,7 @@ static struct i2c_driver inv_mpu_driver = { .of_match_table = inv_of_match, .acpi_match_table = inv_acpi_match, .name = "inv-mpu6050-i2c", - .pm = &inv_mpu_pmops, + .pm = pm_ptr(&inv_mpu_pmops), }, }; @@ -276,3 +276,4 @@ module_i2c_driver(inv_mpu_driver); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_MPU6050); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index e6107b0cc38ff..89f46c2f213d8 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -154,7 +154,7 @@ static struct spi_driver inv_mpu_driver = { .of_match_table = inv_of_match, .acpi_match_table = inv_acpi_match, .name = "inv-mpu6000-spi", - .pm = &inv_mpu_pmops, + .pm = pm_ptr(&inv_mpu_pmops), }, }; @@ -163,3 +163,4 @@ module_spi_driver(inv_mpu_driver); MODULE_AUTHOR("Adriana Reus "); MODULE_DESCRIPTION("Invensense device MPU6000 driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_MPU6050); -- GitLab From 1ccef2e6e9205e209ad958d2e591bcca60981007 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:01 +0300 Subject: [PATCH 0891/1480] iio: adc: ad7192: Simplify using devm_regulator_get_enable() Use devm_regulator_get_enable() instead of open coded get, enable, add-action-to-disable-at-detach - pattern. Also drop the seemingly unused struct member 'dvdd'. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/9719c445c095d3d308e2fc9f4f93294f5806c41c.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7192.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index f5067173deb62..55a6ab5910160 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -177,7 +177,6 @@ struct ad7192_chip_info { struct ad7192_state { const struct ad7192_chip_info *chip_info; struct regulator *avdd; - struct regulator *dvdd; struct clk *mclk; u16 int_vref_mv; u32 fclk; @@ -1015,19 +1014,9 @@ static int ad7192_probe(struct spi_device *spi) if (ret) return ret; - st->dvdd = devm_regulator_get(&spi->dev, "dvdd"); - if (IS_ERR(st->dvdd)) - return PTR_ERR(st->dvdd); - - ret = regulator_enable(st->dvdd); - if (ret) { - dev_err(&spi->dev, "Failed to enable specified DVdd supply\n"); - return ret; - } - - ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->dvdd); + ret = devm_regulator_get_enable(&spi->dev, "dvdd"); if (ret) - return ret; + return dev_err_probe(&spi->dev, ret, "Failed to enable specified DVdd supply\n"); ret = regulator_get_voltage(st->avdd); if (ret < 0) { -- GitLab From 08f75f180db06566d134b1cac1d8a4b8f266761e Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:17 +0300 Subject: [PATCH 0892/1480] iio: dac: ltc2688: Simplify using devm_regulator_*get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. Signed-off-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/a29493f594c84b3bd852e462bbd3e591a8575a27.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ltc2688.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/iio/dac/ltc2688.c b/drivers/iio/dac/ltc2688.c index 28bdde2d30889..fc8eb53c65be3 100644 --- a/drivers/iio/dac/ltc2688.c +++ b/drivers/iio/dac/ltc2688.c @@ -84,7 +84,6 @@ struct ltc2688_chan { struct ltc2688_state { struct spi_device *spi; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; struct ltc2688_chan channels[LTC2688_DAC_CHANNELS]; struct iio_chan_spec *iio_chan; /* lock to protect against multiple access to the device and shared data */ @@ -902,13 +901,6 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref) LTC2688_CONFIG_EXT_REF); } -static void ltc2688_disable_regulators(void *data) -{ - struct ltc2688_state *st = data; - - regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); -} - static void ltc2688_disable_regulator(void *regulator) { regulator_disable(regulator); @@ -965,6 +957,7 @@ static const struct iio_info ltc2688_info = { static int ltc2688_probe(struct spi_device *spi) { + static const char * const regulators[] = { "vcc", "iovcc" }; struct ltc2688_state *st; struct iio_dev *indio_dev; struct regulator *vref_reg; @@ -988,21 +981,11 @@ static int ltc2688_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(st->regmap), "Failed to init regmap"); - st->regulators[0].supply = "vcc"; - st->regulators[1].supply = "iovcc"; - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st->regulators), - st->regulators); - if (ret) - return dev_err_probe(dev, ret, "Failed to get regulators\n"); - - ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (ret) return dev_err_probe(dev, ret, "Failed to enable regulators\n"); - ret = devm_add_action_or_reset(dev, ltc2688_disable_regulators, st); - if (ret) - return ret; - vref_reg = devm_regulator_get_optional(dev, "vref"); if (IS_ERR(vref_reg)) { if (PTR_ERR(vref_reg) != -ENODEV) -- GitLab From 2c620883a46b6e2299cf9e4b4683e5b3cc67a61e Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:31 +0300 Subject: [PATCH 0893/1480] iio: gyro: bmg160_core: Simplify using devm_regulator_*get_enable() Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/3fd11489356b1c73a3d7b4bd9dec7e12c9fe8788.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_core.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index cedd9f02ea211..0e2eb0e98235f 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -93,7 +93,6 @@ struct bmg160_data { struct regmap *regmap; - struct regulator_bulk_data regulators[2]; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct iio_mount_matrix orientation; @@ -1067,16 +1066,10 @@ static const char *bmg160_match_acpi_device(struct device *dev) return dev_name(dev); } -static void bmg160_disable_regulators(void *d) -{ - struct bmg160_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { + static const char * const regulators[] = { "vdd", "vddio" }; struct bmg160_data *data; struct iio_dev *indio_dev; int ret; @@ -1090,22 +1083,11 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, data->irq = irq; data->regmap = regmap; - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (ret) return dev_err_probe(dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, bmg160_disable_regulators, data); - if (ret) - return ret; - ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; -- GitLab From 6900cdbfb99e8600572da340576509297a684a3a Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:46 +0300 Subject: [PATCH 0894/1480] iio: imu: st_lsm6dsx: Simplify using devm_regulator_*get_enable() Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. A functional change (which seems like a bugfix) is that if regulator_bulk_get fails, the enable is not attempted. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/876e58428cec056d51070e49eff559e2d7c23b12.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 -- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 30 ++++---------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d3a4e21bc1149..07ad8027de738 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -374,7 +374,6 @@ struct st_lsm6dsx_sensor { * struct st_lsm6dsx_hw - ST IMU MEMS hw instance * @dev: Pointer to instance of struct device (I2C or SPI). * @regmap: Register map of the device. - * @regulators: VDD/VDDIO voltage regulators. * @irq: Device interrupt line (I2C or SPI). * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. * @conf_lock: Mutex to prevent concurrent FIFO configuration update. @@ -397,7 +396,6 @@ struct st_lsm6dsx_sensor { struct st_lsm6dsx_hw { struct device *dev; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; int irq; struct mutex fifo_lock; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 6af2e905c1612..fe5fa08b68acb 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2177,36 +2177,20 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) static int st_lsm6dsx_init_regulators(struct device *dev) { - struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); + /* vdd-vddio power regulators */ + static const char * const regulators[] = { "vdd", "vddio" }; int err; - /* vdd-vddio power regulators */ - hw->regulators[0].supply = "vdd"; - hw->regulators[1].supply = "vddio"; - err = devm_regulator_bulk_get(dev, ARRAY_SIZE(hw->regulators), - hw->regulators); + err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (err) - return dev_err_probe(dev, err, "failed to get regulators\n"); - - err = regulator_bulk_enable(ARRAY_SIZE(hw->regulators), - hw->regulators); - if (err) { - dev_err(dev, "failed to enable regulators: %d\n", err); - return err; - } + return dev_err_probe(dev, err, "failed to enable regulators\n"); msleep(50); return 0; } -static void st_lsm6dsx_chip_uninit(void *data) -{ - struct st_lsm6dsx_hw *hw = data; - - regulator_bulk_disable(ARRAY_SIZE(hw->regulators), hw->regulators); -} - int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap) { @@ -2230,10 +2214,6 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, if (err) return err; - err = devm_add_action_or_reset(dev, st_lsm6dsx_chip_uninit, hw); - if (err) - return err; - hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); if (!hw->buff) return -ENOMEM; -- GitLab From 7ff0ad35aa6f70fe32fee33bc6e0aa356af99f76 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:03 +0300 Subject: [PATCH 0895/1480] iio: adc: ad7476: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/33070d66b9b976acac1cee5570facef9278b6b61.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7476.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 94776f6962907..80aebed47d1fa 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -368,16 +368,7 @@ static int ad7476_probe(struct spi_device *spi) } if (st->chip_info->has_vdrive) { - reg = devm_regulator_get(&spi->dev, "vdrive"); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - ret = regulator_enable(reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable, - reg); + ret = devm_regulator_get_enable(&spi->dev, "vdrive"); if (ret) return ret; } -- GitLab From fd5b6c48ec3345d5c243e283fbdb69618ada2be8 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:18 +0300 Subject: [PATCH 0896/1480] iio: adc: ad7606: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Whilst here also switch to dev_err_probe() to provide more information if a deferred probe occurs. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/521c52f5a9bdc2db04d5775b36df4b233ae338da.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7606.c | 22 +++------------------- drivers/iio/adc/ad7606.h | 2 -- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index ba24f99523e01..dd6b603f65ead 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -557,13 +557,6 @@ static const struct iio_trigger_ops ad7606_trigger_ops = { .validate_device = iio_trigger_validate_own_device, }; -static void ad7606_regulator_disable(void *data) -{ - struct ad7606_state *st = data; - - regulator_disable(st->reg); -} - int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, const char *name, unsigned int id, const struct ad7606_bus_ops *bops) @@ -589,19 +582,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->scale_avail = ad7606_scale_avail; st->num_scales = ARRAY_SIZE(ad7606_scale_avail); - st->reg = devm_regulator_get(dev, "avcc"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) { - dev_err(dev, "Failed to enable specified AVcc supply\n"); - return ret; - } - - ret = devm_add_action_or_reset(dev, ad7606_regulator_disable, st); + ret = devm_regulator_get_enable(dev, "avcc"); if (ret) - return ret; + return dev_err_probe(dev, ret, + "Failed to enable specified AVcc supply\n"); st->chip_info = &ad7606_chip_info_tbl[id]; diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 2dc4f599f9df9..0c6a88cc46958 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -62,7 +62,6 @@ struct ad7606_chip_info { * struct ad7606_state - driver instance specific data * @dev pointer to kernel device * @chip_info entry in the table of chips that describes this device - * @reg regulator info for the power supply of the device * @bops bus operations (SPI or parallel) * @range voltage range selection, selects which scale to apply * @oversampling oversampling selection @@ -92,7 +91,6 @@ struct ad7606_chip_info { struct ad7606_state { struct device *dev; const struct ad7606_chip_info *chip_info; - struct regulator *reg; const struct ad7606_bus_ops *bops; unsigned int range[16]; unsigned int oversampling; -- GitLab From f55c8e6696425ef22b7d08fc05b920d3a1a5dbf6 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:32 +0300 Subject: [PATCH 0897/1480] iio: adc: max1241: simplify using devm_regulator_get_enable() Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Alexandru Lazar Link: https://lore.kernel.org/r/7c759bf6c06e72ae70bffeebc1939d9903427278.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1241.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c index a815ad1f6913b..500bb09ab19bc 100644 --- a/drivers/iio/adc/max1241.c +++ b/drivers/iio/adc/max1241.c @@ -22,7 +22,6 @@ enum max1241_id { struct max1241 { struct spi_device *spi; struct mutex lock; - struct regulator *vdd; struct regulator *vref; struct gpio_desc *shutdown; @@ -110,17 +109,6 @@ static const struct iio_info max1241_info = { .read_raw = max1241_read_raw, }; -static void max1241_disable_vdd_action(void *data) -{ - struct max1241 *adc = data; - struct device *dev = &adc->spi->dev; - int err; - - err = regulator_disable(adc->vdd); - if (err) - dev_err(dev, "could not disable vdd regulator.\n"); -} - static void max1241_disable_vref_action(void *data) { struct max1241 *adc = data; @@ -147,20 +135,10 @@ static int max1241_probe(struct spi_device *spi) adc->spi = spi; mutex_init(&adc->lock); - adc->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(adc->vdd)) - return dev_err_probe(dev, PTR_ERR(adc->vdd), - "failed to get vdd regulator\n"); - - ret = regulator_enable(adc->vdd); + ret = devm_regulator_get_enable(dev, "vdd"); if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, max1241_disable_vdd_action, adc); - if (ret) { - dev_err(dev, "could not set up vdd regulator cleanup action\n"); - return ret; - } + return dev_err_probe(dev, ret, + "failed to get/enable vdd regulator\n"); adc->vref = devm_regulator_get(dev, "vref"); if (IS_ERR(adc->vref)) -- GitLab From 3dfa1d4f63baf41774bbc77467729de39e0ac8a6 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:47 +0300 Subject: [PATCH 0898/1480] iio: adc: max1363: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/1286ea127d190e5708a0aaff271819b2d3f8802d.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index a28cf86cdce80..42d3479cefb73 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -148,7 +148,6 @@ struct max1363_chip_info { * @chip_info: chip model specific constants, available modes, etc. * @current_mode: the scan mode of this chip * @requestedmask: a valid requested set of channels - * @reg: supply regulator * @lock: lock to ensure state is consistent * @monitor_on: whether monitor mode is enabled * @monitor_speed: parameter corresponding to device monitor speed setting @@ -168,7 +167,6 @@ struct max1363_state { const struct max1363_chip_info *chip_info; const struct max1363_mode *current_mode; u32 requestedmask; - struct regulator *reg; struct mutex lock; /* Using monitor modes and buffer at the same time is @@ -1597,15 +1595,7 @@ static int max1363_probe(struct i2c_client *client, st = iio_priv(indio_dev); mutex_init(&st->lock); - st->reg = devm_regulator_get(&client->dev, "vcc"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, st->reg); + ret = devm_regulator_get_enable(&client->dev, "vcc"); if (ret) return ret; -- GitLab From 563746c26db6c203d30bed2daa301416b27b77fb Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:21:02 +0300 Subject: [PATCH 0899/1480] iio: amplifier: hmc425a: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/8b1193fdefb231a6d721e2bded52c48e56039c20.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/amplifiers/hmc425a.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c index ce80e0c916f4a..108f0f1685ef1 100644 --- a/drivers/iio/amplifiers/hmc425a.c +++ b/drivers/iio/amplifiers/hmc425a.c @@ -34,7 +34,6 @@ struct hmc425a_chip_info { }; struct hmc425a_state { - struct regulator *reg; struct mutex lock; /* protect sensor state */ struct hmc425a_chip_info *chip_info; struct gpio_descs *gpios; @@ -162,13 +161,6 @@ static const struct of_device_id hmc425a_of_match[] = { }; MODULE_DEVICE_TABLE(of, hmc425a_of_match); -static void hmc425a_reg_disable(void *data) -{ - struct hmc425a_state *st = data; - - regulator_disable(st->reg); -} - static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = { [ID_HMC425A] = { .name = "hmc425a", @@ -211,14 +203,7 @@ static int hmc425a_probe(struct platform_device *pdev) return -ENODEV; } - st->reg = devm_regulator_get(&pdev->dev, "vcc-supply"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) - return ret; - ret = devm_add_action_or_reset(&pdev->dev, hmc425a_reg_disable, st); + ret = devm_regulator_get_enable(&pdev->dev, "vcc-supply"); if (ret) return ret; -- GitLab From fd4fc88d0b6fc452571152d4d3b2fc8078be3825 Mon Sep 17 00:00:00 2001 From: Mitja Spes Date: Fri, 21 Oct 2022 15:58:22 +0200 Subject: [PATCH 0900/1480] dt-bindings: iio: pressure: meas,ms5611: add max SPI frequency to the example Added max SPI frequency setting to the example. Signed-off-by: Mitja Spes Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221021135827.1444793-4-mitja@lxnav.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml b/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml index 7fed750fa3ff7..21e6ddb7f41e3 100644 --- a/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/meas,ms5611.yaml @@ -55,6 +55,7 @@ examples: compatible = "meas,ms5611"; reg = <0>; vdd-supply = <&ldo_3v3_gnss>; + spi-max-frequency = <20000000>; }; }; ... -- GitLab From 36a4df5003c91663bd2d68a3cf452c0495ce583c Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 21 Oct 2022 13:41:14 +0300 Subject: [PATCH 0901/1480] dt-bindings: iio: adc: add AD4130 AD4130-8 is an ultra-low power, high precision, measurement solution for low bandwidth battery operated applications. The fully integrated AFE (Analog Front-End) includes a multiplexer for up to 16 single-ended or 8 differential inputs, PGA (Programmable Gain Amplifier), 24-bit Sigma-Delta ADC, on-chip reference and oscillator, selectable filter options, smart sequencer, sensor biasing and excitation options, diagnostics, and a FIFO buffer. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221021104115.1812486-2-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/adi,ad4130.yaml | 259 ++++++++++++++++++ MAINTAINERS | 7 + 2 files changed, 266 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml new file mode 100644 index 0000000000000..28ebd38b9db44 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml @@ -0,0 +1,259 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2022 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4130.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4130 ADC device driver + +maintainers: + - Cosmin Tanislav + +description: | + Bindings for the Analog Devices AD4130 ADC. Datasheet can be found here: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4130-8.pdf + +properties: + compatible: + enum: + - adi,ad4130 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: phandle to the master clock (mclk) + + clock-names: + items: + - const: mclk + + interrupts: + maxItems: 1 + + interrupt-names: + description: | + Specify which interrupt pin should be configured as Data Ready / FIFO + interrupt. + Default if not supplied is int. + enum: + - int + - clk + - p2 + - dout + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + '#clock-cells': + const: 0 + + clock-output-names: + maxItems: 1 + + refin1-supply: + description: refin1 supply. Can be used as reference for conversion. + + refin2-supply: + description: refin2 supply. Can be used as reference for conversion. + + avdd-supply: + description: AVDD voltage supply. Can be used as reference for conversion. + + iovdd-supply: + description: IOVDD voltage supply. Used for the chip interface. + + spi-max-frequency: + maximum: 5000000 + + adi,ext-clk-freq-hz: + description: Specify the frequency of the external clock. + enum: [76800, 153600] + default: 76800 + + adi,bipolar: + description: Specify if the device should be used in bipolar mode. + type: boolean + + adi,vbias-pins: + description: Analog inputs to apply a voltage bias of (AVDD − AVSS) / 2 to. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 16 + items: + minimum: 0 + maximum: 15 + +required: + - compatible + - reg + - interrupts + +patternProperties: + "^channel@([0-9a-f])$": + type: object + $ref: adc.yaml + unevaluatedProperties: false + + properties: + reg: + description: The channel number. + minimum: 0 + maximum: 15 + + diff-channels: + description: | + Besides the analog inputs available, internal inputs can be used. + 16: Internal temperature sensor. + 17: AVSS + 18: Internal reference + 19: DGND + 20: (AVDD − AVSS)/6+ + 21: (AVDD − AVSS)/6- + 22: (IOVDD − DGND)/6+ + 23: (IOVDD − DGND)/6- + 24: (ALDO − AVSS)/6+ + 25: (ALDO − AVSS)/6- + 26: (DLDO − DGND)/6+ + 27: (DLDO − DGND)/6- + 28: V_MV_P + 29: V_MV_M + items: + minimum: 0 + maximum: 29 + + adi,reference-select: + description: | + Select the reference source to use when converting on the + specific channel. Valid values are: + 0: REFIN1(+)/REFIN1(−) + 1: REFIN2(+)/REFIN2(−) + 2: REFOUT/AVSS (Internal reference) + 3: AVDD/AVSS + If not specified, REFIN1 is used. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + default: 0 + + adi,excitation-pin-0: + description: | + Analog input to apply excitation current to while the channel + is active. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 15 + default: 0 + + adi,excitation-pin-1: + description: | + Analog input to apply excitation current to while this channel + is active. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 15 + default: 0 + + adi,excitation-current-0-nanoamp: + description: | + Excitation current in nanoamps to be applied to pin specified in + adi,excitation-pin-0 while this channel is active. + enum: [0, 100, 10000, 20000, 50000, 100000, 150000, 200000] + default: 0 + + adi,excitation-current-1-nanoamp: + description: | + Excitation current in nanoamps to be applied to pin specified in + adi,excitation-pin-1 while this channel is active. + enum: [0, 100, 10000, 20000, 50000, 100000, 150000, 200000] + default: 0 + + adi,burnout-current-nanoamp: + description: | + Burnout current in nanoamps to be applied for this channel. + enum: [0, 500, 2000, 4000] + default: 0 + + adi,buffered-positive: + description: Enable buffered mode for positive input. + type: boolean + + adi,buffered-negative: + description: Enable buffered mode for negative input. + type: boolean + + required: + - reg + - diff-channels + +additionalProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad4130"; + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + spi-max-frequency = <5000000>; + interrupts = <27 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpio>; + + channel@0 { + reg = <0>; + + adi,reference-select = <2>; + + /* AIN8, AIN9 */ + diff-channels = <8 9>; + }; + + channel@1 { + reg = <1>; + + adi,reference-select = <2>; + + /* AIN10, AIN11 */ + diff-channels = <10 11>; + }; + + channel@2 { + reg = <2>; + + adi,reference-select = <2>; + + /* Temperature Sensor, DGND */ + diff-channels = <16 19>; + }; + + channel@3 { + reg = <3>; + + adi,reference-select = <2>; + + /* Internal reference, DGND */ + diff-channels = <18 19>; + }; + + channel@4 { + reg = <4>; + + adi,reference-select = <2>; + + /* DGND, DGND */ + diff-channels = <19 19>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 379945f82a643..5cb67803af96f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1117,6 +1117,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git F: drivers/net/amt.c +ANALOG DEVICES INC AD4130 DRIVER +M: Cosmin Tanislav +L: linux-iio@vger.kernel.org +S: Supported +W: http://ez.analog.com/community/linux-device-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml + ANALOG DEVICES INC AD7192 DRIVER M: Alexandru Tachici L: linux-iio@vger.kernel.org -- GitLab From 62094060cf3acaf52e277457d807ea753269b89e Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 21 Oct 2022 13:41:15 +0300 Subject: [PATCH 0902/1480] iio: adc: ad4130: add AD4130 driver AD4130-8 is an ultra-low power, high precision, measurement solution for low bandwidth battery operated applications. The fully integrated AFE (Analog Front-End) includes a multiplexer for up to 16 single-ended or 8 differential inputs, PGA (Programmable Gain Amplifier), 24-bit Sigma-Delta ADC, on-chip reference and oscillator, selectable filter options, smart sequencer, sensor biasing and excitation options, diagnostics, and a FIFO buffer. Signed-off-by: Cosmin Tanislav Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221021104115.1812486-3-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-adc-ad4130 | 36 + MAINTAINERS | 2 + drivers/iio/adc/Kconfig | 14 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad4130.c | 2100 +++++++++++++++++ 5 files changed, 2153 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 create mode 100644 drivers/iio/adc/ad4130.c diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 new file mode 100644 index 0000000000000..d9555751d21ce --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 @@ -0,0 +1,36 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_filter_mode_available +KernelVersion: 6.2 +Contact: linux-iio@vger.kernel.org +Description: + Reading returns a list with the possible filter modes. + "sinc4" - Sinc 4. Excellent noise performance. Long 1st + conversion time. No natural 50/60Hz rejection. + "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion time. + "sinc3" - Sinc3. Moderate 1st conversion time. Good noise + performance. + "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling frequency + of 50Hz, achieves simultaneous 50Hz and 60Hz + rejection. + "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion time. + Best used with a sampling frequency of at least + 216.19Hz. + "sinc3+pf1" - Sinc3 + Post Filter 1. + 53dB rejection @ 50Hz, 58dB rejection @ 60Hz. + "sinc3+pf2" - Sinc3 + Post Filter 2. + 70dB rejection @ 50Hz, 70dB rejection @ 60Hz. + "sinc3+pf3" - Sinc3 + Post Filter 3. + 99dB rejection @ 50Hz, 103dB rejection @ 60Hz. + "sinc3+pf4" - Sinc3 + Post Filter 4. + 103dB rejection @ 50Hz, 109dB rejection @ 60Hz. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_filter_mode +KernelVersion: 6.2 +Contact: linux-iio@vger.kernel.org +Description: + Set the filter mode of the differential channel. When the filter + mode changes, the in_voltageY-voltageZ_sampling_frequency and + in_voltageY-voltageZ_sampling_frequency_available attributes + might also change to accommodate the new filter mode. + If the current sampling frequency is out of range for the new + filter mode, the sampling frequency will be changed to the + closest valid one. diff --git a/MAINTAINERS b/MAINTAINERS index 5cb67803af96f..ecec0bb6b09e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1122,7 +1122,9 @@ M: Cosmin Tanislav L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers +F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml +F: drivers/iio/adc/ad4130.c ANALOG DEVICES INC AD7192 DRIVER M: Alexandru Tachici diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 5386d862def9c..8d719fbb6acc0 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -21,6 +21,20 @@ config AD_SIGMA_DELTA select IIO_BUFFER select IIO_TRIGGERED_BUFFER +config AD4130 + tristate "Analog Device AD4130 ADC Driver" + depends on SPI + select IIO_BUFFER + select IIO_KFIFO_BUF + select REGMAP_SPI + depends on COMMON_CLK + help + Say yes here to build support for Analog Devices AD4130-8 SPI analog + to digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4130. + config AD7091R5 tristate "Analog Devices AD7091R5 ADC Driver" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 1571e891828eb..4ef41a7dfac6e 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -6,6 +6,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o +obj-$(CONFIG_AD4130) += ad4130.o obj-$(CONFIG_AD7091R5) += ad7091r5.o ad7091r-base.o obj-$(CONFIG_AD7124) += ad7124.o obj-$(CONFIG_AD7192) += ad7192.o diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c new file mode 100644 index 0000000000000..9a4d0043d797e --- /dev/null +++ b/drivers/iio/adc/ad4130.c @@ -0,0 +1,2100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Analog Devices, Inc. + * Author: Cosmin Tanislav + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#define AD4130_NAME "ad4130" + +#define AD4130_COMMS_READ_MASK BIT(6) + +#define AD4130_STATUS_REG 0x00 + +#define AD4130_ADC_CONTROL_REG 0x01 +#define AD4130_ADC_CONTROL_BIPOLAR_MASK BIT(14) +#define AD4130_ADC_CONTROL_INT_REF_VAL_MASK BIT(13) +#define AD4130_INT_REF_2_5V 2500000 +#define AD4130_INT_REF_1_25V 1250000 +#define AD4130_ADC_CONTROL_CSB_EN_MASK BIT(9) +#define AD4130_ADC_CONTROL_INT_REF_EN_MASK BIT(8) +#define AD4130_ADC_CONTROL_MODE_MASK GENMASK(5, 2) +#define AD4130_ADC_CONTROL_MCLK_SEL_MASK GENMASK(1, 0) +#define AD4130_MCLK_FREQ_76_8KHZ 76800 +#define AD4130_MCLK_FREQ_153_6KHZ 153600 + +#define AD4130_DATA_REG 0x02 + +#define AD4130_IO_CONTROL_REG 0x03 +#define AD4130_IO_CONTROL_INT_PIN_SEL_MASK GENMASK(9, 8) +#define AD4130_IO_CONTROL_GPIO_DATA_MASK GENMASK(7, 4) +#define AD4130_IO_CONTROL_GPIO_CTRL_MASK GENMASK(3, 0) + +#define AD4130_VBIAS_REG 0x04 + +#define AD4130_ID_REG 0x05 + +#define AD4130_ERROR_REG 0x06 + +#define AD4130_ERROR_EN_REG 0x07 + +#define AD4130_MCLK_COUNT_REG 0x08 + +#define AD4130_CHANNEL_X_REG(x) (0x09 + (x)) +#define AD4130_CHANNEL_EN_MASK BIT(23) +#define AD4130_CHANNEL_SETUP_MASK GENMASK(22, 20) +#define AD4130_CHANNEL_AINP_MASK GENMASK(17, 13) +#define AD4130_CHANNEL_AINM_MASK GENMASK(12, 8) +#define AD4130_CHANNEL_IOUT1_MASK GENMASK(7, 4) +#define AD4130_CHANNEL_IOUT2_MASK GENMASK(3, 0) + +#define AD4130_CONFIG_X_REG(x) (0x19 + (x)) +#define AD4130_CONFIG_IOUT1_VAL_MASK GENMASK(15, 13) +#define AD4130_CONFIG_IOUT2_VAL_MASK GENMASK(12, 10) +#define AD4130_CONFIG_BURNOUT_MASK GENMASK(9, 8) +#define AD4130_CONFIG_REF_BUFP_MASK BIT(7) +#define AD4130_CONFIG_REF_BUFM_MASK BIT(6) +#define AD4130_CONFIG_REF_SEL_MASK GENMASK(5, 4) +#define AD4130_CONFIG_PGA_MASK GENMASK(3, 1) + +#define AD4130_FILTER_X_REG(x) (0x21 + (x)) +#define AD4130_FILTER_MODE_MASK GENMASK(15, 12) +#define AD4130_FILTER_SELECT_MASK GENMASK(10, 0) +#define AD4130_FILTER_SELECT_MIN 1 + +#define AD4130_OFFSET_X_REG(x) (0x29 + (x)) + +#define AD4130_GAIN_X_REG(x) (0x31 + (x)) + +#define AD4130_MISC_REG 0x39 + +#define AD4130_FIFO_CONTROL_REG 0x3a +#define AD4130_FIFO_CONTROL_HEADER_MASK BIT(18) +#define AD4130_FIFO_CONTROL_MODE_MASK GENMASK(17, 16) +#define AD4130_FIFO_CONTROL_WM_INT_EN_MASK BIT(9) +#define AD4130_FIFO_CONTROL_WM_MASK GENMASK(7, 0) +#define AD4130_WATERMARK_256 0 + +#define AD4130_FIFO_STATUS_REG 0x3b + +#define AD4130_FIFO_THRESHOLD_REG 0x3c + +#define AD4130_FIFO_DATA_REG 0x3d +#define AD4130_FIFO_SIZE 256 +#define AD4130_FIFO_MAX_SAMPLE_SIZE 3 + +#define AD4130_MAX_ANALOG_PINS 16 +#define AD4130_MAX_CHANNELS 16 +#define AD4130_MAX_DIFF_INPUTS 30 +#define AD4130_MAX_GPIOS 4 +#define AD4130_MAX_ODR 2400 +#define AD4130_MAX_PGA 8 +#define AD4130_MAX_SETUPS 8 + +#define AD4130_AIN2_P1 0x2 +#define AD4130_AIN3_P2 0x3 + +#define AD4130_RESET_BUF_SIZE 8 +#define AD4130_RESET_SLEEP_US (160 * MICRO / AD4130_MCLK_FREQ_76_8KHZ) + +#define AD4130_INVALID_SLOT -1 + +static const unsigned int ad4130_reg_size[] = { + [AD4130_STATUS_REG] = 1, + [AD4130_ADC_CONTROL_REG] = 2, + [AD4130_DATA_REG] = 3, + [AD4130_IO_CONTROL_REG] = 2, + [AD4130_VBIAS_REG] = 2, + [AD4130_ID_REG] = 1, + [AD4130_ERROR_REG] = 2, + [AD4130_ERROR_EN_REG] = 2, + [AD4130_MCLK_COUNT_REG] = 1, + [AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3, + [AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2, + [AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_MISC_REG] = 2, + [AD4130_FIFO_CONTROL_REG] = 3, + [AD4130_FIFO_STATUS_REG] = 1, + [AD4130_FIFO_THRESHOLD_REG] = 3, + [AD4130_FIFO_DATA_REG] = 3, +}; + +enum ad4130_int_ref_val { + AD4130_INT_REF_VAL_2_5V, + AD4130_INT_REF_VAL_1_25V, +}; + +enum ad4130_mclk_sel { + AD4130_MCLK_76_8KHZ, + AD4130_MCLK_76_8KHZ_OUT, + AD4130_MCLK_76_8KHZ_EXT, + AD4130_MCLK_153_6KHZ_EXT, +}; + +enum ad4130_int_pin_sel { + AD4130_INT_PIN_INT, + AD4130_INT_PIN_CLK, + AD4130_INT_PIN_P2, + AD4130_INT_PIN_DOUT, +}; + +enum ad4130_iout { + AD4130_IOUT_OFF, + AD4130_IOUT_10000NA, + AD4130_IOUT_20000NA, + AD4130_IOUT_50000NA, + AD4130_IOUT_100000NA, + AD4130_IOUT_150000NA, + AD4130_IOUT_200000NA, + AD4130_IOUT_100NA, + AD4130_IOUT_MAX +}; + +enum ad4130_burnout { + AD4130_BURNOUT_OFF, + AD4130_BURNOUT_500NA, + AD4130_BURNOUT_2000NA, + AD4130_BURNOUT_4000NA, + AD4130_BURNOUT_MAX +}; + +enum ad4130_ref_sel { + AD4130_REF_REFIN1, + AD4130_REF_REFIN2, + AD4130_REF_REFOUT_AVSS, + AD4130_REF_AVDD_AVSS, + AD4130_REF_SEL_MAX +}; + +enum ad4130_fifo_mode { + AD4130_FIFO_MODE_DISABLED = 0b00, + AD4130_FIFO_MODE_WM = 0b01, +}; + +enum ad4130_mode { + AD4130_MODE_CONTINUOUS = 0b0000, + AD4130_MODE_IDLE = 0b0100, +}; + +enum ad4130_filter_mode { + AD4130_FILTER_SINC4, + AD4130_FILTER_SINC4_SINC1, + AD4130_FILTER_SINC3, + AD4130_FILTER_SINC3_REJ60, + AD4130_FILTER_SINC3_SINC1, + AD4130_FILTER_SINC3_PF1, + AD4130_FILTER_SINC3_PF2, + AD4130_FILTER_SINC3_PF3, + AD4130_FILTER_SINC3_PF4, +}; + +enum ad4130_pin_function { + AD4130_PIN_FN_NONE, + AD4130_PIN_FN_SPECIAL = BIT(0), + AD4130_PIN_FN_DIFF = BIT(1), + AD4130_PIN_FN_EXCITATION = BIT(2), + AD4130_PIN_FN_VBIAS = BIT(3), +}; + +struct ad4130_setup_info { + unsigned int iout0_val; + unsigned int iout1_val; + unsigned int burnout; + unsigned int pga; + unsigned int fs; + u32 ref_sel; + enum ad4130_filter_mode filter_mode; + bool ref_bufp; + bool ref_bufm; +}; + +struct ad4130_slot_info { + struct ad4130_setup_info setup; + unsigned int enabled_channels; + unsigned int channels; +}; + +struct ad4130_chan_info { + struct ad4130_setup_info setup; + u32 iout0; + u32 iout1; + int slot; + bool enabled; + bool initialized; +}; + +struct ad4130_filter_config { + enum ad4130_filter_mode filter_mode; + unsigned int odr_div; + unsigned int fs_max; + enum iio_available_type samp_freq_avail_type; + int samp_freq_avail_len; + int samp_freq_avail[3][2]; +}; + +struct ad4130_state { + struct regmap *regmap; + struct spi_device *spi; + struct clk *mclk; + struct regulator_bulk_data regulators[4]; + u32 irq_trigger; + u32 inv_irq_trigger; + + /* + * Synchronize access to members the of driver state, and ensure + * atomicity of consecutive regmap operations. + */ + struct mutex lock; + struct completion completion; + + struct iio_chan_spec chans[AD4130_MAX_CHANNELS]; + struct ad4130_chan_info chans_info[AD4130_MAX_CHANNELS]; + struct ad4130_slot_info slots_info[AD4130_MAX_SETUPS]; + enum ad4130_pin_function pins_fn[AD4130_MAX_ANALOG_PINS]; + u32 vbias_pins[AD4130_MAX_ANALOG_PINS]; + u32 num_vbias_pins; + int scale_tbls[AD4130_REF_SEL_MAX][AD4130_MAX_PGA][2]; + struct gpio_chip gc; + struct clk_hw int_clk_hw; + + u32 int_pin_sel; + u32 int_ref_uv; + u32 mclk_sel; + bool int_ref_en; + bool bipolar; + + unsigned int num_enabled_channels; + unsigned int effective_watermark; + unsigned int watermark; + + struct spi_message fifo_msg; + struct spi_transfer fifo_xfer[2]; + + /* + * DMA (thus cache coherency maintenance) requires any transfer + * buffers to live in their own cache lines. As the use of these + * buffers is synchronous, all of the buffers used for DMA in this + * driver may share a cache line. + */ + u8 reset_buf[AD4130_RESET_BUF_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 reg_write_tx_buf[4]; + u8 reg_read_tx_buf[1]; + u8 reg_read_rx_buf[3]; + u8 fifo_tx_buf[2]; + u8 fifo_rx_buf[AD4130_FIFO_SIZE * + AD4130_FIFO_MAX_SAMPLE_SIZE]; +}; + +static const char * const ad4130_int_pin_names[] = { + [AD4130_INT_PIN_INT] = "int", + [AD4130_INT_PIN_CLK] = "clk", + [AD4130_INT_PIN_P2] = "p2", + [AD4130_INT_PIN_DOUT] = "dout", +}; + +static const unsigned int ad4130_iout_current_na_tbl[AD4130_IOUT_MAX] = { + [AD4130_IOUT_OFF] = 0, + [AD4130_IOUT_100NA] = 100, + [AD4130_IOUT_10000NA] = 10000, + [AD4130_IOUT_20000NA] = 20000, + [AD4130_IOUT_50000NA] = 50000, + [AD4130_IOUT_100000NA] = 100000, + [AD4130_IOUT_150000NA] = 150000, + [AD4130_IOUT_200000NA] = 200000, +}; + +static const unsigned int ad4130_burnout_current_na_tbl[AD4130_BURNOUT_MAX] = { + [AD4130_BURNOUT_OFF] = 0, + [AD4130_BURNOUT_500NA] = 500, + [AD4130_BURNOUT_2000NA] = 2000, + [AD4130_BURNOUT_4000NA] = 4000, +}; + +#define AD4130_VARIABLE_ODR_CONFIG(_filter_mode, _odr_div, _fs_max) \ +{ \ + .filter_mode = (_filter_mode), \ + .odr_div = (_odr_div), \ + .fs_max = (_fs_max), \ + .samp_freq_avail_type = IIO_AVAIL_RANGE, \ + .samp_freq_avail = { \ + { AD4130_MAX_ODR, (_odr_div) * (_fs_max) }, \ + { AD4130_MAX_ODR, (_odr_div) * (_fs_max) }, \ + { AD4130_MAX_ODR, (_odr_div) }, \ + }, \ +} + +#define AD4130_FIXED_ODR_CONFIG(_filter_mode, _odr_div) \ +{ \ + .filter_mode = (_filter_mode), \ + .odr_div = (_odr_div), \ + .fs_max = AD4130_FILTER_SELECT_MIN, \ + .samp_freq_avail_type = IIO_AVAIL_LIST, \ + .samp_freq_avail_len = 1, \ + .samp_freq_avail = { \ + { AD4130_MAX_ODR, (_odr_div) }, \ + }, \ +} + +static const struct ad4130_filter_config ad4130_filter_configs[] = { + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4, 1, 10), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4_SINC1, 11, 10), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3, 1, 2047), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_REJ60, 1, 2047), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_SINC1, 10, 2047), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF1, 92), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF2, 100), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF3, 124), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF4, 148), +}; + +static const char * const ad4130_filter_modes_str[] = { + [AD4130_FILTER_SINC4] = "sinc4", + [AD4130_FILTER_SINC4_SINC1] = "sinc4+sinc1", + [AD4130_FILTER_SINC3] = "sinc3", + [AD4130_FILTER_SINC3_REJ60] = "sinc3+rej60", + [AD4130_FILTER_SINC3_SINC1] = "sinc3+sinc1", + [AD4130_FILTER_SINC3_PF1] = "sinc3+pf1", + [AD4130_FILTER_SINC3_PF2] = "sinc3+pf2", + [AD4130_FILTER_SINC3_PF3] = "sinc3+pf3", + [AD4130_FILTER_SINC3_PF4] = "sinc3+pf4", +}; + +static int ad4130_get_reg_size(struct ad4130_state *st, unsigned int reg, + unsigned int *size) +{ + if (reg >= ARRAY_SIZE(ad4130_reg_size)) + return -EINVAL; + + *size = ad4130_reg_size[reg]; + + return 0; +} + +static unsigned int ad4130_data_reg_size(struct ad4130_state *st) +{ + unsigned int data_reg_size; + int ret; + + ret = ad4130_get_reg_size(st, AD4130_DATA_REG, &data_reg_size); + if (ret) + return 0; + + return data_reg_size; +} + +static unsigned int ad4130_resolution(struct ad4130_state *st) +{ + return ad4130_data_reg_size(st) * BITS_PER_BYTE; +} + +static int ad4130_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct ad4130_state *st = context; + unsigned int size; + int ret; + + ret = ad4130_get_reg_size(st, reg, &size); + if (ret) + return ret; + + st->reg_write_tx_buf[0] = reg; + + switch (size) { + case 3: + put_unaligned_be24(val, &st->reg_write_tx_buf[1]); + break; + case 2: + put_unaligned_be16(val, &st->reg_write_tx_buf[1]); + break; + case 1: + st->reg_write_tx_buf[1] = val; + break; + default: + return -EINVAL; + } + + return spi_write(st->spi, st->reg_write_tx_buf, size + 1); +} + +static int ad4130_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct ad4130_state *st = context; + struct spi_transfer t[] = { + { + .tx_buf = st->reg_read_tx_buf, + .len = sizeof(st->reg_read_tx_buf), + }, + { + .rx_buf = st->reg_read_rx_buf, + }, + }; + unsigned int size; + int ret; + + ret = ad4130_get_reg_size(st, reg, &size); + if (ret) + return ret; + + st->reg_read_tx_buf[0] = AD4130_COMMS_READ_MASK | reg; + t[1].len = size; + + ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); + if (ret) + return ret; + + switch (size) { + case 3: + *val = get_unaligned_be24(st->reg_read_rx_buf); + break; + case 2: + *val = get_unaligned_be16(st->reg_read_rx_buf); + break; + case 1: + *val = st->reg_read_rx_buf[0]; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct regmap_config ad4130_regmap_config = { + .reg_read = ad4130_reg_read, + .reg_write = ad4130_reg_write, +}; + +static int ad4130_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad4130_state *st = gpiochip_get_data(gc); + unsigned int i; + + /* + * Output-only GPIO functionality is available on pins AIN2 through + * AIN5. If these pins are used for anything else, do not expose them. + */ + for (i = 0; i < ngpios; i++) { + unsigned int pin = i + AD4130_AIN2_P1; + bool valid = st->pins_fn[pin] == AD4130_PIN_FN_NONE; + + __assign_bit(i, valid_mask, valid); + } + + return 0; +} + +static int ad4130_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static void ad4130_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct ad4130_state *st = gpiochip_get_data(gc); + unsigned int mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK, + BIT(offset)); + + regmap_update_bits(st->regmap, AD4130_IO_CONTROL_REG, mask, + value ? mask : 0); +} + +static int ad4130_set_mode(struct ad4130_state *st, enum ad4130_mode mode) +{ + return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG, + AD4130_ADC_CONTROL_MODE_MASK, + FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, mode)); +} + +static int ad4130_set_watermark_interrupt_en(struct ad4130_state *st, bool en) +{ + return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_WM_INT_EN_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_WM_INT_EN_MASK, en)); +} + +static unsigned int ad4130_watermark_reg_val(unsigned int val) +{ + if (val == AD4130_FIFO_SIZE) + val = AD4130_WATERMARK_256; + + return val; +} + +static int ad4130_set_fifo_mode(struct ad4130_state *st, + enum ad4130_fifo_mode mode) +{ + return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_MODE_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_MODE_MASK, mode)); +} + +static void ad4130_push_fifo_data(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int data_reg_size = ad4130_data_reg_size(st); + unsigned int transfer_len = st->effective_watermark * data_reg_size; + unsigned int set_size = st->num_enabled_channels * data_reg_size; + unsigned int i; + int ret; + + st->fifo_tx_buf[1] = ad4130_watermark_reg_val(st->effective_watermark); + st->fifo_xfer[1].len = transfer_len; + + ret = spi_sync(st->spi, &st->fifo_msg); + if (ret) + return; + + for (i = 0; i < transfer_len; i += set_size) + iio_push_to_buffers(indio_dev, &st->fifo_rx_buf[i]); +} + +static irqreturn_t ad4130_irq_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct ad4130_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + ad4130_push_fifo_data(indio_dev); + else + complete(&st->completion); + + return IRQ_HANDLED; +} + +static int ad4130_find_slot(struct ad4130_state *st, + struct ad4130_setup_info *target_setup_info, + unsigned int *slot, bool *overwrite) +{ + unsigned int i; + + *slot = AD4130_INVALID_SLOT; + *overwrite = false; + + for (i = 0; i < AD4130_MAX_SETUPS; i++) { + struct ad4130_slot_info *slot_info = &st->slots_info[i]; + + /* Immediately accept a matching setup info. */ + if (!memcmp(target_setup_info, &slot_info->setup, + sizeof(*target_setup_info))) { + *slot = i; + return 0; + } + + /* Ignore all setups which are used by enabled channels. */ + if (slot_info->enabled_channels) + continue; + + /* Find the least used slot. */ + if (*slot == AD4130_INVALID_SLOT || + slot_info->channels < st->slots_info[*slot].channels) + *slot = i; + } + + if (*slot == AD4130_INVALID_SLOT) + return -EINVAL; + + *overwrite = true; + + return 0; +} + +static void ad4130_unlink_channel(struct ad4130_state *st, unsigned int channel) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_slot_info *slot_info = &st->slots_info[chan_info->slot]; + + chan_info->slot = AD4130_INVALID_SLOT; + slot_info->channels--; +} + +static int ad4130_unlink_slot(struct ad4130_state *st, unsigned int slot) +{ + unsigned int i; + + for (i = 0; i < AD4130_MAX_CHANNELS; i++) { + struct ad4130_chan_info *chan_info = &st->chans_info[i]; + + if (!chan_info->initialized || chan_info->slot != slot) + continue; + + ad4130_unlink_channel(st, i); + } + + return 0; +} + +static int ad4130_link_channel_slot(struct ad4130_state *st, + unsigned int channel, unsigned int slot) +{ + struct ad4130_slot_info *slot_info = &st->slots_info[slot]; + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + int ret; + + ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel), + AD4130_CHANNEL_SETUP_MASK, + FIELD_PREP(AD4130_CHANNEL_SETUP_MASK, slot)); + if (ret) + return ret; + + chan_info->slot = slot; + slot_info->channels++; + + return 0; +} + +static int ad4130_write_slot_setup(struct ad4130_state *st, + unsigned int slot, + struct ad4130_setup_info *setup_info) +{ + unsigned int val; + int ret; + + val = FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout0_val) | + FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout1_val) | + FIELD_PREP(AD4130_CONFIG_BURNOUT_MASK, setup_info->burnout) | + FIELD_PREP(AD4130_CONFIG_REF_BUFP_MASK, setup_info->ref_bufp) | + FIELD_PREP(AD4130_CONFIG_REF_BUFM_MASK, setup_info->ref_bufm) | + FIELD_PREP(AD4130_CONFIG_REF_SEL_MASK, setup_info->ref_sel) | + FIELD_PREP(AD4130_CONFIG_PGA_MASK, setup_info->pga); + + ret = regmap_write(st->regmap, AD4130_CONFIG_X_REG(slot), val); + if (ret) + return ret; + + val = FIELD_PREP(AD4130_FILTER_MODE_MASK, setup_info->filter_mode) | + FIELD_PREP(AD4130_FILTER_SELECT_MASK, setup_info->fs); + + ret = regmap_write(st->regmap, AD4130_FILTER_X_REG(slot), val); + if (ret) + return ret; + + memcpy(&st->slots_info[slot].setup, setup_info, sizeof(*setup_info)); + + return 0; +} + +static int ad4130_write_channel_setup(struct ad4130_state *st, + unsigned int channel, bool on_enable) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + bool overwrite; + int slot; + int ret; + + /* + * The following cases need to be handled. + * + * 1. Enabled and linked channel with setup changes: + * - Find a slot. If not possible, return error. + * - Unlink channel from current slot. + * - If the slot has channels linked to it, unlink all channels, and + * write the new setup to it. + * - Link channel to new slot. + * + * 2. Soon to be enabled and unlinked channel: + * - Find a slot. If not possible, return error. + * - If the slot has channels linked to it, unlink all channels, and + * write the new setup to it. + * - Link channel to the slot. + * + * 3. Disabled and linked channel with setup changes: + * - Unlink channel from current slot. + * + * 4. Soon to be enabled and linked channel: + * 5. Disabled and unlinked channel with setup changes: + * - Do nothing. + */ + + /* Case 4 */ + if (on_enable && chan_info->slot != AD4130_INVALID_SLOT) + return 0; + + if (!on_enable && !chan_info->enabled) { + if (chan_info->slot != AD4130_INVALID_SLOT) + /* Case 3 */ + ad4130_unlink_channel(st, channel); + + /* Cases 3 & 5 */ + return 0; + } + + /* Cases 1 & 2 */ + ret = ad4130_find_slot(st, setup_info, &slot, &overwrite); + if (ret) + return ret; + + if (chan_info->slot != AD4130_INVALID_SLOT) + /* Case 1 */ + ad4130_unlink_channel(st, channel); + + if (overwrite) { + ret = ad4130_unlink_slot(st, slot); + if (ret) + return ret; + + ret = ad4130_write_slot_setup(st, slot, setup_info); + if (ret) + return ret; + } + + return ad4130_link_channel_slot(st, channel, slot); +} + +static int ad4130_set_channel_enable(struct ad4130_state *st, + unsigned int channel, bool status) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_slot_info *slot_info; + int ret; + + if (chan_info->enabled == status) + return 0; + + if (status) { + ret = ad4130_write_channel_setup(st, channel, true); + if (ret) + return ret; + } + + slot_info = &st->slots_info[chan_info->slot]; + + ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel), + AD4130_CHANNEL_EN_MASK, + FIELD_PREP(AD4130_CHANNEL_EN_MASK, status)); + if (ret) + return ret; + + slot_info->enabled_channels += status ? 1 : -1; + chan_info->enabled = status; + + return 0; +} + +/* + * Table 58. FILTER_MODE_n bits and Filter Types of the datasheet describes + * the relation between filter mode, ODR and FS. + * + * Notice that the max ODR of each filter mode is not necessarily the + * absolute max ODR supported by the chip. + * + * The ODR divider is not explicitly specified, but it can be deduced based + * on the ODR range of each filter mode. + * + * For example, for Sinc4+Sinc1, max ODR is 218.18. That means that the + * absolute max ODR is divided by 11 to achieve the max ODR of this filter + * mode. + * + * The formulas for converting between ODR and FS for a specific filter + * mode can be deduced from the same table. + * + * Notice that FS = 1 actually means max ODR, and that ODR decreases by + * (maximum ODR / maximum FS) for each increment of FS. + * + * odr = MAX_ODR / odr_div * (1 - (fs - 1) / fs_max) <=> + * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=> + * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=> + * odr = MAX_ODR * (fs_max - fs + 1) / (fs_max * odr_div) + * (used in ad4130_fs_to_freq) + * + * For the opposite formula, FS can be extracted from the last one. + * + * MAX_ODR * (fs_max - fs + 1) = fs_max * odr_div * odr <=> + * fs_max - fs + 1 = fs_max * odr_div * odr / MAX_ODR <=> + * fs = 1 + fs_max - fs_max * odr_div * odr / MAX_ODR + * (used in ad4130_fs_to_freq) + */ + +static void ad4130_freq_to_fs(enum ad4130_filter_mode filter_mode, + int val, int val2, unsigned int *fs) +{ + const struct ad4130_filter_config *filter_config = + &ad4130_filter_configs[filter_mode]; + u64 dividend, divisor; + int temp; + + dividend = filter_config->fs_max * filter_config->odr_div * + ((u64)val * NANO + val2); + divisor = (u64)AD4130_MAX_ODR * NANO; + + temp = AD4130_FILTER_SELECT_MIN + filter_config->fs_max - + DIV64_U64_ROUND_CLOSEST(dividend, divisor); + + if (temp < AD4130_FILTER_SELECT_MIN) + temp = AD4130_FILTER_SELECT_MIN; + else if (temp > filter_config->fs_max) + temp = filter_config->fs_max; + + *fs = temp; +} + +static void ad4130_fs_to_freq(enum ad4130_filter_mode filter_mode, + unsigned int fs, int *val, int *val2) +{ + const struct ad4130_filter_config *filter_config = + &ad4130_filter_configs[filter_mode]; + unsigned int dividend, divisor; + u64 temp; + + dividend = (filter_config->fs_max - fs + AD4130_FILTER_SELECT_MIN) * + AD4130_MAX_ODR; + divisor = filter_config->fs_max * filter_config->odr_div; + + temp = div_u64((u64)dividend * NANO, divisor); + *val = div_u64_rem(temp, NANO, val2); +} + +static int ad4130_set_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + enum ad4130_filter_mode old_filter_mode; + int freq_val, freq_val2; + unsigned int old_fs; + int ret = 0; + + mutex_lock(&st->lock); + if (setup_info->filter_mode == val) + goto out; + + old_fs = setup_info->fs; + old_filter_mode = setup_info->filter_mode; + + /* + * When switching between filter modes, try to match the ODR as + * close as possible. To do this, convert the current FS into ODR + * using the old filter mode, then convert it back into FS using + * the new filter mode. + */ + ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs, + &freq_val, &freq_val2); + + ad4130_freq_to_fs(val, freq_val, freq_val2, &setup_info->fs); + + setup_info->filter_mode = val; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) { + setup_info->fs = old_fs; + setup_info->filter_mode = old_filter_mode; + } + + out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_get_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + enum ad4130_filter_mode filter_mode; + + mutex_lock(&st->lock); + filter_mode = setup_info->filter_mode; + mutex_unlock(&st->lock); + + return filter_mode; +} + +static const struct iio_enum ad4130_filter_mode_enum = { + .items = ad4130_filter_modes_str, + .num_items = ARRAY_SIZE(ad4130_filter_modes_str), + .set = ad4130_set_filter_mode, + .get = ad4130_get_filter_mode, +}; + +static const struct iio_chan_spec_ext_info ad4130_filter_mode_ext_info[] = { + IIO_ENUM("filter_mode", IIO_SEPARATE, &ad4130_filter_mode_enum), + IIO_ENUM_AVAILABLE("filter_mode", IIO_SHARED_BY_TYPE, + &ad4130_filter_mode_enum), + { } +}; + +static const struct iio_chan_spec ad4130_channel_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .differential = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .ext_info = ad4130_filter_mode_ext_info, + .scan_type = { + .sign = 'u', + .endianness = IIO_BE, + }, +}; + +static int ad4130_set_channel_pga(struct ad4130_state *st, unsigned int channel, + int val, int val2) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + unsigned int pga, old_pga; + int ret = 0; + + for (pga = 0; pga < AD4130_MAX_PGA; pga++) + if (val == st->scale_tbls[setup_info->ref_sel][pga][0] && + val2 == st->scale_tbls[setup_info->ref_sel][pga][1]) + break; + + if (pga == AD4130_MAX_PGA) + return -EINVAL; + + mutex_lock(&st->lock); + if (pga == setup_info->pga) + goto out; + + old_pga = setup_info->pga; + setup_info->pga = pga; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) + setup_info->pga = old_pga; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_set_channel_freq(struct ad4130_state *st, + unsigned int channel, int val, int val2) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + unsigned int fs, old_fs; + int ret = 0; + + mutex_lock(&st->lock); + old_fs = setup_info->fs; + + ad4130_freq_to_fs(setup_info->filter_mode, val, val2, &fs); + + if (fs == setup_info->fs) + goto out; + + setup_info->fs = fs; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) + setup_info->fs = old_fs; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int _ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel, + int *val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + ret = ad4130_set_channel_enable(st, channel, true); + if (ret) + return ret; + + reinit_completion(&st->completion); + + ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS); + if (ret) + return ret; + + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + ret = ad4130_set_mode(st, AD4130_MODE_IDLE); + if (ret) + return ret; + + ret = regmap_read(st->regmap, AD4130_DATA_REG, val); + if (ret) + return ret; + + ret = ad4130_set_channel_enable(st, channel, false); + if (ret) + return ret; + + return IIO_VAL_INT; +} + +static int ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel, + int *val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + ret = _ad4130_read_sample(indio_dev, channel, val); + mutex_unlock(&st->lock); + + iio_device_release_direct_mode(indio_dev); + + return ret; +} + +static int ad4130_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4130_read_sample(indio_dev, channel, val); + case IIO_CHAN_INFO_SCALE: + mutex_lock(&st->lock); + *val = st->scale_tbls[setup_info->ref_sel][setup_info->pga][0]; + *val2 = st->scale_tbls[setup_info->ref_sel][setup_info->pga][1]; + mutex_unlock(&st->lock); + + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + *val = st->bipolar ? -BIT(chan->scan_type.realbits - 1) : 0; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&st->lock); + ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs, + val, val2); + mutex_unlock(&st->lock); + + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int ad4130_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + const struct ad4130_filter_config *filter_config; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)st->scale_tbls[setup_info->ref_sel]; + *length = ARRAY_SIZE(st->scale_tbls[setup_info->ref_sel]) * 2; + + *type = IIO_VAL_INT_PLUS_NANO; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&st->lock); + filter_config = &ad4130_filter_configs[setup_info->filter_mode]; + mutex_unlock(&st->lock); + + *vals = (int *)filter_config->samp_freq_avail; + *length = filter_config->samp_freq_avail_len * 2; + *type = IIO_VAL_FRACTIONAL; + + return filter_config->samp_freq_avail_type; + default: + return -EINVAL; + } +} + +static int ad4130_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_SCALE: + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int ad4130_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + return ad4130_set_channel_pga(st, channel, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4130_set_channel_freq(st, channel, val, val2); + default: + return -EINVAL; + } +} + +static int ad4130_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4130_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static int ad4130_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel; + unsigned int val = 0; + int ret; + + mutex_lock(&st->lock); + + for_each_set_bit(channel, scan_mask, indio_dev->num_channels) { + ret = ad4130_set_channel_enable(st, channel, true); + if (ret) + goto out; + + val++; + } + + st->num_enabled_channels = val; + +out: + mutex_unlock(&st->lock); + + return 0; +} + +static int ad4130_set_fifo_watermark(struct iio_dev *indio_dev, unsigned int val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int eff; + int ret; + + if (val > AD4130_FIFO_SIZE) + return -EINVAL; + + eff = val * st->num_enabled_channels; + if (eff > AD4130_FIFO_SIZE) + /* + * Always set watermark to a multiple of the number of + * enabled channels to avoid making the FIFO unaligned. + */ + eff = rounddown(AD4130_FIFO_SIZE, st->num_enabled_channels); + + mutex_lock(&st->lock); + + ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_WM_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_WM_MASK, + ad4130_watermark_reg_val(eff))); + if (ret) + goto out; + + st->effective_watermark = eff; + st->watermark = val; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_info ad4130_info = { + .read_raw = ad4130_read_raw, + .read_avail = ad4130_read_avail, + .write_raw_get_fmt = ad4130_write_raw_get_fmt, + .write_raw = ad4130_write_raw, + .update_scan_mode = ad4130_update_scan_mode, + .hwfifo_set_watermark = ad4130_set_fifo_watermark, + .debugfs_reg_access = ad4130_reg_access, +}; + +static int ad4130_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->lock); + + ret = ad4130_set_watermark_interrupt_en(st, true); + if (ret) + goto out; + + ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger); + if (ret) + goto out; + + ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM); + if (ret) + goto out; + + ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS); + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int i; + int ret; + + mutex_lock(&st->lock); + + ret = ad4130_set_mode(st, AD4130_MODE_IDLE); + if (ret) + goto out; + + ret = irq_set_irq_type(st->spi->irq, st->irq_trigger); + if (ret) + goto out; + + ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED); + if (ret) + goto out; + + ret = ad4130_set_watermark_interrupt_en(st, false); + if (ret) + goto out; + + /* + * update_scan_mode() is not called in the disable path, disable all + * channels here. + */ + for (i = 0; i < indio_dev->num_channels; i++) { + ret = ad4130_set_channel_enable(st, i, false); + if (ret) + goto out; + } + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_buffer_setup_ops ad4130_buffer_ops = { + .postenable = ad4130_buffer_postenable, + .predisable = ad4130_buffer_predisable, +}; + +static ssize_t hwfifo_watermark_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev)); + unsigned int val; + + mutex_lock(&st->lock); + val = st->watermark; + mutex_unlock(&st->lock); + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t hwfifo_enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev)); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD4130_FIFO_CONTROL_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(AD4130_FIFO_CONTROL_MODE_MASK, val); + + return sysfs_emit(buf, "%d\n", val != AD4130_FIFO_MODE_DISABLED); +} + +static ssize_t hwfifo_watermark_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", "1"); +} + +static ssize_t hwfifo_watermark_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", __stringify(AD4130_FIFO_SIZE)); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); + +static const struct attribute *ad4130_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark.dev_attr.attr, + &iio_dev_attr_hwfifo_enabled.dev_attr.attr, + NULL +}; + +static int _ad4130_find_table_index(const unsigned int *tbl, size_t len, + unsigned int val) +{ + unsigned int i; + + for (i = 0; i < len; i++) + if (tbl[i] == val) + return i; + + return -EINVAL; +} + +#define ad4130_find_table_index(table, val) \ + _ad4130_find_table_index(table, ARRAY_SIZE(table), val) + +static int ad4130_get_ref_voltage(struct ad4130_state *st, + enum ad4130_ref_sel ref_sel) +{ + switch (ref_sel) { + case AD4130_REF_REFIN1: + return regulator_get_voltage(st->regulators[2].consumer); + case AD4130_REF_REFIN2: + return regulator_get_voltage(st->regulators[3].consumer); + case AD4130_REF_AVDD_AVSS: + return regulator_get_voltage(st->regulators[0].consumer); + case AD4130_REF_REFOUT_AVSS: + return st->int_ref_uv; + default: + return -EINVAL; + } +} + +static int ad4130_parse_fw_setup(struct ad4130_state *st, + struct fwnode_handle *child, + struct ad4130_setup_info *setup_info) +{ + struct device *dev = &st->spi->dev; + u32 tmp; + int ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,excitation-current-0-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid excitation current %unA\n", tmp); + setup_info->iout0_val = ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,excitation-current-1-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid excitation current %unA\n", tmp); + setup_info->iout1_val = ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,burnout-current-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_burnout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid burnout current %unA\n", tmp); + setup_info->burnout = ret; + + setup_info->ref_bufp = fwnode_property_read_bool(child, "adi,buffered-positive"); + setup_info->ref_bufm = fwnode_property_read_bool(child, "adi,buffered-negative"); + + setup_info->ref_sel = AD4130_REF_REFIN1; + fwnode_property_read_u32(child, "adi,reference-select", + &setup_info->ref_sel); + if (setup_info->ref_sel >= AD4130_REF_SEL_MAX) + return dev_err_probe(dev, -EINVAL, + "Invalid reference selected %u\n", + setup_info->ref_sel); + + if (setup_info->ref_sel == AD4130_REF_REFOUT_AVSS) + st->int_ref_en = true; + + ret = ad4130_get_ref_voltage(st, setup_info->ref_sel); + if (ret < 0) + return dev_err_probe(dev, ret, "Cannot use reference %u\n", + setup_info->ref_sel); + + return 0; +} + +static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_DIFF_INPUTS) + return dev_err_probe(dev, -EINVAL, + "Invalid diffreential channel %u\n", pin); + + if (pin >= AD4130_MAX_ANALOG_PINS) + return 0; + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_DIFF; + + return 0; +} + +static int ad4130_validate_diff_channels(struct ad4130_state *st, + u32 *pins, unsigned int len) +{ + unsigned int i; + int ret; + + for (i = 0; i < len; i++) { + ret = ad4130_validate_diff_channel(st, pins[i]); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_validate_excitation_pin(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, + "Invalid excitation pin %u\n", pin); + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_EXCITATION; + + return 0; +} + +static int ad4130_validate_vbias_pin(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, "Invalid vbias pin %u\n", + pin); + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_VBIAS; + + return 0; +} + +static int ad4130_validate_vbias_pins(struct ad4130_state *st, + u32 *pins, unsigned int len) +{ + unsigned int i; + int ret; + + for (i = 0; i < st->num_vbias_pins; i++) { + ret = ad4130_validate_vbias_pin(st, pins[i]); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_parse_fw_channel(struct iio_dev *indio_dev, + struct fwnode_handle *child) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int resolution = ad4130_resolution(st); + unsigned int index = indio_dev->num_channels++; + struct device *dev = &st->spi->dev; + struct ad4130_chan_info *chan_info; + struct iio_chan_spec *chan; + u32 pins[2]; + int ret; + + if (index >= AD4130_MAX_CHANNELS) + return dev_err_probe(dev, -EINVAL, "Too many channels\n"); + + chan = &st->chans[index]; + chan_info = &st->chans_info[index]; + + *chan = ad4130_channel_template; + chan->scan_type.realbits = resolution; + chan->scan_type.storagebits = resolution; + chan->scan_index = index; + + chan_info->slot = AD4130_INVALID_SLOT; + chan_info->setup.fs = AD4130_FILTER_SELECT_MIN; + chan_info->initialized = true; + + ret = fwnode_property_read_u32_array(child, "diff-channels", pins, + ARRAY_SIZE(pins)); + if (ret) + return ret; + + ret = ad4130_validate_diff_channels(st, pins, ARRAY_SIZE(pins)); + if (ret) + return ret; + + chan->channel = pins[0]; + chan->channel2 = pins[1]; + + ret = ad4130_parse_fw_setup(st, child, &chan_info->setup); + if (ret) + return ret; + + fwnode_property_read_u32(child, "adi,excitation-pin-0", + &chan_info->iout0); + if (chan_info->setup.iout0_val != AD4130_IOUT_OFF) { + ret = ad4130_validate_excitation_pin(st, chan_info->iout0); + if (ret) + return ret; + } + + fwnode_property_read_u32(child, "adi,excitation-pin-1", + &chan_info->iout1); + if (chan_info->setup.iout1_val != AD4130_IOUT_OFF) { + ret = ad4130_validate_excitation_pin(st, chan_info->iout1); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_parse_fw_children(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + struct fwnode_handle *child; + int ret; + + indio_dev->channels = st->chans; + + device_for_each_child_node(dev, child) { + ret = ad4130_parse_fw_channel(indio_dev, child); + if (ret) { + fwnode_handle_put(child); + return ret; + } + } + + return 0; +} + +static int ad4310_parse_fw(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + u32 ext_clk_freq = AD4130_MCLK_FREQ_76_8KHZ; + unsigned int i; + int avdd_uv; + int irq; + int ret; + + st->mclk = devm_clk_get_optional(dev, "mclk"); + if (IS_ERR(st->mclk)) + return dev_err_probe(dev, PTR_ERR(st->mclk), + "Failed to get mclk\n"); + + st->int_pin_sel = AD4130_INT_PIN_INT; + + for (i = 0; i < ARRAY_SIZE(ad4130_int_pin_names); i++) { + irq = fwnode_irq_get_byname(dev_fwnode(dev), + ad4130_int_pin_names[i]); + if (irq > 0) { + st->int_pin_sel = i; + break; + } + } + + if (st->int_pin_sel == AD4130_INT_PIN_DOUT) + return dev_err_probe(dev, -EINVAL, + "Cannot use DOUT as interrupt pin\n"); + + if (st->int_pin_sel == AD4130_INT_PIN_P2) + st->pins_fn[AD4130_AIN3_P2] = AD4130_PIN_FN_SPECIAL; + + device_property_read_u32(dev, "adi,ext-clk-freq-hz", &ext_clk_freq); + if (ext_clk_freq != AD4130_MCLK_FREQ_153_6KHZ && + ext_clk_freq != AD4130_MCLK_FREQ_76_8KHZ) + return dev_err_probe(dev, -EINVAL, + "Invalid external clock frequency %u\n", + ext_clk_freq); + + if (st->mclk && ext_clk_freq == AD4130_MCLK_FREQ_153_6KHZ) + st->mclk_sel = AD4130_MCLK_153_6KHZ_EXT; + else if (st->mclk) + st->mclk_sel = AD4130_MCLK_76_8KHZ_EXT; + else + st->mclk_sel = AD4130_MCLK_76_8KHZ; + + if (st->int_pin_sel == AD4130_INT_PIN_CLK && + st->mclk_sel != AD4130_MCLK_76_8KHZ) + return dev_err_probe(dev, -EINVAL, + "Invalid clock %u for interrupt pin %u\n", + st->mclk_sel, st->int_pin_sel); + + st->int_ref_uv = AD4130_INT_REF_2_5V; + + /* + * When the AVDD supply is set to below 2.5V the internal reference of + * 1.25V should be selected. + * See datasheet page 37, section ADC REFERENCE. + */ + avdd_uv = regulator_get_voltage(st->regulators[0].consumer); + if (avdd_uv > 0 && avdd_uv < AD4130_INT_REF_2_5V) + st->int_ref_uv = AD4130_INT_REF_1_25V; + + st->bipolar = device_property_read_bool(dev, "adi,bipolar"); + + ret = device_property_count_u32(dev, "adi,vbias-pins"); + if (ret > 0) { + if (ret > AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, + "Too many vbias pins %u\n", ret); + + st->num_vbias_pins = ret; + + ret = device_property_read_u32_array(dev, "adi,vbias-pins", + st->vbias_pins, + st->num_vbias_pins); + if (ret) + return dev_err_probe(dev, ret, + "Failed to read vbias pins\n"); + + ret = ad4130_validate_vbias_pins(st, st->vbias_pins, + st->num_vbias_pins); + if (ret) + return ret; + } + + ret = ad4130_parse_fw_children(indio_dev); + if (ret) + return ret; + + return 0; +} + +static void ad4130_fill_scale_tbls(struct ad4130_state *st) +{ + unsigned int pow = ad4130_resolution(st) - st->bipolar; + unsigned int i, j; + + for (i = 0; i < AD4130_REF_SEL_MAX; i++) { + int ret; + u64 nv; + + ret = ad4130_get_ref_voltage(st, i); + if (ret < 0) + continue; + + nv = (u64)ret * NANO; + + for (j = 0; j < AD4130_MAX_PGA; j++) + st->scale_tbls[i][j][1] = div_u64(nv >> (pow + j), MILLI); + } +} + +static void ad4130_clk_disable_unprepare(void *clk) +{ + clk_disable_unprepare(clk); +} + +static int ad4130_set_mclk_sel(struct ad4130_state *st, + enum ad4130_mclk_sel mclk_sel) +{ + return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG, + AD4130_ADC_CONTROL_MCLK_SEL_MASK, + FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK, + mclk_sel)); +} + +static unsigned long ad4130_int_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return AD4130_MCLK_FREQ_76_8KHZ; +} + +static int ad4130_int_clk_is_enabled(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + + return st->mclk_sel == AD4130_MCLK_76_8KHZ_OUT; +} + +static int ad4130_int_clk_prepare(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + int ret; + + ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ_OUT); + if (ret) + return ret; + + st->mclk_sel = AD4130_MCLK_76_8KHZ_OUT; + + return 0; +} + +static void ad4130_int_clk_unprepare(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + int ret; + + ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ); + if (ret) + return; + + st->mclk_sel = AD4130_MCLK_76_8KHZ; +} + +static const struct clk_ops ad4130_int_clk_ops = { + .recalc_rate = ad4130_int_clk_recalc_rate, + .is_enabled = ad4130_int_clk_is_enabled, + .prepare = ad4130_int_clk_prepare, + .unprepare = ad4130_int_clk_unprepare, +}; + +static int ad4130_setup_int_clk(struct ad4130_state *st) +{ + struct device *dev = &st->spi->dev; + struct device_node *of_node = dev_of_node(dev); + struct clk_init_data init; + const char *clk_name; + struct clk *clk; + + if (st->int_pin_sel == AD4130_INT_PIN_CLK || + st->mclk_sel != AD4130_MCLK_76_8KHZ) + return 0; + + if (!of_node) + return 0; + + clk_name = of_node->name; + of_property_read_string(of_node, "clock-output-names", &clk_name); + + init.name = clk_name; + init.ops = &ad4130_int_clk_ops; + + st->int_clk_hw.init = &init; + clk = devm_clk_register(dev, &st->int_clk_hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + return of_clk_add_provider(of_node, of_clk_src_simple_get, clk); +} + +static int ad4130_setup(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + unsigned int int_ref_val; + unsigned long rate = AD4130_MCLK_FREQ_76_8KHZ; + unsigned int val; + unsigned int i; + int ret; + + if (st->mclk_sel == AD4130_MCLK_153_6KHZ_EXT) + rate = AD4130_MCLK_FREQ_153_6KHZ; + + ret = clk_set_rate(st->mclk, rate); + if (ret) + return ret; + + ret = clk_prepare_enable(st->mclk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, ad4130_clk_disable_unprepare, + st->mclk); + if (ret) + return ret; + + if (st->int_ref_uv == AD4130_INT_REF_2_5V) + int_ref_val = AD4130_INT_REF_VAL_2_5V; + else + int_ref_val = AD4130_INT_REF_VAL_1_25V; + + /* Switch to SPI 4-wire mode. */ + val = FIELD_PREP(AD4130_ADC_CONTROL_CSB_EN_MASK, 1); + val |= FIELD_PREP(AD4130_ADC_CONTROL_BIPOLAR_MASK, st->bipolar); + val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_EN_MASK, st->int_ref_en); + val |= FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, AD4130_MODE_IDLE); + val |= FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK, st->mclk_sel); + val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_VAL_MASK, int_ref_val); + + ret = regmap_write(st->regmap, AD4130_ADC_CONTROL_REG, val); + if (ret) + return ret; + + /* + * Configure all GPIOs for output. If configured, the interrupt function + * of P2 takes priority over the GPIO out function. + */ + val = AD4130_IO_CONTROL_GPIO_CTRL_MASK; + val |= FIELD_PREP(AD4130_IO_CONTROL_INT_PIN_SEL_MASK, st->int_pin_sel); + + ret = regmap_write(st->regmap, AD4130_IO_CONTROL_REG, val); + if (ret) + return ret; + + val = 0; + for (i = 0; i < st->num_vbias_pins; i++) + val |= BIT(st->vbias_pins[i]); + + ret = regmap_write(st->regmap, AD4130_VBIAS_REG, val); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_HEADER_MASK, 0); + if (ret) + return ret; + + /* FIFO watermark interrupt starts out as enabled, disable it. */ + ret = ad4130_set_watermark_interrupt_en(st, false); + if (ret) + return ret; + + /* Setup channels. */ + for (i = 0; i < indio_dev->num_channels; i++) { + struct ad4130_chan_info *chan_info = &st->chans_info[i]; + struct iio_chan_spec *chan = &st->chans[i]; + unsigned int val; + + val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK, chan->channel) | + FIELD_PREP(AD4130_CHANNEL_AINM_MASK, chan->channel2) | + FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK, chan_info->iout0) | + FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK, chan_info->iout1); + + ret = regmap_write(st->regmap, AD4130_CHANNEL_X_REG(i), val); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_soft_reset(struct ad4130_state *st) +{ + int ret; + + ret = spi_write(st->spi, st->reset_buf, sizeof(st->reset_buf)); + if (ret) + return ret; + + fsleep(AD4130_RESET_SLEEP_US); + + return 0; +} + +static void ad4130_disable_regulators(void *data) +{ + struct ad4130_state *st = data; + + regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); +} + +static int ad4130_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct iio_dev *indio_dev; + struct ad4130_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + memset(st->reset_buf, 0xff, sizeof(st->reset_buf)); + init_completion(&st->completion); + mutex_init(&st->lock); + st->spi = spi; + + /* + * Xfer: [ XFR1 ] [ XFR2 ] + * Master: 0x7D N ...................... + * Slave: ...... DATA1 DATA2 ... DATAN + */ + st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG; + st->fifo_xfer[0].tx_buf = st->fifo_tx_buf; + st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf); + st->fifo_xfer[1].rx_buf = st->fifo_rx_buf; + spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer, + ARRAY_SIZE(st->fifo_xfer)); + + indio_dev->name = AD4130_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad4130_info; + + st->regmap = devm_regmap_init(dev, NULL, st, &ad4130_regmap_config); + if (IS_ERR(st->regmap)) + return PTR_ERR(st->regmap); + + st->regulators[0].supply = "avdd"; + st->regulators[1].supply = "iovdd"; + st->regulators[2].supply = "refin1"; + st->regulators[3].supply = "refin2"; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st->regulators), + st->regulators); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable regulators\n"); + + ret = devm_add_action_or_reset(dev, ad4130_disable_regulators, st); + if (ret) + return dev_err_probe(dev, ret, + "Failed to add regulators disable action\n"); + + ret = ad4130_soft_reset(st); + if (ret) + return ret; + + ret = ad4310_parse_fw(indio_dev); + if (ret) + return ret; + + ret = ad4130_setup(indio_dev); + if (ret) + return ret; + + ret = ad4130_setup_int_clk(st); + if (ret) + return ret; + + ad4130_fill_scale_tbls(st); + + st->gc.owner = THIS_MODULE; + st->gc.label = AD4130_NAME; + st->gc.base = -1; + st->gc.ngpio = AD4130_MAX_GPIOS; + st->gc.parent = dev; + st->gc.can_sleep = true; + st->gc.init_valid_mask = ad4130_gpio_init_valid_mask; + st->gc.get_direction = ad4130_gpio_get_direction; + st->gc.set = ad4130_gpio_set; + + ret = devm_gpiochip_add_data(dev, &st->gc, st); + if (ret) + return ret; + + ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, + &ad4130_buffer_ops, + ad4130_fifo_attributes); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, spi->irq, NULL, + ad4130_irq_handler, IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq\n"); + + /* + * When the chip enters FIFO mode, IRQ polarity is inverted. + * When the chip exits FIFO mode, IRQ polarity returns to normal. + * See datasheet pages: 65, FIFO Watermark Interrupt section, + * and 71, Bit Descriptions for STATUS Register, RDYB. + * Cache the normal and inverted IRQ triggers to set them when + * entering and exiting FIFO mode. + */ + st->irq_trigger = irq_get_trigger_type(spi->irq); + if (st->irq_trigger & IRQF_TRIGGER_RISING) + st->inv_irq_trigger = IRQF_TRIGGER_FALLING; + else if (st->irq_trigger & IRQF_TRIGGER_FALLING) + st->inv_irq_trigger = IRQF_TRIGGER_RISING; + else + return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n", + st->irq_trigger); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id ad4130_of_match[] = { + { + .compatible = "adi,ad4130", + }, + { } +}; +MODULE_DEVICE_TABLE(of, ad4130_of_match); + +static struct spi_driver ad4130_driver = { + .driver = { + .name = AD4130_NAME, + .of_match_table = ad4130_of_match, + }, + .probe = ad4130_probe, +}; +module_spi_driver(ad4130_driver); + +MODULE_AUTHOR("Cosmin Tanislav "); +MODULE_DESCRIPTION("Analog Devices AD4130 SPI driver"); +MODULE_LICENSE("GPL"); -- GitLab From e54ec96c7201507db1b2c053068cda32f3c42cc7 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Mon, 17 Oct 2022 12:02:30 +0530 Subject: [PATCH 0903/1480] staging: iio: frequency: ad9834: merge unnecessary split lines Improve code readability by merging unnecessary split lines that are well within the code-style guidelines post merge. Signed-off-by: Deepak R Varma Acked-by: Julia Lawall Link: https://lore.kernel.org/r/Y0z2/qFe3kW96MTs@debian-BULLSEYE-live-builder-AMD64 Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/ad9834.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 2b4267a87e65e..285df0e489a62 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -331,11 +331,9 @@ static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9834_write, AD9834_REG_PHASE1); static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, ad9834_write, AD9834_PSEL); static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ -static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, - ad9834_write, AD9834_PIN_SW); +static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, ad9834_write, AD9834_PIN_SW); static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, ad9834_write, AD9834_RESET); -static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL, - ad9834_write, AD9834_OPBITEN); +static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL, ad9834_write, AD9834_OPBITEN); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); -- GitLab From e9b96e18cf47133e51f4cb67d9dd9d163abc5f6d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:56 +0100 Subject: [PATCH 0904/1480] iio: accel: adxl367: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Cosmin Tanislav Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-2-jic23@kernel.org --- drivers/iio/accel/adxl367.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 7c7d780407937..d7af3a006a444 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -160,8 +160,6 @@ struct adxl367_state { struct device *dev; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; - /* * Synchronize access to members of driver state, and ensure atomicity * of consecutive regmap operations. @@ -1487,16 +1485,10 @@ static int adxl367_setup(struct adxl367_state *st) return adxl367_set_measure_en(st, true); } -static void adxl367_disable_regulators(void *data) -{ - struct adxl367_state *st = data; - - regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); -} - int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, void *context, struct regmap *regmap, int irq) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct iio_dev *indio_dev; struct adxl367_state *st; int ret; @@ -1520,25 +1512,13 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, indio_dev->info = &adxl367_info; indio_dev->modes = INDIO_DIRECT_MODE; - st->regulators[0].supply = "vdd"; - st->regulators[1].supply = "vddio"; - - ret = devm_regulator_bulk_get(st->dev, ARRAY_SIZE(st->regulators), - st->regulators); + ret = devm_regulator_bulk_get_enable(st->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(st->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); - if (ret) - return dev_err_probe(st->dev, ret, - "Failed to enable regulators\n"); - - ret = devm_add_action_or_reset(st->dev, adxl367_disable_regulators, st); - if (ret) - return dev_err_probe(st->dev, ret, - "Failed to add regulators disable action\n"); - ret = regmap_write(st->regmap, ADXL367_REG_RESET, ADXL367_RESET_CODE); if (ret) return ret; -- GitLab From 5b30e739ceaf37aa5817195a20cd1fa7a4607623 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:58 +0100 Subject: [PATCH 0905/1480] iio: accel: fxls8962af: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Sean Nyekjaer Reviewed-by: Sean Nyekjaer Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-4-jic23@kernel.org --- drivers/iio/accel/fxls8962af-core.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index bf259db281f59..0d672b1469e8d 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -159,7 +159,6 @@ struct fxls8962af_chip_info { struct fxls8962af_data { struct regmap *regmap; const struct fxls8962af_chip_info *chip_info; - struct regulator *vdd_reg; struct { __le16 channels[3]; s64 ts __aligned(8); @@ -1051,13 +1050,6 @@ static irqreturn_t fxls8962af_interrupt(int irq, void *p) return IRQ_NONE; } -static void fxls8962af_regulator_disable(void *data_ptr) -{ - struct fxls8962af_data *data = data_ptr; - - regulator_disable(data->vdd_reg); -} - static void fxls8962af_pm_disable(void *dev_ptr) { struct device *dev = dev_ptr; @@ -1171,20 +1163,10 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) if (ret) return ret; - data->vdd_reg = devm_regulator_get(dev, "vdd"); - if (IS_ERR(data->vdd_reg)) - return dev_err_probe(dev, PTR_ERR(data->vdd_reg), - "Failed to get vdd regulator\n"); - - ret = regulator_enable(data->vdd_reg); - if (ret) { - dev_err(dev, "Failed to enable vdd regulator: %d\n", ret); - return ret; - } - - ret = devm_add_action_or_reset(dev, fxls8962af_regulator_disable, data); + ret = devm_regulator_get_enable(dev, "vdd"); if (ret) - return ret; + return dev_err_probe(dev, ret, + "Failed to get vdd regulator\n"); ret = regmap_read(data->regmap, FXLS8962AF_WHO_AM_I, ®); if (ret) -- GitLab From 1fa4ff1f249983b38394ee79379e028c1c501ae5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:59 +0100 Subject: [PATCH 0906/1480] iio: accel: kxcjk-1013: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-5-jic23@kernel.org --- drivers/iio/accel/kxcjk-1013.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index adc66b3615c0b..e626b6fa8a36a 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -241,7 +241,6 @@ enum kxcjk1013_axis { }; struct kxcjk1013_data { - struct regulator_bulk_data regulators[2]; struct i2c_client *client; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; @@ -1425,16 +1424,10 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, return dev_name(dev); } -static void kxcjk1013_disable_regulators(void *d) -{ - struct kxcjk1013_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - static int kxcjk1013_probe(struct i2c_client *client, const struct i2c_device_id *id) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct kxcjk1013_data *data; struct iio_dev *indio_dev; struct kxcjk_1013_platform_data *pdata; @@ -1461,22 +1454,12 @@ static int kxcjk1013_probe(struct i2c_client *client, return ret; } - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(&client->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, kxcjk1013_disable_regulators, data); - if (ret) - return ret; - /* * A typical delay of 10ms is required for powering up * according to the data sheets of supported chips. -- GitLab From eefa008b1677244d73ba47920172be36570c87c1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:00 +0100 Subject: [PATCH 0907/1480] iio: accel: msa311: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Dmitry Rokosov Reviewed-by: Dmitry Rokosov Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-6-jic23@kernel.org --- drivers/iio/accel/msa311.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c index 2fded37591717..af94d3adf6d81 100644 --- a/drivers/iio/accel/msa311.c +++ b/drivers/iio/accel/msa311.c @@ -351,7 +351,6 @@ static const struct regmap_config msa311_regmap_config = { * @chip_name: Chip name in the format "msa311-%02x" % partid * @new_data_trig: Optional NEW_DATA interrupt driven trigger used * to notify external consumers a new sample is ready - * @vdd: Optional external voltage regulator for the device power supply */ struct msa311_priv { struct regmap *regs; @@ -362,7 +361,6 @@ struct msa311_priv { char *chip_name; struct iio_trigger *new_data_trig; - struct regulator *vdd; }; enum msa311_si { @@ -1146,11 +1144,6 @@ static void msa311_powerdown(void *msa311) msa311_set_pwr_mode(msa311, MSA311_PWR_MODE_SUSPEND); } -static void msa311_vdd_disable(void *vdd) -{ - regulator_disable(vdd); -} - static int msa311_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; @@ -1173,19 +1166,9 @@ static int msa311_probe(struct i2c_client *i2c) mutex_init(&msa311->lock); - msa311->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(msa311->vdd)) - return dev_err_probe(dev, PTR_ERR(msa311->vdd), - "can't get vdd supply\n"); - - err = regulator_enable(msa311->vdd); + err = devm_regulator_get_enable(dev, "vdd"); if (err) - return dev_err_probe(dev, err, "can't enable vdd supply\n"); - - err = devm_add_action_or_reset(dev, msa311_vdd_disable, msa311->vdd); - if (err) - return dev_err_probe(dev, err, - "can't add vdd disable action\n"); + return dev_err_probe(dev, err, "can't get vdd supply\n"); err = msa311_check_partid(msa311); if (err) -- GitLab From 72ce527c7bb599ac1d64ec5393f66a673b75de6b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:01 +0100 Subject: [PATCH 0908/1480] iio: cdc: ad7150: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-7-jic23@kernel.org --- drivers/iio/cdc/ad7150.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c index ebe112b4618b0..1113745890cae 100644 --- a/drivers/iio/cdc/ad7150.c +++ b/drivers/iio/cdc/ad7150.c @@ -536,19 +536,11 @@ static const struct iio_info ad7150_info_no_irq = { .read_raw = &ad7150_read_raw, }; -static void ad7150_reg_disable(void *data) -{ - struct regulator *reg = data; - - regulator_disable(reg); -} - static int ad7150_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ad7150_chip_info *chip; struct iio_dev *indio_dev; - struct regulator *reg; int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); @@ -563,15 +555,7 @@ static int ad7150_probe(struct i2c_client *client, indio_dev->modes = INDIO_DIRECT_MODE; - reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - ret = regulator_enable(reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, ad7150_reg_disable, reg); + ret = devm_regulator_get_enable(&client->dev, "vdd"); if (ret) return ret; -- GitLab From 9e855d77b1ec57704d23e25761a97e6e64abed66 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:02 +0100 Subject: [PATCH 0909/1480] iio: st_sensors: core and lsm9ds0 switch to devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These drivers only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The two regulators were handled separately so also switch to bulk registration. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Linus Walleij Cc: Andy Shevchenko Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-8-jic23@kernel.org --- .../iio/common/st_sensors/st_sensors_core.c | 39 ++--------- drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c | 65 ++----------------- include/linux/iio/common/st_sensors.h | 4 -- 3 files changed, 14 insertions(+), 94 deletions(-) diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 35720c64fea8f..c77d7bdcc1216 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -219,47 +219,22 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) } EXPORT_SYMBOL_NS(st_sensors_set_axis_enable, IIO_ST_SENSORS); -static void st_reg_disable(void *reg) -{ - regulator_disable(reg); -} int st_sensors_power_enable(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); + static const char * const regulator_names[] = { "vdd", "vddio" }; struct device *parent = indio_dev->dev.parent; int err; /* Regulators not mandatory, but if requested we should enable them. */ - pdata->vdd = devm_regulator_get(parent, "vdd"); - if (IS_ERR(pdata->vdd)) - return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd), - "unable to get Vdd supply\n"); - - err = regulator_enable(pdata->vdd); - if (err != 0) { - dev_warn(&indio_dev->dev, - "Failed to enable specified Vdd supply\n"); - return err; - } - - err = devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd); + err = devm_regulator_bulk_get_enable(parent, + ARRAY_SIZE(regulator_names), + regulator_names); if (err) - return err; + return dev_err_probe(&indio_dev->dev, err, + "unable to enable supplies\n"); - pdata->vdd_io = devm_regulator_get(parent, "vddio"); - if (IS_ERR(pdata->vdd_io)) - return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd_io), - "unable to get Vdd_IO supply\n"); - - err = regulator_enable(pdata->vdd_io); - if (err != 0) { - dev_warn(&indio_dev->dev, - "Failed to enable specified Vdd_IO supply\n"); - return err; - } - - return devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd_io); + return 0; } EXPORT_SYMBOL_NS(st_sensors_power_enable, IIO_ST_SENSORS); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c index ae7bc815382fb..e887b45cdbcd7 100644 --- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c @@ -18,58 +18,6 @@ #include "st_lsm9ds0.h" -static int st_lsm9ds0_power_enable(struct device *dev, struct st_lsm9ds0 *lsm9ds0) -{ - int ret; - - /* Regulators not mandatory, but if requested we should enable them. */ - lsm9ds0->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(lsm9ds0->vdd)) - return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd), - "unable to get Vdd supply\n"); - - ret = regulator_enable(lsm9ds0->vdd); - if (ret) { - dev_warn(dev, "Failed to enable specified Vdd supply\n"); - return ret; - } - - lsm9ds0->vdd_io = devm_regulator_get(dev, "vddio"); - if (IS_ERR(lsm9ds0->vdd_io)) { - regulator_disable(lsm9ds0->vdd); - return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd_io), - "unable to get Vdd_IO supply\n"); - } - ret = regulator_enable(lsm9ds0->vdd_io); - if (ret) { - dev_warn(dev, "Failed to enable specified Vdd_IO supply\n"); - regulator_disable(lsm9ds0->vdd); - return ret; - } - - return 0; -} - -static void st_lsm9ds0_power_disable(void *data) -{ - struct st_lsm9ds0 *lsm9ds0 = data; - - regulator_disable(lsm9ds0->vdd_io); - regulator_disable(lsm9ds0->vdd); -} - -static int devm_st_lsm9ds0_power_enable(struct st_lsm9ds0 *lsm9ds0) -{ - struct device *dev = lsm9ds0->dev; - int ret; - - ret = st_lsm9ds0_power_enable(dev, lsm9ds0); - if (ret) - return ret; - - return devm_add_action_or_reset(dev, st_lsm9ds0_power_disable, lsm9ds0); -} - static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) { const struct st_sensor_settings *settings; @@ -92,8 +40,6 @@ static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *reg data->sensor_settings = (struct st_sensor_settings *)settings; data->irq = lsm9ds0->irq; data->regmap = regmap; - data->vdd = lsm9ds0->vdd; - data->vdd_io = lsm9ds0->vdd_io; return st_accel_common_probe(lsm9ds0->accel); } @@ -120,19 +66,22 @@ static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regm data->sensor_settings = (struct st_sensor_settings *)settings; data->irq = lsm9ds0->irq; data->regmap = regmap; - data->vdd = lsm9ds0->vdd; - data->vdd_io = lsm9ds0->vdd_io; return st_magn_common_probe(lsm9ds0->magn); } int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) { + struct device *dev = lsm9ds0->dev; + static const char * const regulator_names[] = { "vdd", "vddio" }; int ret; - ret = devm_st_lsm9ds0_power_enable(lsm9ds0); + /* Regulators not mandatory, but if requested we should enable them. */ + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); if (ret) - return ret; + return dev_err_probe(dev, ret, + "unable to enable Vdd supply\n"); /* Setup accelerometer device */ ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap); diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index db4a1b260348c..f5f3ee57bc70a 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -224,8 +224,6 @@ struct st_sensor_settings { * @mount_matrix: The mounting matrix of the sensor. * @sensor_settings: Pointer to the specific sensor settings in use. * @current_fullscale: Maximum range of measure by the sensor. - * @vdd: Pointer to sensor's Vdd power supply - * @vdd_io: Pointer to sensor's Vdd-IO power supply * @regmap: Pointer to specific sensor regmap configuration. * @enabled: Status of the sensor (false->off, true->on). * @odr: Output data rate of the sensor [Hz]. @@ -244,8 +242,6 @@ struct st_sensor_data { struct iio_mount_matrix mount_matrix; struct st_sensor_settings *sensor_settings; struct st_sensor_fullscale_avl *current_fullscale; - struct regulator *vdd; - struct regulator *vdd_io; struct regmap *regmap; bool enabled; -- GitLab From d86186a6e0247394c70239713994df5e2c66220c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:03 +0100 Subject: [PATCH 0910/1480] iio: frequency: ad9523: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Note that in event of an error on the devm_regulator_get() the driver would have continued without enabling the regulator which is probably not a good idea. So here we handle any error as a reason to fail the probe(). In theory this may expose breakage on a platform that was previously papered over but it seems low risk. Signed-off-by: Jonathan Cameron Cc: Michael Hennerich Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-9-jic23@kernel.org --- drivers/iio/frequency/ad9523.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 97662ca1ca966..b391c6e27ab0d 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -265,7 +265,6 @@ enum { struct ad9523_state { struct spi_device *spi; - struct regulator *reg; struct ad9523_platform_data *pdata; struct iio_chan_spec ad9523_channels[AD9523_NUM_CHAN]; struct gpio_desc *pwrdown_gpio; @@ -969,13 +968,6 @@ static int ad9523_setup(struct iio_dev *indio_dev) return 0; } -static void ad9523_reg_disable(void *data) -{ - struct regulator *reg = data; - - regulator_disable(reg); -} - static int ad9523_probe(struct spi_device *spi) { struct ad9523_platform_data *pdata = spi->dev.platform_data; @@ -996,17 +988,9 @@ static int ad9523_probe(struct spi_device *spi) mutex_init(&st->lock); - st->reg = devm_regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, - st->reg); - if (ret) - return ret; - } + ret = devm_regulator_get_enable(&spi->dev, "vcc"); + if (ret) + return ret; st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", GPIOD_OUT_HIGH); -- GitLab From 2c97f7b404b8610ebca645d60a6ed1e68d08fbe3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:04 +0100 Subject: [PATCH 0911/1480] iio: humidity: hts211: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Acked-by: Lorenzo Bianconi Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-10-jic23@kernel.org --- drivers/iio/humidity/hts221.h | 2 -- drivers/iio/humidity/hts221_core.c | 27 ++++----------------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/iio/humidity/hts221.h b/drivers/iio/humidity/hts221.h index cf3d8d2dccd6b..721359e226cb9 100644 --- a/drivers/iio/humidity/hts221.h +++ b/drivers/iio/humidity/hts221.h @@ -13,7 +13,6 @@ #define HTS221_DEV_NAME "hts221" #include -#include enum hts221_sensor_type { HTS221_SENSOR_H, @@ -30,7 +29,6 @@ struct hts221_hw { const char *name; struct device *dev; struct regmap *regmap; - struct regulator *vdd; struct iio_trigger *trig; int irq; diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c index 517158307d8c2..2a413da87b760 100644 --- a/drivers/iio/humidity/hts221_core.c +++ b/drivers/iio/humidity/hts221_core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "hts221.h" @@ -549,33 +550,17 @@ static const unsigned long hts221_scan_masks[] = {0x3, 0x0}; static int hts221_init_regulators(struct device *dev) { - struct iio_dev *iio_dev = dev_get_drvdata(dev); - struct hts221_hw *hw = iio_priv(iio_dev); int err; - hw->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(hw->vdd)) - return dev_err_probe(dev, PTR_ERR(hw->vdd), - "failed to get vdd regulator\n"); - - err = regulator_enable(hw->vdd); - if (err) { - dev_err(dev, "failed to enable vdd regulator: %d\n", err); - return err; - } + err = devm_regulator_get_enable(dev, "vdd"); + if (err) + return dev_err_probe(dev, err, "failed to get vdd regulator\n"); msleep(50); return 0; } -static void hts221_chip_uninit(void *data) -{ - struct hts221_hw *hw = data; - - regulator_disable(hw->vdd); -} - int hts221_probe(struct device *dev, int irq, const char *name, struct regmap *regmap) { @@ -600,10 +585,6 @@ int hts221_probe(struct device *dev, int irq, const char *name, if (err) return err; - err = devm_add_action_or_reset(dev, hts221_chip_uninit, hw); - if (err) - return err; - err = hts221_check_whoami(hw); if (err < 0) return err; -- GitLab From c437c977c1d2116e0f3667de7222544f348032e4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:05 +0100 Subject: [PATCH 0912/1480] iio: light: ltr501: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power for some regulators on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-11-jic23@kernel.org --- drivers/iio/light/ltr501.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 74a1ccda8b9c4..453b845ef265b 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -153,7 +153,6 @@ struct ltr501_chip_info { struct ltr501_data { struct i2c_client *client; - struct regulator_bulk_data regulators[2]; struct mutex lock_als, lock_ps; const struct ltr501_chip_info *chip_info; u8 als_contr, ps_contr; @@ -1415,13 +1414,6 @@ static const struct regmap_config ltr501_regmap_config = { .volatile_reg = ltr501_is_volatile_reg, }; -static void ltr501_disable_regulators(void *d) -{ - struct ltr501_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - static int ltr501_powerdown(struct ltr501_data *data) { return ltr501_write_contr(data, data->als_contr & @@ -1443,6 +1435,7 @@ static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx) static int ltr501_probe(struct i2c_client *client, const struct i2c_device_id *id) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct ltr501_data *data; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1466,25 +1459,13 @@ static int ltr501_probe(struct i2c_client *client, mutex_init(&data->lock_als); mutex_init(&data->lock_ps); - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(&client->dev, - ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(&client->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, - ltr501_disable_regulators, data); - if (ret) - return ret; - data->reg_it = devm_regmap_field_alloc(&client->dev, regmap, reg_field_it); if (IS_ERR(data->reg_it)) { -- GitLab From b620be5f32621b953313056c396894818d5a2ed9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:06 +0100 Subject: [PATCH 0913/1480] iio: light: noa1305: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Martyn Welch Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-12-jic23@kernel.org --- drivers/iio/light/noa1305.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c index ee81fe083e4cc..be3536b390fcb 100644 --- a/drivers/iio/light/noa1305.c +++ b/drivers/iio/light/noa1305.c @@ -46,7 +46,6 @@ struct noa1305_priv { struct i2c_client *client; struct regmap *regmap; - struct regulator *vin_reg; }; static int noa1305_measure(struct noa1305_priv *priv) @@ -187,13 +186,6 @@ static const struct regmap_config noa1305_regmap_config = { .writeable_reg = noa1305_writable_reg, }; -static void noa1305_reg_remove(void *data) -{ - struct noa1305_priv *priv = data; - - regulator_disable(priv->vin_reg); -} - static int noa1305_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -216,23 +208,11 @@ static int noa1305_probe(struct i2c_client *client, priv = iio_priv(indio_dev); - priv->vin_reg = devm_regulator_get(&client->dev, "vin"); - if (IS_ERR(priv->vin_reg)) - return dev_err_probe(&client->dev, PTR_ERR(priv->vin_reg), + ret = devm_regulator_get_enable(&client->dev, "vin"); + if (ret) + return dev_err_probe(&client->dev, ret, "get regulator vin failed\n"); - ret = regulator_enable(priv->vin_reg); - if (ret) { - dev_err(&client->dev, "enable regulator vin failed\n"); - return ret; - } - - ret = devm_add_action_or_reset(&client->dev, noa1305_reg_remove, priv); - if (ret) { - dev_err(&client->dev, "addition of devm action failed\n"); - return ret; - } - i2c_set_clientdata(client, indio_dev); priv->client = client; priv->regmap = regmap; -- GitLab From 1db96143df6b81a402e9b88d08f04374f1353ed0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:07 +0100 Subject: [PATCH 0914/1480] iio: proximity: sx_common: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power for some regulators on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Gwendal Grignou Reviewed-by: Stephen Boyd Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-13-jic23@kernel.org --- drivers/iio/proximity/sx_common.c | 23 +++-------------------- drivers/iio/proximity/sx_common.h | 2 -- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/iio/proximity/sx_common.c b/drivers/iio/proximity/sx_common.c index d70a6b4f0bf86..eba9256730ec1 100644 --- a/drivers/iio/proximity/sx_common.c +++ b/drivers/iio/proximity/sx_common.c @@ -424,13 +424,6 @@ static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = { .postdisable = sx_common_buffer_postdisable, }; -static void sx_common_regulator_disable(void *_data) -{ - struct sx_common_data *data = _data; - - regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); -} - #define SX_COMMON_SOFT_RESET 0xde static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev) @@ -474,6 +467,7 @@ int sx_common_probe(struct i2c_client *client, const struct sx_common_chip_info *chip_info, const struct regmap_config *regmap_config) { + static const char * const regulator_names[] = { "vdd", "svdd" }; struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sx_common_data *data; @@ -487,8 +481,6 @@ int sx_common_probe(struct i2c_client *client, data->chip_info = chip_info; data->client = client; - data->supplies[0].supply = "vdd"; - data->supplies[1].supply = "svdd"; mutex_init(&data->mutex); init_completion(&data->completion); @@ -497,23 +489,14 @@ int sx_common_probe(struct i2c_client *client, return dev_err_probe(dev, PTR_ERR(data->regmap), "Could init register map\n"); - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), - data->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(dev, ret, "Unable to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); - if (ret) - return dev_err_probe(dev, ret, "Unable to enable regulators\n"); - /* Must wait for Tpor time after initial power up */ usleep_range(1000, 1100); - ret = devm_add_action_or_reset(dev, sx_common_regulator_disable, data); - if (ret) - return dev_err_probe(dev, ret, - "Unable to register regulators deleter\n"); - ret = data->chip_info->ops.check_whoami(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, "error reading WHOAMI\n"); diff --git a/drivers/iio/proximity/sx_common.h b/drivers/iio/proximity/sx_common.h index 5d3edeb75f4e0..49d4517103b0f 100644 --- a/drivers/iio/proximity/sx_common.h +++ b/drivers/iio/proximity/sx_common.h @@ -102,7 +102,6 @@ struct sx_common_chip_info { * @trig: IIO trigger object. * @regmap: Register map. * @num_default_regs: Number of default registers to set at init. - * @supplies: Power supplies object. * @chan_prox_stat: Last reading of the proximity status for each channel. * We only send an event to user space when this changes. * @trigger_enabled: True when the device trigger is enabled. @@ -120,7 +119,6 @@ struct sx_common_data { struct iio_trigger *trig; struct regmap *regmap; - struct regulator_bulk_data supplies[2]; unsigned long chan_prox_stat; bool trigger_enabled; -- GitLab From ecff5cb471b5dc20b996378c0533bd5f34e85c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:40 +0200 Subject: [PATCH 0915/1480] iio: accel: adxl367: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-2-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c index 3606efa25835e..070aad724abd4 100644 --- a/drivers/iio/accel/adxl367_i2c.c +++ b/drivers/iio/accel/adxl367_i2c.c @@ -41,8 +41,7 @@ static const struct adxl367_ops adxl367_i2c_ops = { .read_fifo = adxl367_i2c_read_fifo, }; -static int adxl367_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adxl367_i2c_probe(struct i2c_client *client) { struct adxl367_i2c_state *st; struct regmap *regmap; @@ -78,7 +77,7 @@ static struct i2c_driver adxl367_i2c_driver = { .name = "adxl367_i2c", .of_match_table = adxl367_of_match, }, - .probe = adxl367_i2c_probe, + .probe_new = adxl367_i2c_probe, .id_table = adxl367_i2c_id, }; -- GitLab From a9e38f1ecc461c43aa26849394c552e38593ad38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:45 +0200 Subject: [PATCH 0916/1480] iio: accel: da311: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-7-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da311.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c index ec4e29d260f7e..080335fa2ad65 100644 --- a/drivers/iio/accel/da311.c +++ b/drivers/iio/accel/da311.c @@ -217,8 +217,7 @@ static void da311_disable(void *client) da311_enable(client, false); } -static int da311_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int da311_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -279,7 +278,7 @@ static struct i2c_driver da311_driver = { .name = "da311", .pm = pm_sleep_ptr(&da311_pm_ops), }, - .probe = da311_probe, + .probe_new = da311_probe, .id_table = da311_i2c_id, }; -- GitLab From 72907238b193be0fc18f2859b7f4c6741b73aedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:46 +0200 Subject: [PATCH 0917/1480] iio: accel: dmard06: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-8-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard06.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c index 4b69c8530f5e6..7390509aaac05 100644 --- a/drivers/iio/accel/dmard06.c +++ b/drivers/iio/accel/dmard06.c @@ -125,8 +125,7 @@ static const struct iio_info dmard06_info = { .read_raw = dmard06_read_raw, }; -static int dmard06_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard06_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -218,7 +217,7 @@ static const struct of_device_id dmard06_of_match[] = { MODULE_DEVICE_TABLE(of, dmard06_of_match); static struct i2c_driver dmard06_driver = { - .probe = dmard06_probe, + .probe_new = dmard06_probe, .id_table = dmard06_id, .driver = { .name = DMARD06_DRV_NAME, -- GitLab From d61f79d383f548df8b3b9da58ab687c7db1a93c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:47 +0200 Subject: [PATCH 0918/1480] iio: accel: dmard09: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-9-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard09.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index cb0246ca72f32..4b7a537f617d5 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -88,8 +88,7 @@ static const struct iio_info dmard09_info = { .read_raw = dmard09_read_raw, }; -static int dmard09_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard09_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -136,7 +135,7 @@ static struct i2c_driver dmard09_driver = { .driver = { .name = DMARD09_DRV_NAME }, - .probe = dmard09_probe, + .probe_new = dmard09_probe, .id_table = dmard09_id, }; -- GitLab From 5019025fc3a9869c438ad33ab18a4fdad46a996d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:48 +0200 Subject: [PATCH 0919/1480] iio: accel: dmard10: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-10-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard10.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c index 8ac62ec0a04a4..07e68aed8a13c 100644 --- a/drivers/iio/accel/dmard10.c +++ b/drivers/iio/accel/dmard10.c @@ -175,8 +175,7 @@ static void dmard10_shutdown_cleanup(void *client) dmard10_shutdown(client); } -static int dmard10_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard10_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -242,7 +241,7 @@ static struct i2c_driver dmard10_driver = { .name = "dmard10", .pm = pm_sleep_ptr(&dmard10_pm_ops), }, - .probe = dmard10_probe, + .probe_new = dmard10_probe, .id_table = dmard10_i2c_id, }; -- GitLab From 2ba423fefb1c87d080e3a7964ccfa7e929ed6f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:50 +0200 Subject: [PATCH 0920/1480] iio: accel: kxsd9: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-12-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxsd9-i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c index 61346ea8ef194..6b3683ddce36d 100644 --- a/drivers/iio/accel/kxsd9-i2c.c +++ b/drivers/iio/accel/kxsd9-i2c.c @@ -10,8 +10,7 @@ #include "kxsd9.h" -static int kxsd9_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int kxsd9_i2c_probe(struct i2c_client *i2c) { static const struct regmap_config config = { .reg_bits = 8, @@ -55,7 +54,7 @@ static struct i2c_driver kxsd9_i2c_driver = { .of_match_table = kxsd9_of_match, .pm = pm_ptr(&kxsd9_dev_pm_ops), }, - .probe = kxsd9_i2c_probe, + .probe_new = kxsd9_i2c_probe, .remove = kxsd9_i2c_remove, .id_table = kxsd9_i2c_id, }; -- GitLab From ded7a4f8f90286e63eefcd32443ac911d926e118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:51 +0200 Subject: [PATCH 0921/1480] iio: accel: mc3230: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-13-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mc3230.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c index 2462000e05198..efc21871de42b 100644 --- a/drivers/iio/accel/mc3230.c +++ b/drivers/iio/accel/mc3230.c @@ -106,8 +106,7 @@ static const struct iio_info mc3230_info = { .read_raw = mc3230_read_raw, }; -static int mc3230_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mc3230_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -191,7 +190,7 @@ static struct i2c_driver mc3230_driver = { .name = "mc3230", .pm = pm_sleep_ptr(&mc3230_pm_ops), }, - .probe = mc3230_probe, + .probe_new = mc3230_probe, .remove = mc3230_remove, .id_table = mc3230_i2c_id, }; -- GitLab From 76403ea698adffb6661e083545f21e50fef5b3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:53 +0200 Subject: [PATCH 0922/1480] iio: accel: mma7660: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-15-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma7660.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c index 85829990bbada..b279ca4dcdc05 100644 --- a/drivers/iio/accel/mma7660.c +++ b/drivers/iio/accel/mma7660.c @@ -169,8 +169,7 @@ static const struct iio_info mma7660_info = { .attrs = &mma7660_attribute_group, }; -static int mma7660_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma7660_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -267,7 +266,7 @@ static struct i2c_driver mma7660_driver = { .of_match_table = mma7660_of_match, .acpi_match_table = mma7660_acpi_id, }, - .probe = mma7660_probe, + .probe_new = mma7660_probe, .remove = mma7660_remove, .id_table = mma7660_i2c_id, }; -- GitLab From a97d9d95a188d21f5d1cbedbbc7c990b00bf5744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:57 +0200 Subject: [PATCH 0923/1480] iio: accel: mxc4005: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-19-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mxc4005.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index df600d2917c0a..b146fc82738f6 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -385,8 +385,7 @@ static int mxc4005_chip_init(struct mxc4005_data *data) return 0; } -static int mxc4005_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mxc4005_probe(struct i2c_client *client) { struct mxc4005_data *data; struct iio_dev *indio_dev; @@ -489,7 +488,7 @@ static struct i2c_driver mxc4005_driver = { .name = MXC4005_DRV_NAME, .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), }, - .probe = mxc4005_probe, + .probe_new = mxc4005_probe, .id_table = mxc4005_id, }; -- GitLab From 76e4a118c85a7e93ff5264ff8d92f76f675be352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:58 +0200 Subject: [PATCH 0924/1480] iio: accel: mxc6255: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-20-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mxc6255.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c index 9aeeadc420d31..aa2e660545f84 100644 --- a/drivers/iio/accel/mxc6255.c +++ b/drivers/iio/accel/mxc6255.c @@ -113,8 +113,7 @@ static const struct regmap_config mxc6255_regmap_config = { .readable_reg = mxc6255_is_readable_reg, }; -static int mxc6255_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mxc6255_probe(struct i2c_client *client) { struct mxc6255_data *data; struct iio_dev *indio_dev; @@ -184,7 +183,7 @@ static struct i2c_driver mxc6255_driver = { .name = MXC6255_DRV_NAME, .acpi_match_table = ACPI_PTR(mxc6255_acpi_match), }, - .probe = mxc6255_probe, + .probe_new = mxc6255_probe, .id_table = mxc6255_id, }; -- GitLab From 3d8a49ebd6576b7803181e0a9fa4e7930f011f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:22:59 +0200 Subject: [PATCH 0925/1480] iio: accel: stk8312: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-21-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/stk8312.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index 7b1d6fb692b37..68f680db75051 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -498,8 +498,7 @@ static const struct iio_buffer_setup_ops stk8312_buffer_setup_ops = { .postdisable = stk8312_buffer_postdisable, }; -static int stk8312_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk8312_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -645,7 +644,7 @@ static struct i2c_driver stk8312_driver = { .name = STK8312_DRIVER_NAME, .pm = pm_sleep_ptr(&stk8312_pm_ops), }, - .probe = stk8312_probe, + .probe_new = stk8312_probe, .remove = stk8312_remove, .id_table = stk8312_i2c_id, }; -- GitLab From d18e70608e01a5845fd75e7ec1956ce422b07184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:23:00 +0200 Subject: [PATCH 0926/1480] iio: accel: stk8ba50: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-22-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/stk8ba50.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 2f5e4ab2a6e7d..44f6e0fbdfcc6 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -379,8 +379,7 @@ static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = { .postdisable = stk8ba50_buffer_postdisable, }; -static int stk8ba50_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk8ba50_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -544,7 +543,7 @@ static struct i2c_driver stk8ba50_driver = { .pm = pm_sleep_ptr(&stk8ba50_pm_ops), .acpi_match_table = ACPI_PTR(stk8ba50_acpi_id), }, - .probe = stk8ba50_probe, + .probe_new = stk8ba50_probe, .remove = stk8ba50_remove, .id_table = stk8ba50_i2c_id, }; -- GitLab From 9492c00d83ee8b2b141e29acbcd3e56dd11aa436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:23:01 +0200 Subject: [PATCH 0927/1480] iio: accel: st_magn: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-23-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/st_magn_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index c5d8c303db4ef..b4098d3b38137 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -54,8 +54,7 @@ static const struct of_device_id st_magn_of_match[] = { }; MODULE_DEVICE_TABLE(of, st_magn_of_match); -static int st_magn_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_magn_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *mdata; @@ -107,7 +106,7 @@ static struct i2c_driver st_magn_driver = { .name = "st-magn-i2c", .of_match_table = st_magn_of_match, }, - .probe = st_magn_i2c_probe, + .probe_new = st_magn_i2c_probe, .id_table = st_magn_id_table, }; module_i2c_driver(st_magn_driver); -- GitLab From 2ca0b16f6ce23cf586c27a9139cf426b3f64d242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 23 Oct 2022 15:23:02 +0200 Subject: [PATCH 0928/1480] iio: accel: vl6180: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-24-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/light/vl6180.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index d47a4f6f4e870..8b56df26c59e8 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -493,8 +493,7 @@ static int vl6180_init(struct vl6180_data *data) return vl6180_hold(data, false); } -static int vl6180_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vl6180_probe(struct i2c_client *client) { struct vl6180_data *data; struct iio_dev *indio_dev; @@ -539,7 +538,7 @@ static struct i2c_driver vl6180_driver = { .name = VL6180_DRV_NAME, .of_match_table = vl6180_of_match, }, - .probe = vl6180_probe, + .probe_new = vl6180_probe, .id_table = vl6180_id, }; -- GitLab From a95ccebde759f1f6a6070819cd43dce1ad06750d Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Mon, 24 Oct 2022 12:22:05 +0200 Subject: [PATCH 0929/1480] iio: temperature: mlx90632 Style alignment for the driver Changing and aligning the overall style of the driver with the recent reviews. There is no functional change, only type generalization and moving to the reverse Christmas tree for variable declarations. Reviewed-by: Andy Shevchenko Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/d59aad00891c1a64e044a0f5bc7d40e42d47e9c7.1666606912.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 65 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 224db7513baa7..a17fe5f4967a6 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -219,11 +219,11 @@ static const struct regmap_config mlx90632_regmap = { .cache_type = REGCACHE_RBTREE, }; -static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) +static int mlx90632_pwr_set_sleep_step(struct regmap *regmap) { struct mlx90632_data *data = iio_priv(dev_get_drvdata(regmap_get_device(regmap))); - s32 ret; + int ret; if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) return 0; @@ -234,14 +234,14 @@ static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) return ret; data->powerstatus = MLX90632_PWR_STATUS_SLEEP_STEP; - return ret; + return 0; } -static s32 mlx90632_pwr_continuous(struct regmap *regmap) +static int mlx90632_pwr_continuous(struct regmap *regmap) { struct mlx90632_data *data = iio_priv(dev_get_drvdata(regmap_get_device(regmap))); - s32 ret; + int ret; if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) return 0; @@ -252,7 +252,7 @@ static s32 mlx90632_pwr_continuous(struct regmap *regmap) return ret; data->powerstatus = MLX90632_PWR_STATUS_CONTINUOUS; - return ret; + return 0; } /** @@ -444,8 +444,8 @@ static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, static int mlx90632_read_ambient_raw(struct regmap *regmap, s16 *ambient_new_raw, s16 *ambient_old_raw) { - int ret; unsigned int read_tmp; + int ret; ret = regmap_read(regmap, MLX90632_RAM_3(1), &read_tmp); if (ret < 0) @@ -464,11 +464,11 @@ static int mlx90632_read_object_raw(struct regmap *regmap, int perform_measurement_ret, s16 *object_new_raw, s16 *object_old_raw) { - int ret; unsigned int read_tmp; - s16 read; - u8 channel = 0; u8 channel_old = 0; + u8 channel = 0; + s16 read; + int ret; ret = mlx90632_channel_new_select(perform_measurement_ret, &channel, &channel_old); @@ -503,7 +503,8 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, s16 *ambient_new_raw, s16 *ambient_old_raw, s16 *object_new_raw, s16 *object_old_raw) { - s32 ret, measurement; + s32 measurement; + int ret; mutex_lock(&data->lock); ret = mlx90632_set_meas_type(data, MLX90632_MTYP_MEDICAL); @@ -512,24 +513,24 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, switch (data->powerstatus) { case MLX90632_PWR_STATUS_CONTINUOUS: - measurement = mlx90632_perform_measurement(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_perform_measurement(data); + if (ret < 0) goto read_unlock; - } + break; case MLX90632_PWR_STATUS_SLEEP_STEP: - measurement = mlx90632_perform_measurement_burst(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_perform_measurement_burst(data); + if (ret < 0) goto read_unlock; - } + break; default: ret = -EOPNOTSUPP; goto read_unlock; } + measurement = ret; /* If we came here ret holds the measurement position */ + ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw, ambient_old_raw); if (ret < 0) @@ -615,15 +616,21 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o if (ret < 0) goto read_unlock; - if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) { + switch (data->powerstatus) { + case MLX90632_PWR_STATUS_CONTINUOUS: ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, 50000, 800000, false, data); if (ret) goto read_unlock; - } else if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + break; + case MLX90632_PWR_STATUS_SLEEP_STEP: ret = mlx90632_perform_measurement_burst(data); if (ret < 0) goto read_unlock; + break; + default: + ret = -EOPNOTSUPP; + goto read_unlock; } ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); @@ -640,9 +647,9 @@ read_unlock: static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, s32 *reg_value) { - s32 ret; unsigned int read; u32 value; + int ret; ret = regmap_read(regmap, reg_lsb, &read); if (ret < 0) @@ -806,12 +813,12 @@ static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 refle static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) { - s32 ret; + s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw; s32 Ea, Eb, Fa, Fb, Ga; unsigned int read_tmp; - s16 Ha, Hb, Gb, Ka; - s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw; s64 object, ambient; + s16 Ha, Hb, Gb, Ka; + int ret; ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ea, &Ea); if (ret < 0) @@ -885,11 +892,11 @@ static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) { - s32 ret; + s16 ambient_new_raw, ambient_old_raw; unsigned int read_tmp; s32 PT, PR, PG, PO; + int ret; s16 Gb; - s16 ambient_new_raw, ambient_old_raw; ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_R, &PR); if (ret < 0) @@ -1164,11 +1171,11 @@ static int mlx90632_enable_regulator(struct mlx90632_data *data) static int mlx90632_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct iio_dev *indio_dev; struct mlx90632_data *mlx90632; + struct iio_dev *indio_dev; struct regmap *regmap; - int ret; unsigned int read; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90632)); if (!indio_dev) { -- GitLab From f7626504432a6d30178bc6946d50a9d4a1bb4e31 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 24 Oct 2022 18:52:50 +0800 Subject: [PATCH 0930/1480] iio: trigger: sysfs: rename error label in iio_sysfs_trigger_probe() Rename error label in iio_sysfs_trigger_probe() to make more readable. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221024105250.873394-1-yangyingliang@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/iio-trig-sysfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index d6c5e96447383..63ce01ac20368 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -138,18 +138,18 @@ static int iio_sysfs_trigger_probe(int id) } if (foundit) { ret = -EINVAL; - goto out1; + goto err_unlock; } t = kmalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) { ret = -ENOMEM; - goto out1; + goto err_unlock; } t->id = id; t->trig = iio_trigger_alloc(&iio_sysfs_trig_dev, "sysfstrig%d", id); if (!t->trig) { ret = -ENOMEM; - goto free_t; + goto err_free_sys_trig; } t->trig->dev.groups = iio_sysfs_trigger_attr_groups; @@ -159,17 +159,17 @@ static int iio_sysfs_trigger_probe(int id) ret = iio_trigger_register(t->trig); if (ret) - goto out2; + goto err_free_trig; list_add(&t->l, &iio_sysfs_trig_list); __module_get(THIS_MODULE); mutex_unlock(&iio_sysfs_trig_list_mut); return 0; -out2: +err_free_trig: iio_trigger_free(t->trig); -free_t: +err_free_sys_trig: kfree(t); -out1: +err_unlock: mutex_unlock(&iio_sysfs_trig_list_mut); return ret; } -- GitLab From b52e2f19f80240365d7eaa3fdd320afcf14cf4c0 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 24 Oct 2022 15:40:11 +0300 Subject: [PATCH 0931/1480] dt-bindings: iio: Add KX022A accelerometer KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features. Add the basic device tree description for the accelerometer. Only basic accelerometer features are considered as of now - new properties may or may not be needed in the future when rest of the features are supported. Signed-off-by: Matti Vaittinen Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/06f8e1ab29d02ed216db10091a269df4b6abad9a.1666614295.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/accel/kionix,kx022a.yaml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml diff --git a/Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml b/Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file mode 100644 index 0000000000000..986df1a6ff0ab --- /dev/null +++ b/Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM/Kionix KX022A Accelerometer + +maintainers: + - Matti Vaittinen + +description: | + KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges, + output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering. + KX022A can be accessed either via I2C or SPI. + +properties: + compatible: + const: kionix,kx022a + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + items: + - enum: [INT1, INT2] + - const: INT2 + + vdd-supply: true + io-vdd-supply: true + + mount-matrix: + description: | + an optional 3x3 mounting rotation matrix. + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + accel@1f { + compatible = "kionix,kx022a"; + reg = <0x1f>; + + interrupt-parent = <&gpio1>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "INT1"; + + io-vdd-supply = <&iovdd>; + vdd-supply = <&vdd>; + }; + }; -- GitLab From 7c1d1677b3227c6b18ac999f2b84778baa280b8f Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 24 Oct 2022 15:40:29 +0300 Subject: [PATCH 0932/1480] iio: accel: Support Kionix/ROHM KX022A accelerometer KX022A is a 3-axis accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g), and probably some other cool features. Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ). Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management. Signed-off-by: Matti Vaittinen Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/758b00d6aea0a6431a5a3a78d557d449c113b21e.1666614295.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 21 + drivers/iio/accel/Makefile | 3 + drivers/iio/accel/kionix-kx022a-i2c.c | 51 ++ drivers/iio/accel/kionix-kx022a-spi.c | 58 ++ drivers/iio/accel/kionix-kx022a.c | 1142 +++++++++++++++++++++++++ drivers/iio/accel/kionix-kx022a.h | 82 ++ 6 files changed, 1357 insertions(+) create mode 100644 drivers/iio/accel/kionix-kx022a-i2c.c create mode 100644 drivers/iio/accel/kionix-kx022a-spi.c create mode 100644 drivers/iio/accel/kionix-kx022a.c create mode 100644 drivers/iio/accel/kionix-kx022a.h diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index ffac66db7ac92..03ac410c162e1 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -409,6 +409,27 @@ config IIO_ST_ACCEL_SPI_3AXIS To compile this driver as a module, choose M here. The module will be called st_accel_spi. +config IIO_KX022A + tristate + +config IIO_KX022A_SPI + tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" + depends on SPI + select IIO_KX022A + select REGMAP_SPI + help + Enable support for the Kionix KX022A digital tri-axis + accelerometer connected to I2C interface. + +config IIO_KX022A_I2C + tristate "Kionix KX022A tri-axis digital accelerometer I2C interface" + depends on I2C + select IIO_KX022A + select REGMAP_I2C + help + Enable support for the Kionix KX022A digital tri-axis + accelerometer connected to I2C interface. + config KXSD9 tristate "Kionix KXSD9 Accelerometer Driver" select IIO_BUFFER diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 5e45b5fa5ab50..311ead9c3ef18 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -40,6 +40,9 @@ obj-$(CONFIG_FXLS8962AF) += fxls8962af-core.o obj-$(CONFIG_FXLS8962AF_I2C) += fxls8962af-i2c.o obj-$(CONFIG_FXLS8962AF_SPI) += fxls8962af-spi.o obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o +obj-$(CONFIG_IIO_KX022A) += kionix-kx022a.o +obj-$(CONFIG_IIO_KX022A_I2C) += kionix-kx022a-i2c.o +obj-$(CONFIG_IIO_KX022A_SPI) += kionix-kx022a-spi.o obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o obj-$(CONFIG_KXSD9) += kxsd9.o obj-$(CONFIG_KXSD9_SPI) += kxsd9-spi.o diff --git a/drivers/iio/accel/kionix-kx022a-i2c.c b/drivers/iio/accel/kionix-kx022a-i2c.c new file mode 100644 index 0000000000000..e6fd02d931b60 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a-i2c.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +static int kx022a_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct regmap *regmap; + + if (!i2c->irq) { + dev_err(dev, "No IRQ configured\n"); + return -EINVAL; + } + + regmap = devm_regmap_init_i2c(i2c, &kx022a_regmap); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialize Regmap\n"); + + return kx022a_probe_internal(dev); +} + +static const struct of_device_id kx022a_of_match[] = { + { .compatible = "kionix,kx022a", }, + { } +}; +MODULE_DEVICE_TABLE(of, kx022a_of_match); + +static struct i2c_driver kx022a_i2c_driver = { + .driver = { + .name = "kx022a-i2c", + .of_match_table = kx022a_of_match, + }, + .probe_new = kx022a_i2c_probe, +}; +module_i2c_driver(kx022a_i2c_driver); + +MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_KX022A); diff --git a/drivers/iio/accel/kionix-kx022a-spi.c b/drivers/iio/accel/kionix-kx022a-spi.c new file mode 100644 index 0000000000000..9cd047f7b3467 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a-spi.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +static int kx022a_spi_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct regmap *regmap; + + if (!spi->irq) { + dev_err(dev, "No IRQ configured\n"); + return -EINVAL; + } + + regmap = devm_regmap_init_spi(spi, &kx022a_regmap); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialize Regmap\n"); + + return kx022a_probe_internal(dev); +} + +static const struct spi_device_id kx022a_id[] = { + { "kx022a" }, + { } +}; +MODULE_DEVICE_TABLE(spi, kx022a_id); + +static const struct of_device_id kx022a_of_match[] = { + { .compatible = "kionix,kx022a", }, + { } +}; +MODULE_DEVICE_TABLE(of, kx022a_of_match); + +static struct spi_driver kx022a_spi_driver = { + .driver = { + .name = "kx022a-spi", + .of_match_table = kx022a_of_match, + }, + .probe = kx022a_spi_probe, + .id_table = kx022a_id, +}; +module_spi_driver(kx022a_spi_driver); + +MODULE_DESCRIPTION("ROHM/Kionix kx022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_KX022A); diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c new file mode 100644 index 0000000000000..50de7f9a1cc7f --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a.c @@ -0,0 +1,1142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +/* + * The KX022A has FIFO which can store 43 samples of HiRes data from 2 + * channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to + * 258 bytes of sample data. The quirk to know is that the amount of bytes in + * the FIFO is advertised via 8 bit register (max value 255). The thing to note + * is that full 258 bytes of data is indicated using the max value 255. + */ +#define KX022A_FIFO_LENGTH 43 +#define KX022A_FIFO_FULL_VALUE 255 +#define KX022A_SOFT_RESET_WAIT_TIME_US (5 * USEC_PER_MSEC) +#define KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US (500 * USEC_PER_MSEC) + +/* 3 axis, 2 bytes of data for each of the axis */ +#define KX022A_FIFO_SAMPLES_SIZE_BYTES 6 +#define KX022A_FIFO_MAX_BYTES \ + (KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES) + +enum { + KX022A_STATE_SAMPLE, + KX022A_STATE_FIFO, +}; + +/* Regmap configs */ +static const struct regmap_range kx022a_volatile_ranges[] = { + { + .range_min = KX022A_REG_XHP_L, + .range_max = KX022A_REG_COTR, + }, { + .range_min = KX022A_REG_TSCP, + .range_max = KX022A_REG_INT_REL, + }, { + /* The reset bit will be cleared by sensor */ + .range_min = KX022A_REG_CNTL2, + .range_max = KX022A_REG_CNTL2, + }, { + .range_min = KX022A_REG_BUF_STATUS_1, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_volatile_regs = { + .yes_ranges = &kx022a_volatile_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_volatile_ranges), +}; + +static const struct regmap_range kx022a_precious_ranges[] = { + { + .range_min = KX022A_REG_INT_REL, + .range_max = KX022A_REG_INT_REL, + }, +}; + +static const struct regmap_access_table kx022a_precious_regs = { + .yes_ranges = &kx022a_precious_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_precious_ranges), +}; + +/* + * The HW does not set WHO_AM_I reg as read-only but we don't want to write it + * so we still include it in the read-only ranges. + */ +static const struct regmap_range kx022a_read_only_ranges[] = { + { + .range_min = KX022A_REG_XHP_L, + .range_max = KX022A_REG_INT_REL, + }, { + .range_min = KX022A_REG_BUF_STATUS_1, + .range_max = KX022A_REG_BUF_STATUS_2, + }, { + .range_min = KX022A_REG_BUF_READ, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_ro_regs = { + .no_ranges = &kx022a_read_only_ranges[0], + .n_no_ranges = ARRAY_SIZE(kx022a_read_only_ranges), +}; + +static const struct regmap_range kx022a_write_only_ranges[] = { + { + .range_min = KX022A_REG_BTS_WUF_TH, + .range_max = KX022A_REG_BTS_WUF_TH, + }, { + .range_min = KX022A_REG_MAN_WAKE, + .range_max = KX022A_REG_MAN_WAKE, + }, { + .range_min = KX022A_REG_SELF_TEST, + .range_max = KX022A_REG_SELF_TEST, + }, { + .range_min = KX022A_REG_BUF_CLEAR, + .range_max = KX022A_REG_BUF_CLEAR, + }, +}; + +static const struct regmap_access_table kx022a_wo_regs = { + .no_ranges = &kx022a_write_only_ranges[0], + .n_no_ranges = ARRAY_SIZE(kx022a_write_only_ranges), +}; + +static const struct regmap_range kx022a_noinc_read_ranges[] = { + { + .range_min = KX022A_REG_BUF_READ, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_nir_regs = { + .yes_ranges = &kx022a_noinc_read_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_noinc_read_ranges), +}; + +const struct regmap_config kx022a_regmap = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = &kx022a_volatile_regs, + .rd_table = &kx022a_wo_regs, + .wr_table = &kx022a_ro_regs, + .rd_noinc_table = &kx022a_nir_regs, + .precious_table = &kx022a_precious_regs, + .max_register = KX022A_MAX_REGISTER, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_NS_GPL(kx022a_regmap, IIO_KX022A); + +struct kx022a_data { + struct regmap *regmap; + struct iio_trigger *trig; + struct device *dev; + struct iio_mount_matrix orientation; + int64_t timestamp, old_timestamp; + + int irq; + int inc_reg; + int ien_reg; + + unsigned int g_range; + unsigned int state; + unsigned int odr_ns; + + bool trigger_enabled; + /* + * Prevent toggling the sensor stby/active state (PC1 bit) in the + * middle of a configuration, or when the fifo is enabled. Also, + * protect the data stored/retrieved from this structure from + * concurrent accesses. + */ + struct mutex mutex; + u8 watermark; + + /* 3 x 16bit accel data + timestamp */ + __le16 buffer[8] __aligned(IIO_DMA_MINALIGN); + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan; +}; + +static const struct iio_mount_matrix * +kx022a_get_mount_matrix(const struct iio_dev *idev, + const struct iio_chan_spec *chan) +{ + struct kx022a_data *data = iio_priv(idev); + + return &data->orientation; +} + +enum { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_MAX +}; + +static const unsigned long kx022a_scan_masks[] = { + BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 0 +}; + +static const struct iio_chan_spec_ext_info kx022a_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kx022a_get_mount_matrix), + { } +}; + +#define KX022A_ACCEL_CHAN(axis, index) \ +{ \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .ext_info = kx022a_ext_info, \ + .address = KX022A_REG_##axis##OUT_L, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec kx022a_channels[] = { + KX022A_ACCEL_CHAN(X, 0), + KX022A_ACCEL_CHAN(Y, 1), + KX022A_ACCEL_CHAN(Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +/* + * The sensor HW can support ODR up to 1600 Hz, which is beyond what most of the + * Linux CPUs can handle without dropping samples. Also, the low power mode is + * not available for higher sample rates. Thus, the driver only supports 200 Hz + * and slower ODRs. The slowest is 0.78 Hz. + */ +static const int kx022a_accel_samp_freq_table[][2] = { + { 0, 780000 }, + { 1, 563000 }, + { 3, 125000 }, + { 6, 250000 }, + { 12, 500000 }, + { 25, 0 }, + { 50, 0 }, + { 100, 0 }, + { 200, 0 }, +}; + +static const unsigned int kx022a_odrs[] = { + 1282051282, + 639795266, + 320 * MEGA, + 160 * MEGA, + 80 * MEGA, + 40 * MEGA, + 20 * MEGA, + 10 * MEGA, + 5 * MEGA, +}; + +/* + * range is typically +-2G/4G/8G/16G, distributed over the amount of bits. + * The scale table can be calculated using + * (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2 + * => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed + * in low-power mode(?) ) + * => +/-2G => 4 / 2^16 * 9,80665 * 10^6 (to scale to micro) + * => +/-2G - 598.550415 + * +/-4G - 1197.10083 + * +/-8G - 2394.20166 + * +/-16G - 4788.40332 + */ +static const int kx022a_scale_table[][2] = { + { 598, 550415 }, + { 1197, 100830 }, + { 2394, 201660 }, + { 4788, 403320 }, +}; + +static int kx022a_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (const int *)kx022a_accel_samp_freq_table; + *length = ARRAY_SIZE(kx022a_accel_samp_freq_table) * + ARRAY_SIZE(kx022a_accel_samp_freq_table[0]); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals = (const int *)kx022a_scale_table; + *length = ARRAY_SIZE(kx022a_scale_table) * + ARRAY_SIZE(kx022a_scale_table[0]); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +#define KX022A_DEFAULT_PERIOD_NS (20 * NSEC_PER_MSEC) + +static void kx022a_reg2freq(unsigned int val, int *val1, int *val2) +{ + *val1 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][0]; + *val2 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][1]; +} + +static void kx022a_reg2scale(unsigned int val, unsigned int *val1, + unsigned int *val2) +{ + val &= KX022A_MASK_GSEL; + val >>= KX022A_GSEL_SHIFT; + + *val1 = kx022a_scale_table[val][0]; + *val2 = kx022a_scale_table[val][1]; +} + +static int kx022a_turn_on_off_unlocked(struct kx022a_data *data, bool on) +{ + int ret; + + if (on) + ret = regmap_set_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_PC1); + else + ret = regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_PC1); + if (ret) + dev_err(data->dev, "Turn %s fail %d\n", str_on_off(on), ret); + + return ret; + +} + +static int kx022a_turn_off_lock(struct kx022a_data *data) +{ + int ret; + + mutex_lock(&data->mutex); + ret = kx022a_turn_on_off_unlocked(data, false); + if (ret) + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_turn_on_unlock(struct kx022a_data *data) +{ + int ret; + + ret = kx022a_turn_on_off_unlocked(data, true); + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_write_raw(struct iio_dev *idev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct kx022a_data *data = iio_priv(idev); + int ret, n; + + /* + * We should not allow changing scale or frequency when FIFO is running + * as it will mess the timestamp/scale for samples existing in the + * buffer. If this turns out to be an issue we can later change logic + * to internally flush the fifo before reconfiguring so the samples in + * fifo keep matching the freq/scale settings. (Such setup could cause + * issues if users trust the watermark to be reached within known + * time-limit). + */ + ret = iio_device_claim_direct_mode(idev); + if (ret) + return ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + n = ARRAY_SIZE(kx022a_accel_samp_freq_table); + + while (n--) + if (val == kx022a_accel_samp_freq_table[n][0] && + val2 == kx022a_accel_samp_freq_table[n][1]) + break; + if (n < 0) { + ret = -EINVAL; + goto unlock_out; + } + ret = kx022a_turn_off_lock(data); + if (ret) + break; + + ret = regmap_update_bits(data->regmap, + KX022A_REG_ODCNTL, + KX022A_MASK_ODR, n); + data->odr_ns = kx022a_odrs[n]; + kx022a_turn_on_unlock(data); + break; + case IIO_CHAN_INFO_SCALE: + n = ARRAY_SIZE(kx022a_scale_table); + + while (n-- > 0) + if (val == kx022a_scale_table[n][0] && + val2 == kx022a_scale_table[n][1]) + break; + if (n < 0) { + ret = -EINVAL; + goto unlock_out; + } + + ret = kx022a_turn_off_lock(data); + if (ret) + break; + + ret = regmap_update_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_GSEL, + n << KX022A_GSEL_SHIFT); + kx022a_turn_on_unlock(data); + break; + default: + ret = -EINVAL; + break; + } + +unlock_out: + iio_device_release_direct_mode(idev); + + return ret; +} + +static int kx022a_fifo_set_wmi(struct kx022a_data *data) +{ + u8 threshold; + + threshold = data->watermark; + + return regmap_update_bits(data->regmap, KX022A_REG_BUF_CNTL1, + KX022A_MASK_WM_TH, threshold); +} + +static int kx022a_get_axis(struct kx022a_data *data, + struct iio_chan_spec const *chan, + int *val) +{ + int ret; + + ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer[0], + sizeof(__le16)); + if (ret) + return ret; + + *val = le16_to_cpu(data->buffer[0]); + + return IIO_VAL_INT; +} + +static int kx022a_read_raw(struct iio_dev *idev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct kx022a_data *data = iio_priv(idev); + unsigned int regval; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(idev); + if (ret) + return ret; + + mutex_lock(&data->mutex); + ret = kx022a_get_axis(data, chan, val); + mutex_unlock(&data->mutex); + + iio_device_release_direct_mode(idev); + + return ret; + + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(data->regmap, KX022A_REG_ODCNTL, ®val); + if (ret) + return ret; + + if ((regval & KX022A_MASK_ODR) > + ARRAY_SIZE(kx022a_accel_samp_freq_table)) { + dev_err(data->dev, "Invalid ODR\n"); + return -EINVAL; + } + + kx022a_reg2freq(regval, val, val2); + + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SCALE: + ret = regmap_read(data->regmap, KX022A_REG_CNTL, ®val); + if (ret < 0) + return ret; + + kx022a_reg2scale(regval, val, val2); + + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +}; + +static int kx022a_validate_trigger(struct iio_dev *idev, + struct iio_trigger *trig) +{ + struct kx022a_data *data = iio_priv(idev); + + if (data->trig != trig) + return -EINVAL; + + return 0; +} + +static int kx022a_set_watermark(struct iio_dev *idev, unsigned int val) +{ + struct kx022a_data *data = iio_priv(idev); + + if (val > KX022A_FIFO_LENGTH) + val = KX022A_FIFO_LENGTH; + + mutex_lock(&data->mutex); + data->watermark = val; + mutex_unlock(&data->mutex); + + return 0; +} + +static ssize_t hwfifo_enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *idev = dev_to_iio_dev(dev); + struct kx022a_data *data = iio_priv(idev); + bool state; + + mutex_lock(&data->mutex); + state = data->state; + mutex_unlock(&data->mutex); + + return sysfs_emit(buf, "%d\n", state); +} + +static ssize_t hwfifo_watermark_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *idev = dev_to_iio_dev(dev); + struct kx022a_data *data = iio_priv(idev); + int wm; + + mutex_lock(&data->mutex); + wm = data->watermark; + mutex_unlock(&data->mutex); + + return sysfs_emit(buf, "%d\n", wm); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); + +static const struct attribute *kx022a_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark.dev_attr.attr, + &iio_dev_attr_hwfifo_enabled.dev_attr.attr, + NULL +}; + +static int kx022a_drop_fifo_contents(struct kx022a_data *data) +{ + /* + * We must clear the old time-stamp to avoid computing the timestamps + * based on samples acquired when buffer was last enabled. + * + * We don't need to protect the timestamp as long as we are only + * called from fifo-disable where we can guarantee the sensor is not + * triggering interrupts and where the mutex is locked to prevent the + * user-space access. + */ + data->timestamp = 0; + + return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0x0); +} + +static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples, + bool irq) +{ + struct kx022a_data *data = iio_priv(idev); + struct device *dev = regmap_get_device(data->regmap); + __le16 buffer[KX022A_FIFO_LENGTH * 3]; + uint64_t sample_period; + int count, fifo_bytes; + bool renable = false; + int64_t tstamp; + int ret, i; + + ret = regmap_read(data->regmap, KX022A_REG_BUF_STATUS_1, &fifo_bytes); + if (ret) { + dev_err(dev, "Error reading buffer status\n"); + return ret; + } + + /* Let's not overflow if we for some reason get bogus value from i2c */ + if (fifo_bytes == KX022A_FIFO_FULL_VALUE) + fifo_bytes = KX022A_FIFO_MAX_BYTES; + + if (fifo_bytes % KX022A_FIFO_SAMPLES_SIZE_BYTES) + dev_warn(data->dev, "Bad FIFO alignment. Data may be corrupt\n"); + + count = fifo_bytes / KX022A_FIFO_SAMPLES_SIZE_BYTES; + if (!count) + return 0; + + /* + * If we are being called from IRQ handler we know the stored timestamp + * is fairly accurate for the last stored sample. Otherwise, if we are + * called as a result of a read operation from userspace and hence + * before the watermark interrupt was triggered, take a timestamp + * now. We can fall anywhere in between two samples so the error in this + * case is at most one sample period. + */ + if (!irq) { + /* + * We need to have the IRQ disabled or we risk of messing-up + * the timestamps. If we are ran from IRQ, then the + * IRQF_ONESHOT has us covered - but if we are ran by the + * user-space read we need to disable the IRQ to be on a safe + * side. We do this usng synchronous disable so that if the + * IRQ thread is being ran on other CPU we wait for it to be + * finished. + */ + disable_irq(data->irq); + renable = true; + + data->old_timestamp = data->timestamp; + data->timestamp = iio_get_time_ns(idev); + } + + /* + * Approximate timestamps for each of the sample based on the sampling + * frequency, timestamp for last sample and number of samples. + * + * We'd better not use the current bandwidth settings to compute the + * sample period. The real sample rate varies with the device and + * small variation adds when we store a large number of samples. + * + * To avoid this issue we compute the actual sample period ourselves + * based on the timestamp delta between the last two flush operations. + */ + if (data->old_timestamp) { + sample_period = data->timestamp - data->old_timestamp; + do_div(sample_period, count); + } else { + sample_period = data->odr_ns; + } + tstamp = data->timestamp - (count - 1) * sample_period; + + if (samples && count > samples) { + /* + * Here we leave some old samples to the buffer. We need to + * adjust the timestamp to match the first sample in the buffer + * or we will miscalculate the sample_period at next round. + */ + data->timestamp -= (count - samples) * sample_period; + count = samples; + } + + fifo_bytes = count * KX022A_FIFO_SAMPLES_SIZE_BYTES; + ret = regmap_noinc_read(data->regmap, KX022A_REG_BUF_READ, + &buffer[0], fifo_bytes); + if (ret) + goto renable_out; + + for (i = 0; i < count; i++) { + __le16 *sam = &buffer[i * 3]; + __le16 *chs; + int bit; + + chs = &data->scan.channels[0]; + for_each_set_bit(bit, idev->active_scan_mask, AXIS_MAX) + chs[bit] = sam[bit]; + + iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp); + + tstamp += sample_period; + } + + ret = count; + +renable_out: + if (renable) + enable_irq(data->irq); + + return ret; +} + +static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples) +{ + struct kx022a_data *data = iio_priv(idev); + int ret; + + mutex_lock(&data->mutex); + ret = __kx022a_fifo_flush(idev, samples, false); + mutex_unlock(&data->mutex); + + return ret; +} + +static const struct iio_info kx022a_info = { + .read_raw = &kx022a_read_raw, + .write_raw = &kx022a_write_raw, + .read_avail = &kx022a_read_avail, + + .validate_trigger = kx022a_validate_trigger, + .hwfifo_set_watermark = kx022a_set_watermark, + .hwfifo_flush_to_buffer = kx022a_fifo_flush, +}; + +static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en) +{ + if (en) + return regmap_set_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_DRDY); + + return regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_DRDY); +} + +static int kx022a_prepare_irq_pin(struct kx022a_data *data) +{ + /* Enable IRQ1 pin. Set polarity to active low */ + int mask = KX022A_MASK_IEN | KX022A_MASK_IPOL | + KX022A_MASK_ITYP; + int val = KX022A_MASK_IEN | KX022A_IPOL_LOW | + KX022A_ITYP_LEVEL; + int ret; + + ret = regmap_update_bits(data->regmap, data->inc_reg, mask, val); + if (ret) + return ret; + + /* We enable WMI to IRQ pin only at buffer_enable */ + mask = KX022A_MASK_INS2_DRDY; + + return regmap_set_bits(data->regmap, data->ien_reg, mask); +} + +static int kx022a_fifo_disable(struct kx022a_data *data) +{ + int ret = 0; + + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + ret = regmap_clear_bits(data->regmap, data->ien_reg, KX022A_MASK_WMI); + if (ret) + goto unlock_out; + + ret = regmap_clear_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BUF_EN); + if (ret) + goto unlock_out; + + data->state &= ~KX022A_STATE_FIFO; + + kx022a_drop_fifo_contents(data); + + return kx022a_turn_on_unlock(data); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_buffer_predisable(struct iio_dev *idev) +{ + struct kx022a_data *data = iio_priv(idev); + + if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED) + return 0; + + return kx022a_fifo_disable(data); +} + +static int kx022a_fifo_enable(struct kx022a_data *data) +{ + int ret; + + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + /* Update watermark to HW */ + ret = kx022a_fifo_set_wmi(data); + if (ret) + goto unlock_out; + + /* Enable buffer */ + ret = regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BUF_EN); + if (ret) + goto unlock_out; + + data->state |= KX022A_STATE_FIFO; + ret = regmap_set_bits(data->regmap, data->ien_reg, + KX022A_MASK_WMI); + if (ret) + goto unlock_out; + + return kx022a_turn_on_unlock(data); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_buffer_postenable(struct iio_dev *idev) +{ + struct kx022a_data *data = iio_priv(idev); + + /* + * If we use data-ready trigger, then the IRQ masks should be handled by + * trigger enable and the hardware buffer is not used but we just update + * results to the IIO fifo when data-ready triggers. + */ + if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED) + return 0; + + return kx022a_fifo_enable(data); +} + +static const struct iio_buffer_setup_ops kx022a_buffer_ops = { + .postenable = kx022a_buffer_postenable, + .predisable = kx022a_buffer_predisable, +}; + +static irqreturn_t kx022a_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *idev = pf->indio_dev; + struct kx022a_data *data = iio_priv(idev); + int ret; + + ret = regmap_bulk_read(data->regmap, KX022A_REG_XOUT_L, data->buffer, + KX022A_FIFO_SAMPLES_SIZE_BYTES); + if (ret < 0) + goto err_read; + + iio_push_to_buffers_with_timestamp(idev, data->buffer, pf->timestamp); +err_read: + iio_trigger_notify_done(idev->trig); + + return IRQ_HANDLED; +} + +/* Get timestamps and wake the thread if we need to read data */ +static irqreturn_t kx022a_irq_handler(int irq, void *private) +{ + struct iio_dev *idev = private; + struct kx022a_data *data = iio_priv(idev); + + data->old_timestamp = data->timestamp; + data->timestamp = iio_get_time_ns(idev); + + if (data->state & KX022A_STATE_FIFO || data->trigger_enabled) + return IRQ_WAKE_THREAD; + + return IRQ_NONE; +} + +/* + * WMI and data-ready IRQs are acked when results are read. If we add + * TILT/WAKE or other IRQs - then we may need to implement the acking + * (which is racy). + */ +static irqreturn_t kx022a_irq_thread_handler(int irq, void *private) +{ + struct iio_dev *idev = private; + struct kx022a_data *data = iio_priv(idev); + irqreturn_t ret = IRQ_NONE; + + mutex_lock(&data->mutex); + + if (data->trigger_enabled) { + iio_trigger_poll_chained(data->trig); + ret = IRQ_HANDLED; + } + + if (data->state & KX022A_STATE_FIFO) { + int ok; + + ok = __kx022a_fifo_flush(idev, KX022A_FIFO_LENGTH, true); + if (ok > 0) + ret = IRQ_HANDLED; + } + + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct kx022a_data *data = iio_trigger_get_drvdata(trig); + int ret = 0; + + mutex_lock(&data->mutex); + + if (data->trigger_enabled == state) + goto unlock_out; + + if (data->state & KX022A_STATE_FIFO) { + dev_warn(data->dev, "Can't set trigger when FIFO enabled\n"); + ret = -EBUSY; + goto unlock_out; + } + + ret = kx022a_turn_on_off_unlocked(data, false); + if (ret) + goto unlock_out; + + data->trigger_enabled = state; + ret = kx022a_set_drdy_irq(data, state); + if (ret) + goto unlock_out; + + ret = kx022a_turn_on_off_unlocked(data, true); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static const struct iio_trigger_ops kx022a_trigger_ops = { + .set_trigger_state = kx022a_trigger_set_state, +}; + +static int kx022a_chip_init(struct kx022a_data *data) +{ + int ret, val; + + /* Reset the senor */ + ret = regmap_write(data->regmap, KX022A_REG_CNTL2, KX022A_MASK_SRST); + if (ret) + return ret; + + /* + * I've seen I2C read failures if we poll too fast after the sensor + * reset. Slight delay gives I2C block the time to recover. + */ + msleep(1); + + ret = regmap_read_poll_timeout(data->regmap, KX022A_REG_CNTL2, val, + !(val & KX022A_MASK_SRST), + KX022A_SOFT_RESET_WAIT_TIME_US, + KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US); + if (ret) { + dev_err(data->dev, "Sensor reset %s\n", + val & KX022A_MASK_SRST ? "timeout" : "fail#"); + return ret; + } + + ret = regmap_reinit_cache(data->regmap, &kx022a_regmap); + if (ret) { + dev_err(data->dev, "Failed to reinit reg cache\n"); + return ret; + } + + /* set data res 16bit */ + ret = regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BRES16); + if (ret) { + dev_err(data->dev, "Failed to set data resolution\n"); + return ret; + } + + return kx022a_prepare_irq_pin(data); +} + +int kx022a_probe_internal(struct device *dev) +{ + static const char * const regulator_names[] = {"io-vdd", "vdd"}; + struct iio_trigger *indio_trig; + struct fwnode_handle *fwnode; + struct kx022a_data *data; + struct regmap *regmap; + unsigned int chip_id; + struct iio_dev *idev; + int ret, irq; + char *name; + + regmap = dev_get_regmap(dev, NULL); + if (!regmap) { + dev_err(dev, "no regmap\n"); + return -EINVAL; + } + + fwnode = dev_fwnode(dev); + if (!fwnode) + return -ENODEV; + + idev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!idev) + return -ENOMEM; + + data = iio_priv(idev); + + /* + * VDD is the analog and digital domain voltage supply and + * IO_VDD is the digital I/O voltage supply. + */ + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to enable regulator\n"); + + ret = regmap_read(regmap, KX022A_REG_WHO, &chip_id); + if (ret) + return dev_err_probe(dev, ret, "Failed to access sensor\n"); + + if (chip_id != KX022A_ID) { + dev_err(dev, "unsupported device 0x%x\n", chip_id); + return -EINVAL; + } + + irq = fwnode_irq_get_byname(fwnode, "INT1"); + if (irq > 0) { + data->inc_reg = KX022A_REG_INC1; + data->ien_reg = KX022A_REG_INC4; + } else { + irq = fwnode_irq_get_byname(fwnode, "INT2"); + if (irq <= 0) + return dev_err_probe(dev, irq, "No suitable IRQ\n"); + + data->inc_reg = KX022A_REG_INC5; + data->ien_reg = KX022A_REG_INC6; + } + + data->regmap = regmap; + data->dev = dev; + data->irq = irq; + data->odr_ns = KX022A_DEFAULT_PERIOD_NS; + mutex_init(&data->mutex); + + idev->channels = kx022a_channels; + idev->num_channels = ARRAY_SIZE(kx022a_channels); + idev->name = "kx022-accel"; + idev->info = &kx022a_info; + idev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; + idev->available_scan_masks = kx022a_scan_masks; + + /* Read the mounting matrix, if present */ + ret = iio_read_mount_matrix(dev, &data->orientation); + if (ret) + return ret; + + /* The sensor must be turned off for configuration */ + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + ret = kx022a_chip_init(data); + if (ret) { + mutex_unlock(&data->mutex); + return ret; + } + + ret = kx022a_turn_on_unlock(data); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup_ext(dev, idev, + &iio_pollfunc_store_time, + kx022a_trigger_handler, + IIO_BUFFER_DIRECTION_IN, + &kx022a_buffer_ops, + kx022a_fifo_attributes); + + if (ret) + return dev_err_probe(data->dev, ret, + "iio_triggered_buffer_setup_ext FAIL\n"); + indio_trig = devm_iio_trigger_alloc(dev, "%sdata-rdy-dev%d", idev->name, + iio_device_id(idev)); + if (!indio_trig) + return -ENOMEM; + + data->trig = indio_trig; + + indio_trig->ops = &kx022a_trigger_ops; + iio_trigger_set_drvdata(indio_trig, data); + + /* + * No need to check for NULL. request_threaded_irq() defaults to + * dev_name() should the alloc fail. + */ + name = devm_kasprintf(data->dev, GFP_KERNEL, "%s-kx022a", + dev_name(data->dev)); + + ret = devm_request_threaded_irq(data->dev, irq, kx022a_irq_handler, + &kx022a_irq_thread_handler, + IRQF_ONESHOT, name, idev); + if (ret) + return dev_err_probe(data->dev, ret, "Could not request IRQ\n"); + + + ret = devm_iio_trigger_register(dev, indio_trig); + if (ret) + return dev_err_probe(data->dev, ret, + "Trigger registration failed\n"); + + ret = devm_iio_device_register(data->dev, idev); + if (ret < 0) + return dev_err_probe(dev, ret, + "Unable to register iio device\n"); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(kx022a_probe_internal, IIO_KX022A); + +MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/kionix-kx022a.h b/drivers/iio/accel/kionix-kx022a.h new file mode 100644 index 0000000000000..12424649d438b --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#ifndef _KX022A_H_ +#define _KX022A_H_ + +#include +#include + +#define KX022A_REG_WHO 0x0f +#define KX022A_ID 0xc8 + +#define KX022A_REG_CNTL2 0x19 +#define KX022A_MASK_SRST BIT(7) +#define KX022A_REG_CNTL 0x18 +#define KX022A_MASK_PC1 BIT(7) +#define KX022A_MASK_RES BIT(6) +#define KX022A_MASK_DRDY BIT(5) +#define KX022A_MASK_GSEL GENMASK(4, 3) +#define KX022A_GSEL_SHIFT 3 +#define KX022A_GSEL_2 0x0 +#define KX022A_GSEL_4 BIT(3) +#define KX022A_GSEL_8 BIT(4) +#define KX022A_GSEL_16 GENMASK(4, 3) + +#define KX022A_REG_INS2 0x13 +#define KX022A_MASK_INS2_DRDY BIT(4) +#define KX122_MASK_INS2_WMI BIT(5) + +#define KX022A_REG_XHP_L 0x0 +#define KX022A_REG_XOUT_L 0x06 +#define KX022A_REG_YOUT_L 0x08 +#define KX022A_REG_ZOUT_L 0x0a +#define KX022A_REG_COTR 0x0c +#define KX022A_REG_TSCP 0x10 +#define KX022A_REG_INT_REL 0x17 + +#define KX022A_REG_ODCNTL 0x1b + +#define KX022A_REG_BTS_WUF_TH 0x31 +#define KX022A_REG_MAN_WAKE 0x2c + +#define KX022A_REG_BUF_CNTL1 0x3a +#define KX022A_MASK_WM_TH GENMASK(6, 0) +#define KX022A_REG_BUF_CNTL2 0x3b +#define KX022A_MASK_BUF_EN BIT(7) +#define KX022A_MASK_BRES16 BIT(6) +#define KX022A_REG_BUF_STATUS_1 0x3c +#define KX022A_REG_BUF_STATUS_2 0x3d +#define KX022A_REG_BUF_CLEAR 0x3e +#define KX022A_REG_BUF_READ 0x3f +#define KX022A_MASK_ODR GENMASK(3, 0) +#define KX022A_ODR_SHIFT 3 +#define KX022A_FIFO_MAX_WMI_TH 41 + +#define KX022A_REG_INC1 0x1c +#define KX022A_REG_INC5 0x20 +#define KX022A_REG_INC6 0x21 +#define KX022A_MASK_IEN BIT(5) +#define KX022A_MASK_IPOL BIT(4) +#define KX022A_IPOL_LOW 0 +#define KX022A_IPOL_HIGH KX022A_MASK_IPOL1 +#define KX022A_MASK_ITYP BIT(3) +#define KX022A_ITYP_PULSE KX022A_MASK_ITYP +#define KX022A_ITYP_LEVEL 0 + +#define KX022A_REG_INC4 0x1f +#define KX022A_MASK_WMI BIT(5) + +#define KX022A_REG_SELF_TEST 0x60 +#define KX022A_MAX_REGISTER 0x60 + +struct device; + +int kx022a_probe_internal(struct device *dev); +extern const struct regmap_config kx022a_regmap; + +#endif -- GitLab From d269e0d60761e9d2a6ca2adb9b3b44323a2f55cb Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 24 Oct 2022 15:40:58 +0300 Subject: [PATCH 0933/1480] MAINTAINERS: Add KX022A maintainer entry Add maintainer entry for ROHM/Kionix KX022A accelerometer sensor driver. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/7895435f7fd31a3b576fc6a59b01eb3202c85d36.1666614295.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ecec0bb6b09e3..be373dfae4dd4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11450,6 +11450,12 @@ F: drivers/mfd/khadas-mcu.c F: include/linux/mfd/khadas-mcu.h F: drivers/thermal/khadas_mcu_fan.c +KIONIX/ROHM KX022A ACCELEROMETER +M: Matti Vaittinen +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/accel/kionix-kx022a* + KMEMLEAK M: Catalin Marinas S: Maintained -- GitLab From 6abcb19e0a6a371b5dafe4473ea886a6891a5cd5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 4 Nov 2022 09:31:48 +0000 Subject: [PATCH 0934/1480] iio: adc: ad4130: Fix spelling mistake "diffreential" -> "differential" There is a spelling mistake in an error message. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221104093148.167765-1-colin.i.king@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4130.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index 9a4d0043d797e..ae1a4dd5c40ad 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -1480,7 +1480,7 @@ static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin) if (pin >= AD4130_MAX_DIFF_INPUTS) return dev_err_probe(dev, -EINVAL, - "Invalid diffreential channel %u\n", pin); + "Invalid differential channel %u\n", pin); if (pin >= AD4130_MAX_ANALOG_PINS) return 0; -- GitLab From 2cc64a23c4e26107887af23a62f8ba3c79ff7ab5 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:12:04 +0300 Subject: [PATCH 0935/1480] iio: Add IIO_STATIC_CONST_DEVICE_ATTR Add IIO_STATIC_CONST_DEVICE_ATTR macro for creating an read-only iio_dev_attr which returns constant value. This macro is intended to be used when replacing the IIO_CONST_ATTR - attributes for triggered buffers because the triggered buffer attributes must be of type iio_dev_attr. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/8dd853dd0ef8eb40cb980cc6f6e7a43166de3afb.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- include/linux/iio/sysfs.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h index e51fba66de4b2..de5bb125815c5 100644 --- a/include/linux/iio/sysfs.h +++ b/include/linux/iio/sysfs.h @@ -97,6 +97,17 @@ struct iio_const_attr { = { .string = _string, \ .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} +#define IIO_STATIC_CONST_DEVICE_ATTR(_name, _string) \ + static ssize_t iio_const_dev_attr_show_##_name( \ + struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ + return sysfs_emit(buf, "%s\n", _string); \ + } \ + static IIO_DEVICE_ATTR(_name, 0444, \ + iio_const_dev_attr_show_##_name, NULL, 0) + /* Generic attributes of onetype or another */ /** -- GitLab From f0ab171b80d49a2a47b88f79de38ca64c7d641d4 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:12:25 +0300 Subject: [PATCH 0936/1480] iio: adxl367: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/c96c55363b8f36017ef7f18fdfe810cd3990e2a4.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index d7af3a006a444..d8e98f65f25df 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1183,22 +1183,9 @@ static ssize_t adxl367_get_fifo_watermark(struct device *dev, return sysfs_emit(buf, "%d\n", fifo_watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(ADXL367_FIFO_MAX_WATERMARK)); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl367_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, -- GitLab From f7e6804509eeb27accc6625150db3f02d0b93ad7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:12:48 +0300 Subject: [PATCH 0937/1480] iio: adxl372: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/3632af8849ef101c54ec1f739596f22c773b067c.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl372.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index bc53af809d5de..90e1d726b9c59 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -998,22 +998,9 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev, return sprintf(buf, "%d\n", st->watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(ADXL372_FIFO_SIZE)); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl372_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, -- GitLab From c02b2a5166a58823e8a335c486ee71ce4f22f2b7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:10 +0300 Subject: [PATCH 0938/1480] iio: bmc150-accel-core: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/b1b0d662705b43d68594639fb7719bc431101f79.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 92f8b139acce9..b4a0779448967 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -925,22 +925,9 @@ static const struct iio_chan_spec_ext_info bmc150_accel_ext_info[] = { { } }; -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(BMC150_ACCEL_FIFO_LENGTH)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(BMC150_ACCEL_FIFO_LENGTH)); static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO, bmc150_accel_get_fifo_state, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO, -- GitLab From c1531e3ad43f5e66cd04ae19644343b9222204d2 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:31 +0300 Subject: [PATCH 0939/1480] iio: at91-sama5d2_adc: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Tested-by: Claudiu Beznea Link: https://lore.kernel.org/r/4476a4ce852febb3eb863878e66751c787195b18.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 33e2515522149..aa2e1640c4a3c 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2193,26 +2193,13 @@ static ssize_t at91_adc_get_watermark(struct device *dev, return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "2"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", AT91_HWFIFO_MAX_SIZE_STR); -} - static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, at91_adc_get_fifo_state, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, at91_adc_get_watermark, NULL, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); + +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR); static const struct attribute *at91_adc_fifo_attributes[] = { &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, -- GitLab From 0a33755c4b01ed62a6d025cb585928304f9653d7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:53 +0300 Subject: [PATCH 0940/1480] iio: Don't silently expect attribute types The iio_triggered_buffer_setup_ext() and the devm_iio_kfifo_buffer_setup_ext() were changed by commit 15097c7a1adc ("iio: buffer: wrap all buffer attributes into iio_dev_attr") to silently expect that all attributes given in buffer_attrs array are device-attributes. This expectation was not forced by the API - and some drivers did register attributes created by IIO_CONST_ATTR(). When using IIO_CONST_ATTRs the added attribute "wrapping" does not copy the pointer to stored string constant and when the sysfs file is read the kernel will access to invalid location. Change the function signatures to expect an array of iio_dev_attrs to avoid similar errors in the future. Merge conflict resolved whilst applying due to patch crossing with two new drivers (kx022a accelerometer and ad4130 ADC). Signed-off-by: Matti Vaittinen Tested-by: Claudiu Beznea Link: https://lore.kernel.org/r/63f54787a684eb1232f1c5d275a09c786987fe4a.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367.c | 10 +++++----- drivers/iio/accel/adxl372.c | 10 +++++----- drivers/iio/accel/bmc150-accel-core.c | 12 ++++++------ drivers/iio/accel/kionix-kx022a.c | 6 +++--- drivers/iio/adc/ad4130.c | 10 +++++----- drivers/iio/adc/at91-sama5d2_adc.c | 12 ++++++------ drivers/iio/buffer/industrialio-buffer-dmaengine.c | 4 ++-- drivers/iio/buffer/industrialio-triggered-buffer.c | 4 ++-- drivers/iio/buffer/kfifo_buf.c | 2 +- .../common/cros_ec_sensors/cros_ec_sensors_core.c | 6 +++--- drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 8 ++++---- drivers/iio/industrialio-buffer.c | 11 +++++++---- include/linux/iio/buffer_impl.h | 2 +- include/linux/iio/kfifo_buf.h | 3 ++- include/linux/iio/triggered_buffer.h | 6 +++--- 15 files changed, 55 insertions(+), 51 deletions(-) diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index d8e98f65f25df..90b7ae6d42b77 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1191,11 +1191,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl367_get_fifo_enabled, NULL, 0); -static const struct attribute *adxl367_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *adxl367_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 90e1d726b9c59..c4193286eb053 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -1006,11 +1006,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl372_get_fifo_enabled, NULL, 0); -static const struct attribute *adxl372_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *adxl372_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index b4a0779448967..110591804b4c4 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -933,11 +933,11 @@ static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO, static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO, bmc150_accel_get_fifo_watermark, NULL, 0); -static const struct attribute *bmc150_accel_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *bmc150_accel_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -1665,7 +1665,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, enum bmc150_type type, const char *name, bool block_supported) { - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; struct bmc150_accel_data *data; struct iio_dev *indio_dev; int ret; diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c index 50de7f9a1cc7f..f866859855cdd 100644 --- a/drivers/iio/accel/kionix-kx022a.c +++ b/drivers/iio/accel/kionix-kx022a.c @@ -575,9 +575,9 @@ static ssize_t hwfifo_watermark_show(struct device *dev, static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); -static const struct attribute *kx022a_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *kx022a_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL }; diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index ae1a4dd5c40ad..38394341fd6e7 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -1380,11 +1380,11 @@ static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); -static const struct attribute *ad4130_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *ad4130_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL }; diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index aa2e1640c4a3c..a00b8316a12f2 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2201,11 +2201,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2"); IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR); -static const struct attribute *at91_adc_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *at91_adc_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -2222,7 +2222,7 @@ static int at91_adc_buffer_and_trigger_init(struct device *dev, struct iio_dev *indio) { struct at91_adc_state *st = iio_priv(indio); - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; int ret; if (st->selected_trig->hw_trig) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index f744b62a636ad..5f85ba38e6f6e 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -142,8 +142,8 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev, static IIO_DEVICE_ATTR(length_align_bytes, 0444, iio_dmaengine_buffer_get_length_align, NULL, 0); -static const struct attribute *iio_dmaengine_buffer_attrs[] = { - &iio_dev_attr_length_align_bytes.dev_attr.attr, +static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = { + &iio_dev_attr_length_align_bytes, NULL, }; diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c index 8d4fc97d10059..c7671b1f5eada 100644 --- a/drivers/iio/buffer/industrialio-triggered-buffer.c +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c @@ -41,7 +41,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { struct iio_buffer *buffer; int ret; @@ -110,7 +110,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { int ret; diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c index 35d8b4077376c..05b285f0eb225 100644 --- a/drivers/iio/buffer/kfifo_buf.c +++ b/drivers/iio/buffer/kfifo_buf.c @@ -270,7 +270,7 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev) int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { struct iio_buffer *buffer; diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 05a28d353e343..943e9e14d1e99 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -172,9 +172,9 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev, static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); -static const struct attribute *cros_ec_sensor_fifo_attributes[] = { - &iio_dev_attr_hwfifo_timeout.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, +static const struct iio_dev_attr *cros_ec_sensor_fifo_attributes[] = { + &iio_dev_attr_hwfifo_timeout, + &iio_dev_attr_hwfifo_watermark_max, NULL, }; diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 1151434038d40..ad8910e6ad59d 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -75,9 +75,9 @@ static IIO_DEVICE_ATTR(hwfifo_timeout, 0644, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, _hid_sensor_get_fifo_state, NULL, 0); -static const struct attribute *hid_sensor_fifo_attributes[] = { - &iio_dev_attr_hwfifo_timeout.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *hid_sensor_fifo_attributes[] = { + &iio_dev_attr_hwfifo_timeout, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -231,7 +231,7 @@ static const struct iio_trigger_ops hid_sensor_trigger_ops = { int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, struct hid_sensor_common *attrb) { - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; int ret; struct iio_trigger *trig; diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 9cd7db549fcbc..80c78bd6bbef4 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1605,6 +1605,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_dev_attr *p; + const struct iio_dev_attr *id_attr; struct attribute **attr; int ret, i, attrn, scan_el_attrcount, buffer_attrcount; const struct iio_chan_spec *channels; @@ -1614,6 +1615,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, while (buffer->attrs[buffer_attrcount] != NULL) buffer_attrcount++; } + buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs); scan_el_attrcount = 0; INIT_LIST_HEAD(&buffer->buffer_attr_list); @@ -1656,7 +1658,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, } } - attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs); + attrn = buffer_attrcount + scan_el_attrcount; attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL); if (!attr) { ret = -ENOMEM; @@ -1671,10 +1673,11 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, attr[2] = &dev_attr_watermark_ro.attr; if (buffer->attrs) - memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs, - sizeof(struct attribute *) * buffer_attrcount); + for (i = 0, id_attr = buffer->attrs[i]; + (id_attr = buffer->attrs[i]); i++) + attr[ARRAY_SIZE(iio_buffer_attrs) + i] = + (struct attribute *)&id_attr->dev_attr.attr; - buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs); buffer->buffer_group.attrs = attr; for (i = 0; i < buffer_attrcount; i++) { diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index e2ca8ea23e191..89c3fd7c29caf 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -123,7 +123,7 @@ struct iio_buffer { struct attribute_group buffer_group; /* @attrs: Standard attributes of the buffer. */ - const struct attribute **attrs; + const struct iio_dev_attr **attrs; /* @demux_bounce: Buffer for doing gather from incoming scan. */ void *demux_bounce; diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 8a83fb58232d5..22874da0c8be9 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -5,6 +5,7 @@ struct iio_buffer; struct iio_buffer_setup_ops; struct iio_dev; +struct iio_dev_attr; struct device; struct iio_buffer *iio_kfifo_allocate(void); @@ -13,7 +14,7 @@ void iio_kfifo_free(struct iio_buffer *r); int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); #define devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops) \ devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (setup_ops), NULL) diff --git a/include/linux/iio/triggered_buffer.h b/include/linux/iio/triggered_buffer.h index 7490b05fc5b2f..29e1fe146879a 100644 --- a/include/linux/iio/triggered_buffer.h +++ b/include/linux/iio/triggered_buffer.h @@ -5,8 +5,8 @@ #include #include -struct attribute; struct iio_dev; +struct iio_dev_attr; struct iio_buffer_setup_ops; int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, @@ -14,7 +14,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev); #define iio_triggered_buffer_setup(indio_dev, h, thread, setup_ops) \ @@ -28,7 +28,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); #define devm_iio_triggered_buffer_setup(dev, indio_dev, h, thread, setup_ops) \ devm_iio_triggered_buffer_setup_ext((dev), (indio_dev), (h), (thread), \ -- GitLab From 26bfb581931a020eaf560612f01009b3e179db0a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:46 +0100 Subject: [PATCH 0941/1480] iio: adc: cc10001: Add local struct device *dev variable to avoid repitition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are lots of uses of this in probe() and we are about to introduce some more, so add a local variable to simplify this. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-2-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index e16ac935693b6..eeaea1362ed12 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -307,14 +307,15 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev, static int cc10001_adc_probe(struct platform_device *pdev) { - struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; struct cc10001_adc_device *adc_dev; unsigned long adc_clk_rate; struct iio_dev *indio_dev; unsigned long channel_map; int ret; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev)); if (indio_dev == NULL) return -ENOMEM; @@ -326,7 +327,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) channel_map &= ~ret; } - adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); + adc_dev->reg = devm_regulator_get(dev, "vref"); if (IS_ERR(adc_dev->reg)) return PTR_ERR(adc_dev->reg); @@ -334,7 +335,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (ret) return ret; - indio_dev->name = dev_name(&pdev->dev); + indio_dev->name = dev_name(dev); indio_dev->info = &cc10001_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -344,23 +345,23 @@ static int cc10001_adc_probe(struct platform_device *pdev) goto err_disable_reg; } - adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc"); + adc_dev->adc_clk = devm_clk_get(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { - dev_err(&pdev->dev, "failed to get the clock\n"); + dev_err(dev, "failed to get the clock\n"); ret = PTR_ERR(adc_dev->adc_clk); goto err_disable_reg; } ret = clk_prepare_enable(adc_dev->adc_clk); if (ret) { - dev_err(&pdev->dev, "failed to enable the clock\n"); + dev_err(dev, "failed to enable the clock\n"); goto err_disable_reg; } adc_clk_rate = clk_get_rate(adc_dev->adc_clk); if (!adc_clk_rate) { ret = -EINVAL; - dev_err(&pdev->dev, "null clock rate!\n"); + dev_err(dev, "null clock rate!\n"); goto err_disable_clk; } -- GitLab From dc0ba516d103532b7f289b20119374fe3797f81b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:47 +0100 Subject: [PATCH 0942/1480] iio: adc: cc10001: Add devm_add_action_or_reset() to disable regulator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the voltage of this regulator is queried, we cannot use the devm_regulator_get_enable() call and have to role our own disable. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-3-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index eeaea1362ed12..4f42ceb40ded4 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -305,6 +305,11 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev, return 0; } +static void cc10001_reg_disable(void *priv) +{ + regulator_disable(priv); +} + static int cc10001_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -335,27 +340,28 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (ret) return ret; + ret = devm_add_action_or_reset(dev, cc10001_reg_disable, adc_dev->reg); + if (ret) + return ret; + indio_dev->name = dev_name(dev); indio_dev->info = &cc10001_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(adc_dev->reg_base)) { - ret = PTR_ERR(adc_dev->reg_base); - goto err_disable_reg; - } + if (IS_ERR(adc_dev->reg_base)) + return PTR_ERR(adc_dev->reg_base); adc_dev->adc_clk = devm_clk_get(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { dev_err(dev, "failed to get the clock\n"); - ret = PTR_ERR(adc_dev->adc_clk); - goto err_disable_reg; + return PTR_ERR(adc_dev->adc_clk); } ret = clk_prepare_enable(adc_dev->adc_clk); if (ret) { dev_err(dev, "failed to enable the clock\n"); - goto err_disable_reg; + return ret; } adc_clk_rate = clk_get_rate(adc_dev->adc_clk); @@ -400,8 +406,6 @@ err_cleanup_buffer: iio_triggered_buffer_cleanup(indio_dev); err_disable_clk: clk_disable_unprepare(adc_dev->adc_clk); -err_disable_reg: - regulator_disable(adc_dev->reg); return ret; } @@ -414,7 +418,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); clk_disable_unprepare(adc_dev->adc_clk); - regulator_disable(adc_dev->reg); return 0; } -- GitLab From c247e0d8c0d50793f459d2a7997d2f8f2105c973 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:48 +0100 Subject: [PATCH 0943/1480] iio: adc: cc10001: Use devm_clk_get_enabled() to avoid boilerplate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As this driver just enables clock in probe() and disables in remove() we can use this new function to replace boilerplate and simplify error paths. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-4-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 4f42ceb40ded4..1a3a5e0a52f79 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -352,23 +352,16 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (IS_ERR(adc_dev->reg_base)) return PTR_ERR(adc_dev->reg_base); - adc_dev->adc_clk = devm_clk_get(dev, "adc"); + adc_dev->adc_clk = devm_clk_get_enabled(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { - dev_err(dev, "failed to get the clock\n"); + dev_err(dev, "failed to get/enable the clock\n"); return PTR_ERR(adc_dev->adc_clk); } - ret = clk_prepare_enable(adc_dev->adc_clk); - if (ret) { - dev_err(dev, "failed to enable the clock\n"); - return ret; - } - adc_clk_rate = clk_get_rate(adc_dev->adc_clk); if (!adc_clk_rate) { - ret = -EINVAL; dev_err(dev, "null clock rate!\n"); - goto err_disable_clk; + return -EINVAL; } adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; @@ -385,14 +378,14 @@ static int cc10001_adc_probe(struct platform_device *pdev) /* Setup the ADC channels available on the device */ ret = cc10001_adc_channel_init(indio_dev, channel_map); if (ret < 0) - goto err_disable_clk; + return ret; mutex_init(&adc_dev->lock); ret = iio_triggered_buffer_setup(indio_dev, NULL, &cc10001_adc_trigger_h, NULL); if (ret < 0) - goto err_disable_clk; + return ret; ret = iio_device_register(indio_dev); if (ret < 0) @@ -404,8 +397,6 @@ static int cc10001_adc_probe(struct platform_device *pdev) err_cleanup_buffer: iio_triggered_buffer_cleanup(indio_dev); -err_disable_clk: - clk_disable_unprepare(adc_dev->adc_clk); return ret; } @@ -417,7 +408,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) cc10001_adc_power_down(adc_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); - clk_disable_unprepare(adc_dev->adc_clk); return 0; } -- GitLab From a43d5155b9455d38c4b3e4656131d79af61a2978 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:49 +0100 Subject: [PATCH 0944/1480] iio: adc: cc10001: Use devm_ to call device power down. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is presumably safe to call the powerdown whether or not we are in the commented shared state (the driver always did this). The power down was previously out of order wrt to the probe() function so move using devm_ will ensure it occurs after the userspace interfaces are removed. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-5-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 1a3a5e0a52f79..aecad89c00ff9 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -310,6 +310,11 @@ static void cc10001_reg_disable(void *priv) regulator_disable(priv); } +static void cc10001_pd_cb(void *priv) +{ + cc10001_adc_power_down(priv); +} + static int cc10001_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -375,6 +380,9 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (adc_dev->shared) cc10001_adc_power_up(adc_dev); + ret = devm_add_action_or_reset(dev, cc10001_pd_cb, adc_dev); + if (ret) + return ret; /* Setup the ADC channels available on the device */ ret = cc10001_adc_channel_init(indio_dev, channel_map); if (ret < 0) @@ -405,7 +413,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); - cc10001_adc_power_down(adc_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); -- GitLab From c5269fe908635c67c1eb4876df625efcfb156827 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:50 +0100 Subject: [PATCH 0945/1480] iio: adc: cc10001: Switch remaining IIO calls in probe to devm_ forms. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As everything else is now handled by devm managed releases the triggered buffer setup and IIO device registration can also be moved over to their devm forms allowing dropping of remove(). Only user of drvdata associated with the struct device was the remove function, so also drop the platform_set_drvdata() call. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-6-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index aecad89c00ff9..2cde4b44fc6e4 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -390,33 +390,12 @@ static int cc10001_adc_probe(struct platform_device *pdev) mutex_init(&adc_dev->lock); - ret = iio_triggered_buffer_setup(indio_dev, NULL, - &cc10001_adc_trigger_h, NULL); + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &cc10001_adc_trigger_h, NULL); if (ret < 0) return ret; - ret = iio_device_register(indio_dev); - if (ret < 0) - goto err_cleanup_buffer; - - platform_set_drvdata(pdev, indio_dev); - - return 0; - -err_cleanup_buffer: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} - -static int cc10001_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - - return 0; + return devm_iio_device_register(dev, indio_dev); } static const struct of_device_id cc10001_adc_dt_ids[] = { @@ -431,7 +410,6 @@ static struct platform_driver cc10001_adc_driver = { .of_match_table = cc10001_adc_dt_ids, }, .probe = cc10001_adc_probe, - .remove = cc10001_adc_remove, }; module_platform_driver(cc10001_adc_driver); -- GitLab From 306935570f23e25bff22a3273bc6f92c8f13c910 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Oct 2022 10:34:10 -0400 Subject: [PATCH 0946/1480] dt-bindings: iio: adc: qcom,spmi-vadc: simplify compatible enum The second compatible item in oneOf is just an enum, not a list. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221027143411.277980-1-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 8bac0c4120dd0..a848df37db068 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -22,13 +22,11 @@ properties: - items: - const: qcom,pms405-adc - const: qcom,spmi-adc-rev2 - - - items: - - enum: - - qcom,spmi-vadc - - qcom,spmi-adc5 - - qcom,spmi-adc-rev2 - - qcom,spmi-adc7 + - enum: + - qcom,spmi-vadc + - qcom,spmi-adc5 + - qcom,spmi-adc-rev2 + - qcom,spmi-adc7 reg: description: VADC base address in the SPMI PMIC register map -- GitLab From ea4b79e98ae0aedc0ebbe4adbb8f73b6c34f21d7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Oct 2022 10:34:11 -0400 Subject: [PATCH 0947/1480] dt-bindings: iio: adc: qcom,spmi-vadc: extend example Cleanup existing example (generic node name for spmi, use 4-space indentation) and add example for ADCv7 copied from Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221027143411.277980-2-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/qcom,spmi-vadc.yaml | 94 ++++++++++++------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index a848df37db068..f1522196042d8 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -236,42 +236,72 @@ additionalProperties: false examples: - | - spmi_bus { - #address-cells = <1>; - #size-cells = <0>; - /* VADC node */ - pmic_vadc: adc@3100 { - compatible = "qcom,spmi-vadc"; - reg = <0x3100>; - interrupts = <0x0 0x31 0x0 0x1>; + spmi { #address-cells = <1>; #size-cells = <0>; - #io-channel-cells = <1>; - - /* Channel node */ - adc-chan@39 { - reg = <0x39>; - qcom,decimation = <512>; - qcom,ratiometric; - qcom,hw-settle-time = <200>; - qcom,avg-samples = <1>; - qcom,pre-scaling = <1 3>; - }; - - adc-chan@9 { - reg = <0x9>; - }; - - adc-chan@a { - reg = <0xa>; + /* VADC node */ + pmic_vadc: adc@3100 { + compatible = "qcom,spmi-vadc"; + reg = <0x3100>; + interrupts = <0x0 0x31 0x0 0x1>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + /* Channel node */ + adc-chan@39 { + reg = <0x39>; + qcom,decimation = <512>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,avg-samples = <1>; + qcom,pre-scaling = <1 3>; + }; + + adc-chan@9 { + reg = <0x9>; + }; + + adc-chan@a { + reg = <0xa>; + }; + + adc-chan@e { + reg = <0xe>; + }; + + adc-chan@f { + reg = <0xf>; + }; }; + }; - adc-chan@e { - reg = <0xe>; - }; + - | + #include + #include + #include - adc-chan@f { - reg = <0xf>; + spmi { + #address-cells = <1>; + #size-cells = <0>; + adc@3100 { + reg = <0x3100>; + compatible = "qcom,spmi-adc7"; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + /* Other properties are omitted */ + xo-therm@44 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + conn-therm@47 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; }; - }; }; -- GitLab From 2cfb2180c3e8002719234c43b88b040e4f89396f Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 28 Oct 2022 13:23:42 +0200 Subject: [PATCH 0948/1480] iio: imu: st_lsm6dsx: introduce sw trigger support There are some hw configuration where irq0 and/or irq1 pins are not connected to the SPI or I2C/I3C controller. In order to avoid polling the output register introduce iio-sw trigger support when irq line is not available (or hw FIFO is not supported). Suggested-by: Mario Tesi Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/93ae6ff1150b531a9d7a4d3d1b1adb8383613717.1666955685.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 3 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 78 ++++++++++++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 4 +- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 07ad8027de738..6399b0bb6f674 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -424,7 +424,7 @@ struct st_lsm6dsx_hw { struct { __le16 channels[3]; s64 ts __aligned(8); - } scan[3]; + } scan[ST_LSM6DSX_ID_MAX]; }; static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { @@ -456,6 +456,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw); int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val); int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name); int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable); +int st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, int len); int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable); static inline int diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index fe5fa08b68acb..73fd5f038375d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include #include @@ -2117,6 +2119,32 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) return fifo_len || event ? IRQ_HANDLED : IRQ_NONE; } +static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq, + void *private) +{ + struct iio_poll_func *pf = private; + struct iio_dev *iio_dev = pf->indio_dev; + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + struct st_lsm6dsx_hw *hw = sensor->hw; + + if (sensor->id == ST_LSM6DSX_ID_EXT0 || + sensor->id == ST_LSM6DSX_ID_EXT1 || + sensor->id == ST_LSM6DSX_ID_EXT2) + st_lsm6dsx_shub_read_output(hw, + (u8 *)hw->scan[sensor->id].channels, + sizeof(hw->scan[sensor->id].channels)); + else + st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address, + hw->scan[sensor->id].channels, + sizeof(hw->scan[sensor->id].channels)); + + iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id], + iio_get_time_ns(iio_dev)); + iio_trigger_notify_done(iio_dev->trig); + + return IRQ_HANDLED; +} + static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) { struct st_sensors_platform_data *pdata; @@ -2175,6 +2203,46 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) return 0; } +static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + + return st_lsm6dsx_device_set_enable(sensor, true); +} + +static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + + return st_lsm6dsx_device_set_enable(sensor, false); +} + +static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = { + .preenable = st_lsm6dsx_sw_buffer_preenable, + .postdisable = st_lsm6dsx_sw_buffer_postdisable, +}; + +static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw) +{ + int i; + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + int err; + + if (!hw->iio_devs[i]) + continue; + + err = devm_iio_triggered_buffer_setup(hw->dev, + hw->iio_devs[i], NULL, + st_lsm6dsx_sw_trigger_handler_thread, + &st_lsm6dsx_sw_buffer_ops); + if (err) + return err; + } + + return 0; +} + static int st_lsm6dsx_init_regulators(struct device *dev) { /* vdd-vddio power regulators */ @@ -2255,6 +2323,16 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } + if (!hw->irq || !hw->settings->fifo_ops.read_fifo) { + /* + * Rely on sw triggers (e.g. hr-timers) if irq pin is not + * connected of if the device does not support HW FIFO + */ + err = st_lsm6dsx_sw_buffers_setup(hw); + if (err) + return err; + } + err = iio_read_mount_matrix(hw->dev, &hw->orientation); if (err) return err; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index 99562ba85ee43..f2b64b4956a33 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -170,9 +170,7 @@ static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) * * Read st_lsm6dsx i2c controller register */ -static int -st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, - int len) +int st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, int len) { const struct st_lsm6dsx_shub_settings *hub_settings; int err; -- GitLab From a1c6d631ff12cd41201c3ab824f3c4db66621c13 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 31 Oct 2022 12:41:25 +0100 Subject: [PATCH 0949/1480] iio: imu: st_lsm6dsx: add support to LSM6DSV Add support to STM LSM6DSV (accelerometer and gyroscope) Mems sensor. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dsv.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/aad879e7af0fe583bbf043a2b93e32fade79fa19.1667216004.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 + .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 202 ++++++++++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 + 6 files changed, 216 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 2ed2b3f40c0b1..1c68bac94bcee 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,7 +13,7 @@ config IIO_ST_LSM6DSX sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx, - the accelerometer/gyroscope of lsm9ds1 and lsm6dst. + lsm6dsv, the accelerometer/gyroscope of lsm9ds1 and lsm6dst. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6399b0bb6f674..ab61895cf0720 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -33,6 +33,7 @@ #define ST_LSM6DSOP_DEV_NAME "lsm6dsop" #define ST_ASM330LHHX_DEV_NAME "asm330lhhx" #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" +#define ST_LSM6DSV_DEV_NAME "lsm6dsv" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -53,6 +54,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSOP_ID, ST_ASM330LHHX_ID, ST_LSM6DSTX_ID, + ST_LSM6DSV_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 48fe6a45671bd..7dd5205aea5b4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -15,7 +15,7 @@ * value of the decimation factor and ODR set for each FIFO data set. * * LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/LSM6DSRX/ISM330DHCX/ - * LSM6DST/LSM6DSOP/LSM6DSTX: + * LSM6DST/LSM6DSOP/LSM6DSTX/LSM6DSV: * The FIFO buffer can be configured to store data from gyroscope and * accelerometer. Each sample is queued with a tag (1B) indicating data * source (gyroscope, accelerometer, hw timer). diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 73fd5f038375d..5e716a5071fd4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -1162,6 +1162,208 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .wakeup_src_x_mask = BIT(2), }, }, + { + .reset = { + .addr = 0x12, + .mask = BIT(0), + }, + .boot = { + .addr = 0x12, + .mask = BIT(7), + }, + .bdu = { + .addr = 0x12, + .mask = BIT(6), + }, + .id = { + { + .hw_id = ST_LSM6DSV_ID, + .name = ST_LSM6DSV_DEV_NAME, + .wai = 0x70, + }, + }, + .channels = { + [ST_LSM6DSX_ID_ACC] = { + .chan = st_lsm6dsx_acc_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + }, + [ST_LSM6DSX_ID_GYRO] = { + .chan = st_lsm6dsx_gyro_channels, + .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), + }, + }, + .drdy_mask = { + .addr = 0x13, + .mask = BIT(3), + }, + .odr_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(3, 0), + }, + .odr_avl[0] = { 7500, 0x02 }, + .odr_avl[1] = { 15000, 0x03 }, + .odr_avl[2] = { 30000, 0x04 }, + .odr_avl[3] = { 60000, 0x05 }, + .odr_avl[4] = { 120000, 0x06 }, + .odr_avl[5] = { 240000, 0x07 }, + .odr_avl[6] = { 480000, 0x08 }, + .odr_avl[7] = { 960000, 0x09 }, + .odr_len = 8, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(3, 0), + }, + .odr_avl[0] = { 7500, 0x02 }, + .odr_avl[1] = { 15000, 0x03 }, + .odr_avl[2] = { 30000, 0x04 }, + .odr_avl[3] = { 60000, 0x05 }, + .odr_avl[4] = { 120000, 0x06 }, + .odr_avl[5] = { 240000, 0x07 }, + .odr_avl[6] = { 480000, 0x08 }, + .odr_avl[7] = { 960000, 0x09 }, + .odr_len = 8, + }, + }, + .fs_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x17, + .mask = GENMASK(1, 0), + }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x1 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x2 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x3 }, + .fs_len = 4, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x15, + .mask = GENMASK(3, 0), + }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x1 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x2 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x3 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x4 }, + .fs_len = 4, + }, + }, + .irq_config = { + .irq1 = { + .addr = 0x0d, + .mask = BIT(3), + }, + .irq2 = { + .addr = 0x0e, + .mask = BIT(3), + }, + .lir = { + .addr = 0x56, + .mask = BIT(0), + }, + .irq1_func = { + .addr = 0x5e, + .mask = BIT(5), + }, + .irq2_func = { + .addr = 0x5f, + .mask = BIT(5), + }, + .hla = { + .addr = 0x03, + .mask = BIT(4), + }, + .od = { + .addr = 0x03, + .mask = BIT(3), + }, + }, + .batch = { + [ST_LSM6DSX_ID_ACC] = { + .addr = 0x09, + .mask = GENMASK(3, 0), + }, + [ST_LSM6DSX_ID_GYRO] = { + .addr = 0x09, + .mask = GENMASK(7, 4), + }, + }, + .fifo_ops = { + .update_fifo = st_lsm6dsx_update_fifo, + .read_fifo = st_lsm6dsx_read_tagged_fifo, + .fifo_th = { + .addr = 0x07, + .mask = GENMASK(7, 0), + }, + .fifo_diff = { + .addr = 0x1b, + .mask = GENMASK(8, 0), + }, + .max_size = 512, + .th_wl = 1, + }, + .ts_settings = { + .timer_en = { + .addr = 0x50, + .mask = BIT(6), + }, + .decimator = { + .addr = 0x0a, + .mask = GENMASK(7, 6), + }, + .freq_fine = 0x4f, + }, + .shub_settings = { + .page_mux = { + .addr = 0x01, + .mask = BIT(6), + }, + .master_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(2), + }, + .pullup_en = { + .addr = 0x03, + .mask = BIT(6), + }, + .aux_sens = { + .addr = 0x14, + .mask = GENMASK(1, 0), + }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, + .slv0_addr = 0x15, + .dw_slv0_addr = 0x21, + .batch_en = BIT(3), + }, + .event_settings = { + .enable_reg = { + .addr = 0x50, + .mask = BIT(7), + }, + .wakeup_reg = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .wakeup_src_reg = 0x45, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), + }, + }, }; int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 307c8c436862a..239c8920a31f8 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -109,6 +109,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dstx", .data = (void *)ST_LSM6DSTX_ID, }, + { + .compatible = "st,lsm6dsv", + .data = (void *)ST_LSM6DSV_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -132,6 +136,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, + { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 6a4eecf4bb050..66705ef16ed04 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -109,6 +109,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dstx", .data = (void *)ST_LSM6DSTX_ID, }, + { + .compatible = "st,lsm6dsv", + .data = (void *)ST_LSM6DSV_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -132,6 +136,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, + { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- GitLab From 9b4901528f57fe88c7e0a0bfdf69d8edcaad46fb Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 31 Oct 2022 12:41:26 +0100 Subject: [PATCH 0950/1480] dt-bindings: iio: imu: st_lsm6dsx: add lsm6dsv device bindings Introduce device bindings for LSM6DSV IMU sensor. Signed-off-by: Lorenzo Bianconi Acked-by: Rob Herring Link: https://lore.kernel.org/r/c34cea4468dc26050dff812f47e1a21f8e544758.1667216004.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index fe1e02e5d7b39..e7349a3275dda 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -32,6 +32,7 @@ properties: - st,lsm6dsrx - st,lsm6dst - st,lsm6dsop + - st,lsm6dsv - items: - const: st,asm330lhhx - const: st,lsm6dsr -- GitLab From 75347e30f142521c140ba1f5011d4fb175c1406b Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Mon, 31 Oct 2022 12:51:27 +0200 Subject: [PATCH 0951/1480] drivers: iio: accel: Use warning if invalid device id is detected Use warning instead of failing driver probe if invalid device id is detected for ADXL355 device. Signed-off-by: Ramona Bolboaca Link: https://lore.kernel.org/r/20221031105129.47740-2-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl355_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 4bc648eac8b29..dd08253d66d06 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -262,10 +262,8 @@ static int adxl355_setup(struct adxl355_data *data) if (ret) return ret; - if (regval != ADXL355_PARTID_VAL) { - dev_err(data->dev, "Invalid DEV ID 0x%02x\n", regval); - return -ENODEV; - } + if (regval != ADXL355_PARTID_VAL) + dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval); /* * Perform a software reset to make sure the device is in a consistent -- GitLab From b311d2e170761fbf73184d236f53187e3db8bd14 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Mon, 31 Oct 2022 12:51:28 +0200 Subject: [PATCH 0952/1480] dt-bindings: iio: accel: Add docs for ADXL359 Update ADXL355 existing documentation with documentation for ADXL359 device. Signed-off-by: Ramona Bolboaca Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221031105129.47740-3-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/accel/adi,adxl355.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml index 14b487088ab49..6b03c4efbb083 100644 --- a/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml @@ -4,20 +4,22 @@ $id: http://devicetree.org/schemas/iio/accel/adi,adxl355.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer +title: Analog Devices ADXL355 and ADXL359 3-Axis, Low noise MEMS Accelerometers maintainers: - Puranjay Mohan description: | - Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer that supports - both I2C & SPI interfaces + Analog Devices ADXL355 and ADXL359 3-Axis, Low noise MEMS Accelerometers that + support both I2C & SPI interfaces https://www.analog.com/en/products/adxl355.html + https://www.analog.com/en/products/adxl359.html properties: compatible: enum: - adi,adxl355 + - adi,adxl359 reg: maxItems: 1 -- GitLab From d3532d69757f9c6a73155d73bd9b94b64b12ef72 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Mon, 31 Oct 2022 12:51:29 +0200 Subject: [PATCH 0953/1480] drivers: iio: accel: Add support for ADXL359 device Add support for ADXL359 device in already existing ADXL355 driver. Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl359.pdf Signed-off-by: Ramona Bolboaca Link: https://lore.kernel.org/r/20221031105129.47740-4-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl355.h | 20 +++++++- drivers/iio/accel/adxl355_core.c | 87 +++++++++++++++++++++++++------- drivers/iio/accel/adxl355_i2c.c | 22 ++++++-- drivers/iio/accel/adxl355_spi.c | 19 +++++-- 4 files changed, 121 insertions(+), 27 deletions(-) diff --git a/drivers/iio/accel/adxl355.h b/drivers/iio/accel/adxl355.h index 6dd49b13e4fd0..061e66dc7057b 100644 --- a/drivers/iio/accel/adxl355.h +++ b/drivers/iio/accel/adxl355.h @@ -10,12 +10,30 @@ #include +enum adxl355_device_type { + ADXL355, + ADXL359, +}; + +struct adxl355_fractional_type { + int integer; + int decimal; +}; + struct device; +struct adxl355_chip_info { + const char *name; + u8 part_id; + struct adxl355_fractional_type accel_scale; + struct adxl355_fractional_type temp_offset; +}; + extern const struct regmap_access_table adxl355_readable_regs_tbl; extern const struct regmap_access_table adxl355_writeable_regs_tbl; +extern const struct adxl355_chip_info adxl35x_chip_info[]; int adxl355_core_probe(struct device *dev, struct regmap *regmap, - const char *name); + const struct adxl355_chip_info *chip_info); #endif /* _ADXL355_H_ */ diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index dd08253d66d06..0c9225d18fb29 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -60,6 +60,7 @@ #define ADXL355_DEVID_AD_VAL 0xAD #define ADXL355_DEVID_MST_VAL 0x1D #define ADXL355_PARTID_VAL 0xED +#define ADXL359_PARTID_VAL 0xE9 #define ADXL355_RESET_CODE 0x52 static const struct regmap_range adxl355_read_reg_range[] = { @@ -83,6 +84,60 @@ const struct regmap_access_table adxl355_writeable_regs_tbl = { }; EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355); +const struct adxl355_chip_info adxl35x_chip_info[] = { + [ADXL355] = { + .name = "adxl355", + .part_id = ADXL355_PARTID_VAL, + /* + * At +/- 2g with 20-bit resolution, scale is given in datasheet + * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2. + */ + .accel_scale = { + .integer = 0, + .decimal = 38245, + }, + /* + * The datasheet defines an intercept of 1885 LSB at 25 degC + * and a slope of -9.05 LSB/C. The following formula can be used + * to find the temperature: + * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow + * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. + * Hence using some rearranging we get the scale as -110.497238 + * and offset as -2111.25. + */ + .temp_offset = { + .integer = -2111, + .decimal = 250000, + }, + }, + [ADXL359] = { + .name = "adxl359", + .part_id = ADXL359_PARTID_VAL, + /* + * At +/- 10g with 20-bit resolution, scale is given in datasheet + * as 19.5ug/LSB = 0.0000195 * 9.80665 = 0.0.00019122967 m/s^2. + */ + .accel_scale = { + .integer = 0, + .decimal = 191229, + }, + /* + * The datasheet defines an intercept of 1852 LSB at 25 degC + * and a slope of -9.05 LSB/C. The following formula can be used + * to find the temperature: + * Temp = ((RAW - 1852)/(-9.05)) + 25 but this doesn't follow + * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. + * Hence using some rearranging we get the scale as -110.497238 + * and offset as -2079.25. + */ + .temp_offset = { + .integer = -2079, + .decimal = 250000, + }, + }, +}; +EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, IIO_ADXL355); + enum adxl355_op_mode { ADXL355_MEASUREMENT, ADXL355_STANDBY, @@ -162,6 +217,7 @@ static const struct adxl355_chan_info adxl355_chans[] = { }; struct adxl355_data { + const struct adxl355_chip_info *chip_info; struct regmap *regmap; struct device *dev; struct mutex lock; /* lock to protect op_mode */ @@ -456,33 +512,25 @@ static int adxl355_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { - /* - * The datasheet defines an intercept of 1885 LSB at 25 degC - * and a slope of -9.05 LSB/C. The following formula can be used - * to find the temperature: - * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow - * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. - * Hence using some rearranging we get the scale as -110.497238 - * and offset as -2111.25. - */ case IIO_TEMP: + /* + * Temperature scale is -110.497238. + * See the detailed explanation in adxl35x_chip_info + * definition above. + */ *val = -110; *val2 = 497238; return IIO_VAL_INT_PLUS_MICRO; - /* - * At +/- 2g with 20-bit resolution, scale is given in datasheet - * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2. - */ case IIO_ACCEL: - *val = 0; - *val2 = 38245; + *val = data->chip_info->accel_scale.integer; + *val2 = data->chip_info->accel_scale.decimal; return IIO_VAL_INT_PLUS_NANO; default: return -EINVAL; } case IIO_CHAN_INFO_OFFSET: - *val = -2111; - *val2 = 250000; + *val = data->chip_info->temp_offset.integer; + *val2 = data->chip_info->temp_offset.decimal; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: *val = sign_extend32(data->calibbias[chan->address], 15); @@ -705,7 +753,7 @@ static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq) } int adxl355_core_probe(struct device *dev, struct regmap *regmap, - const char *name) + const struct adxl355_chip_info *chip_info) { struct adxl355_data *data; struct iio_dev *indio_dev; @@ -720,9 +768,10 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap, data->regmap = regmap; data->dev = dev; data->op_mode = ADXL355_STANDBY; + data->chip_info = chip_info; mutex_init(&data->lock); - indio_dev->name = name; + indio_dev->name = chip_info->name; indio_dev->info = &adxl355_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = adxl355_channels; diff --git a/drivers/iio/accel/adxl355_i2c.c b/drivers/iio/accel/adxl355_i2c.c index f67d57921c81b..6cde5ccac06b8 100644 --- a/drivers/iio/accel/adxl355_i2c.c +++ b/drivers/iio/accel/adxl355_i2c.c @@ -23,6 +23,20 @@ static const struct regmap_config adxl355_i2c_regmap_config = { static int adxl355_i2c_probe(struct i2c_client *client) { struct regmap *regmap; + const struct adxl355_chip_info *chip_data; + const struct i2c_device_id *adxl355; + + chip_data = device_get_match_data(&client->dev); + if (!chip_data) { + adxl355 = to_i2c_driver(client->dev.driver)->id_table; + if (!adxl355) + return -EINVAL; + + chip_data = (void *)i2c_match_id(adxl355, client)->driver_data; + + if (!chip_data) + return -EINVAL; + } regmap = devm_regmap_init_i2c(client, &adxl355_i2c_regmap_config); if (IS_ERR(regmap)) { @@ -32,17 +46,19 @@ static int adxl355_i2c_probe(struct i2c_client *client) return PTR_ERR(regmap); } - return adxl355_core_probe(&client->dev, regmap, client->name); + return adxl355_core_probe(&client->dev, regmap, chip_data); } static const struct i2c_device_id adxl355_i2c_id[] = { - { "adxl355", 0 }, + { "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] }, + { "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(i2c, adxl355_i2c_id); static const struct of_device_id adxl355_of_match[] = { - { .compatible = "adi,adxl355" }, + { .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] }, + { .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(of, adxl355_of_match); diff --git a/drivers/iio/accel/adxl355_spi.c b/drivers/iio/accel/adxl355_spi.c index 5fe986ae03f63..fc99534d91ffc 100644 --- a/drivers/iio/accel/adxl355_spi.c +++ b/drivers/iio/accel/adxl355_spi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "adxl355.h" @@ -24,9 +25,17 @@ static const struct regmap_config adxl355_spi_regmap_config = { static int adxl355_spi_probe(struct spi_device *spi) { - const struct spi_device_id *id = spi_get_device_id(spi); + const struct adxl355_chip_info *chip_data; struct regmap *regmap; + chip_data = device_get_match_data(&spi->dev); + if (!chip_data) { + chip_data = (void *)spi_get_device_id(spi)->driver_data; + + if (!chip_data) + return -EINVAL; + } + regmap = devm_regmap_init_spi(spi, &adxl355_spi_regmap_config); if (IS_ERR(regmap)) { dev_err(&spi->dev, "Error initializing spi regmap: %ld\n", @@ -35,17 +44,19 @@ static int adxl355_spi_probe(struct spi_device *spi) return PTR_ERR(regmap); } - return adxl355_core_probe(&spi->dev, regmap, id->name); + return adxl355_core_probe(&spi->dev, regmap, chip_data); } static const struct spi_device_id adxl355_spi_id[] = { - { "adxl355", 0 }, + { "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] }, + { "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(spi, adxl355_spi_id); static const struct of_device_id adxl355_of_match[] = { - { .compatible = "adi,adxl355" }, + { .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] }, + { .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(of, adxl355_of_match); -- GitLab From ed81d3de8eacf70c96f7012e4e16257efc2e12a9 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Sun, 6 Nov 2022 21:02:33 +0700 Subject: [PATCH 0954/1480] Documentation: ad4130: format list of in_voltage-voltage_filter_mode_available modes Sphinx reports two warnings on sysfs documentation for AD4130 driver: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130:2: WARNING: Unexpected indentation. Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130:2: WARNING: Block quote ends without a blank line; unexpected unindent. These are due to misformatting of sinc* modes list. Format it with bullet list. Since each entry spans multiple lines, separate each with a blank line. Fixes: 62094060cf3a ("iio: adc: ad4130: add AD4130 driver") Signed-off-by: Bagas Sanjaya Link: https://lore.kernel.org/r/20221106140233.74112-1-bagasdotme@gmail.com Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-adc-ad4130 | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 index d9555751d21ce..f24ed6687e900 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 @@ -3,25 +3,35 @@ KernelVersion: 6.2 Contact: linux-iio@vger.kernel.org Description: Reading returns a list with the possible filter modes. - "sinc4" - Sinc 4. Excellent noise performance. Long 1st - conversion time. No natural 50/60Hz rejection. - "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion time. - "sinc3" - Sinc3. Moderate 1st conversion time. Good noise - performance. - "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling frequency - of 50Hz, achieves simultaneous 50Hz and 60Hz - rejection. - "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion time. - Best used with a sampling frequency of at least - 216.19Hz. - "sinc3+pf1" - Sinc3 + Post Filter 1. - 53dB rejection @ 50Hz, 58dB rejection @ 60Hz. - "sinc3+pf2" - Sinc3 + Post Filter 2. - 70dB rejection @ 50Hz, 70dB rejection @ 60Hz. - "sinc3+pf3" - Sinc3 + Post Filter 3. - 99dB rejection @ 50Hz, 103dB rejection @ 60Hz. - "sinc3+pf4" - Sinc3 + Post Filter 4. - 103dB rejection @ 50Hz, 109dB rejection @ 60Hz. + + * "sinc4" - Sinc 4. Excellent noise performance. Long + 1st conversion time. No natural 50/60Hz rejection. + + * "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion + time. + + * "sinc3" - Sinc3. Moderate 1st conversion time. + Good noise performance. + + * "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling + frequency of 50Hz, achieves simultaneous 50Hz and 60Hz + rejection. + + * "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion + time. Best used with a sampling frequency of at least + 216.19Hz. + + * "sinc3+pf1" - Sinc3 + Post Filter 1. 53dB rejection @ + 50Hz, 58dB rejection @ 60Hz. + + * "sinc3+pf2" - Sinc3 + Post Filter 2. 70dB rejection @ + 50Hz, 70dB rejection @ 60Hz. + + * "sinc3+pf3" - Sinc3 + Post Filter 3. 99dB rejection @ + 50Hz, 103dB rejection @ 60Hz. + + * "sinc3+pf4" - Sinc3 + Post Filter 4. 103dB rejection @ + 50Hz, 109dB rejection @ 60Hz. What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_filter_mode KernelVersion: 6.2 -- GitLab From 5e0176213949724fbe9a8e4a39817edce337b8a0 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:29 +0200 Subject: [PATCH 0955/1480] iio: temperature: ltc2983: make bulk write buffer DMA-safe regmap_bulk_write() does not guarantee implicit DMA-safety, even though the current implementation duplicates the given buffer. Do not rely on it. Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983") Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221103130041.2153295-2-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/ltc2983.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index a60ccf1836872..1117991ca2ab6 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -209,6 +209,7 @@ struct ltc2983_data { * Holds the converted temperature */ __be32 temp __aligned(IIO_DMA_MINALIGN); + __be32 chan_val; }; struct ltc2983_sensor { @@ -313,19 +314,18 @@ static int __ltc2983_fault_handler(const struct ltc2983_data *st, return 0; } -static int __ltc2983_chan_assign_common(const struct ltc2983_data *st, +static int __ltc2983_chan_assign_common(struct ltc2983_data *st, const struct ltc2983_sensor *sensor, u32 chan_val) { u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan); - __be32 __chan_val; chan_val |= LTC2983_CHAN_TYPE(sensor->type); dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg, chan_val); - __chan_val = cpu_to_be32(chan_val); - return regmap_bulk_write(st->regmap, reg, &__chan_val, - sizeof(__chan_val)); + st->chan_val = cpu_to_be32(chan_val); + return regmap_bulk_write(st->regmap, reg, &st->chan_val, + sizeof(st->chan_val)); } static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st, -- GitLab From 4ecee36077698bc5c759571106cd29321a886735 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:30 +0200 Subject: [PATCH 0956/1480] dt-bindings: iio: temperature: ltc2983: add default values Binding properties should have default values to let the reader know if they should change it. Add them based on driver logic. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-3-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 722781aa4697e..82667adc85b10 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -34,6 +34,7 @@ properties: cases. An extra delay can be configured using this property. The value is rounded to nearest 100us. maximum: 255 + default: 0 adi,filter-notch-freq: description: @@ -45,6 +46,7 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 maximum: 2 + default: 0 '#address-cells': const: 1 @@ -104,6 +106,7 @@ patternProperties: This property set's the pulsed current value applied during open-circuit detect. enum: [10, 100, 500, 1000] + default: 10 adi,cold-junction-handle: description: @@ -163,6 +166,7 @@ patternProperties: cycles, this property will assume different predefined values on each cycle. Just set the value of the first cycle (1l). enum: [10, 20, 40, 80] + default: 10 adi,ideal-factor-value: description: @@ -170,6 +174,7 @@ patternProperties: be multiplied by 1000000 to remove the fractional part. For more information look at table 20 of the datasheet. $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 "^rtd@": type: object @@ -207,6 +212,7 @@ patternProperties: property to 5 means 4 wires with Kelvin Rsense. $ref: /schemas/types.yaml#/definitions/uint32 enum: [2, 3, 4, 5] + default: 2 adi,rsense-share: description: @@ -226,6 +232,7 @@ patternProperties: This property controls the magnitude of the excitation current applied to the RTD. enum: [5, 10, 25, 50, 100, 250, 500, 1000] + default: 5 adi,rtd-curve: description: @@ -234,6 +241,7 @@ patternProperties: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 maximum: 3 + default: 0 adi,custom-rtd: description: @@ -308,6 +316,7 @@ patternProperties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000] + default: 0 adi,custom-thermistor: description: -- GitLab From d449fb5146b9ba93cb72a0676c3da3dd7a1743a9 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:31 +0200 Subject: [PATCH 0957/1480] dt-bindings: iio: temperature: ltc2983: use hex for sensor address Addresses should be in hex, fix it. Although the driver initially specified 1-20, it can be made free-range since the address is supposed to match reg, onto which we can impose restrictions based on the compatible property value. Signed-off-by: Cosmin Tanislav Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-4-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 82667adc85b10..29f6fa5e25291 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -55,7 +55,7 @@ properties: const: 0 patternProperties: - "@([1-9]|1[0-9]|20)$": + "@([0-9a-f]+)$": type: object properties: -- GitLab From 828a6c2252babdb79c7870080e872729ea90df17 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:32 +0200 Subject: [PATCH 0958/1480] dt-bindings: iio: temperature: ltc2983: remove qutations from phandle ref Not needed, so why have them? Signed-off-by: Cosmin Tanislav Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-5-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 29f6fa5e25291..6b3a20448f78f 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -112,7 +112,7 @@ patternProperties: description: Phandle which points to a sensor object responsible for measuring the thermocouple cold junction temperature. - $ref: "/schemas/types.yaml#/definitions/phandle" + $ref: /schemas/types.yaml#/definitions/phandle adi,custom-thermocouple: description: @@ -204,7 +204,7 @@ patternProperties: adi,rsense-handle: description: Phandle pointing to a rsense object associated with this RTD. - $ref: "/schemas/types.yaml#/definitions/phandle" + $ref: /schemas/types.yaml#/definitions/phandle adi,number-of-wires: description: @@ -288,7 +288,7 @@ patternProperties: description: Phandle pointing to a rsense object associated with this thermistor. - $ref: "/schemas/types.yaml#/definitions/phandle" + $ref: /schemas/types.yaml#/definitions/phandle adi,single-ended: description: -- GitLab From 6cf75e90c5cc268d47ea67bfdf05961c1439dee4 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:33 +0200 Subject: [PATCH 0959/1480] dt-bindings: iio: temperature: ltc2983: describe matrix items Give a little bit of information on what each item in the matrix is supposed to be. Also, some matrices put the 'minItems' and 'maxItems' keywords in the wrong level. They should be on the same level as the 'items' keyword. Fix it. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-6-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 6b3a20448f78f..4f26b337c9574 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -126,8 +126,9 @@ patternProperties: minItems: 3 maxItems: 64 items: - minItems: 2 - maxItems: 2 + items: + - description: Voltage point in nV, signed. + - description: Temperature point in uK. "^diode@": type: object @@ -249,12 +250,12 @@ patternProperties: resistance(ohm)-temperature(K). The entries added here are in uohm and uK. For more details values look at table 74 and 75. $ref: /schemas/types.yaml#/definitions/uint64-matrix + minItems: 3 + maxItems: 64 items: - minItems: 3 - maxItems: 64 items: - minItems: 2 - maxItems: 2 + - description: Resistance point in uOhms. + - description: Temperature point in uK. required: - adi,rsense-handle @@ -328,8 +329,9 @@ patternProperties: minItems: 3 maxItems: 64 items: - minItems: 2 - maxItems: 2 + items: + - description: Resistance point in uOhms. + - description: Temperature point in uK. adi,custom-steinhart: description: @@ -338,9 +340,8 @@ patternProperties: Steinhart sensors the coefficients are given in the raw format. Look at table 82 for more information. $ref: /schemas/types.yaml#/definitions/uint32-array - items: - minItems: 6 - maxItems: 6 + minItems: 6 + maxItems: 6 required: - adi,rsense-handle -- GitLab From a2ebc8d281de63797fea5188f2aaa402cdb63cf1 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:34 +0200 Subject: [PATCH 0960/1480] dt-bindings: iio: temperature: ltc2983: require custom sensor tables The driver will error out when a custom sensor type is used but a custom sensor table is not provided. Require it in the binding too. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-7-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 4f26b337c9574..bbac5f5cfbb3a 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -130,6 +130,15 @@ patternProperties: - description: Voltage point in nV, signed. - description: Temperature point in uK. + allOf: + - if: + properties: + adi,sensor-type: + const: 9 + then: + required: + - adi,custom-thermocouple + "^diode@": type: object description: @@ -263,6 +272,15 @@ patternProperties: dependencies: adi,current-rotate: [ "adi,rsense-share" ] + allOf: + - if: + properties: + adi,sensor-type: + const: 18 + then: + required: + - adi,custom-rtd + "^thermistor@": type: object description: @@ -349,6 +367,22 @@ patternProperties: dependencies: adi,current-rotate: [ "adi,rsense-share" ] + allOf: + - if: + properties: + adi,sensor-type: + const: 26 + then: + required: + - adi,custom-steinhart + - if: + properties: + adi,sensor-type: + const: 27 + then: + required: + - adi,custom-thermistor + "^adc@": type: object description: Represents a channel which is being used as a direct adc. -- GitLab From b3805fc3dcf35512266bddf8c785eb82a24325bc Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:35 +0200 Subject: [PATCH 0961/1480] dt-bindings: iio: temperature: ltc2983: require 4 wire rtd for current rotate The driver will error out when current rotation is enabled but the RTD is not 4-wire. Require it in the binding too. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-8-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index bbac5f5cfbb3a..b603219fb0c98 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -230,13 +230,6 @@ patternProperties: resistor is used for multiple 2-, 3-, and/or 4-wire RTDs. type: boolean - adi,current-rotate: - description: - Boolean property which enables excitation current rotation to - automatically remove parasitic thermocouple effects. Note that - this property is not allowed for 2- and 3-wire RTDs. - type: boolean - adi,excitation-current-microamp: description: This property controls the magnitude of the excitation current @@ -269,10 +262,22 @@ patternProperties: required: - adi,rsense-handle - dependencies: - adi,current-rotate: [ "adi,rsense-share" ] - allOf: + - if: + properties: + adi,number-of-wires: + const: 4 + then: + properties: + adi,current-rotate: + description: + Whether to enable excitation current rotation to automatically + remove parasitic thermocouple effects. + type: boolean + + dependencies: + adi,current-rotate: [ "adi,rsense-share" ] + - if: properties: adi,sensor-type: -- GitLab From ee7e336c48d3f8f5bef748b202792290d0fa0c1e Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:36 +0200 Subject: [PATCH 0962/1480] dt-bindings: iio: temperature: ltc2983: change default excitation for custom thermistors Excitation cannot be set to auto-range when using a custom thermistor or Steinhart sensor type. Default it to 1000nA to match the driver and remove the auto-range value from the enum. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-9-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index b603219fb0c98..1b6a11f2aa9da 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -378,6 +378,11 @@ patternProperties: adi,sensor-type: const: 26 then: + properties: + adi,excitation-current-nanoamp: + enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000, + 250000, 500000, 1000000] + default: 1000 required: - adi,custom-steinhart - if: @@ -385,6 +390,11 @@ patternProperties: adi,sensor-type: const: 27 then: + properties: + adi,excitation-current-nanoamp: + enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000, + 250000, 500000, 1000000] + default: 1000 required: - adi,custom-thermistor -- GitLab From 95027f5b3999b1b47a407ae4aa7bee18591164d1 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:37 +0200 Subject: [PATCH 0963/1480] dt-bindings: iio: temperature: ltc2983: refine descriptions Some descriptions are too verbose, while others are too succint. Rewrite them all. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-10-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 163 +++++++----------- 1 file changed, 65 insertions(+), 98 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 1b6a11f2aa9da..676801b036cf1 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -25,21 +25,16 @@ properties: maxItems: 1 adi,mux-delay-config-us: - description: - The LTC2983 performs 2 or 3 internal conversion cycles per temperature - result. Each conversion cycle is performed with different excitation and - input multiplexer configurations. Prior to each conversion, these - excitation circuits and input switch configurations are changed and an - internal 1ms delay ensures settling prior to the conversion cycle in most - cases. An extra delay can be configured using this property. The value is - rounded to nearest 100us. + description: | + Extra delay prior to each conversion, in addition to the internal 1ms + delay, for the multiplexer to switch input configurations and + excitation values. maximum: 255 default: 0 adi,filter-notch-freq: description: - Set's the default setting of the digital filter. The default is - simultaneous 50/60Hz rejection. + Notch frequency of the digital filter. 0 - 50/60Hz rejection 1 - 60Hz rejection 2 - 50Hz rejection @@ -57,17 +52,18 @@ properties: patternProperties: "@([0-9a-f]+)$": type: object + description: Sensor. properties: reg: description: - The channel number. It can be connected to one of the 20 channels of - the device. + Channel number. Connects the sensor to the channel with this number + of the device. minimum: 1 maximum: 20 adi,sensor-type: - description: Identifies the type of sensor connected to the device. + description: Type of sensor connected to the device. $ref: /schemas/types.yaml#/definitions/uint32 required: @@ -76,9 +72,7 @@ patternProperties: "^thermocouple@": type: object - description: - Represents a thermocouple sensor which is connected to one of the device - channels. + description: Thermocouple sensor. properties: adi,sensor-type: @@ -97,31 +91,24 @@ patternProperties: maximum: 9 adi,single-ended: - description: - Boolean property which set's the thermocouple as single-ended. + description: Whether the sensor is single-ended. type: boolean adi,sensor-oc-current-microamp: - description: - This property set's the pulsed current value applied during - open-circuit detect. + description: Pulsed current value applied during open-circuit detect. enum: [10, 100, 500, 1000] default: 10 adi,cold-junction-handle: description: - Phandle which points to a sensor object responsible for measuring - the thermocouple cold junction temperature. + Sensor responsible for measuring the thermocouple cold junction + temperature. $ref: /schemas/types.yaml#/definitions/phandle adi,custom-thermocouple: description: - This is a table, where each entry should be a pair of - voltage(mv)-temperature(K). The entries must be given in nv and uK - so that, the original values must be multiplied by 1000000. For - more details look at table 69 and 70. - Note should be signed, but dtc doesn't currently maintain the - sign. + Used for digitizing custom thermocouples. + See Page 59 of the datasheet. $ref: /schemas/types.yaml#/definitions/uint64-matrix minItems: 3 maxItems: 64 @@ -141,55 +128,50 @@ patternProperties: "^diode@": type: object - description: - Represents a diode sensor which is connected to one of the device - channels. + description: Diode sensor. properties: adi,sensor-type: - description: Identifies the sensor as a diode. + description: Sensor type for diodes. $ref: /schemas/types.yaml#/definitions/uint32 const: 28 adi,single-ended: - description: Boolean property which set's the diode as single-ended. + description: Whether the sensor is single-ended. type: boolean adi,three-conversion-cycles: description: - Boolean property which set's three conversion cycles removing - parasitic resistance effects between the LTC2983 and the diode. + Whether to use three conversion cycles to remove parasitic + resistance between the device and the diode. type: boolean adi,average-on: description: - Boolean property which enables a running average of the diode - temperature reading. This reduces the noise when the diode is used - as a cold junction temperature element on an isothermal block - where temperatures change slowly. + Whether to use a running average of the diode temperature + reading to reduce the noise when the diode is used as a cold + junction temperature element on an isothermal block where + temperatures change slowly. type: boolean adi,excitation-current-microamp: description: - This property controls the magnitude of the excitation current - applied to the diode. Depending on the number of conversions - cycles, this property will assume different predefined values on - each cycle. Just set the value of the first cycle (1l). + Magnitude of the 1l excitation current applied to the diode. + 4l excitation current will be 4 times this value, and 8l + excitation current will be 8 times value. enum: [10, 20, 40, 80] default: 10 adi,ideal-factor-value: description: - This property sets the diode ideality factor. The real value must - be multiplied by 1000000 to remove the fractional part. For more - information look at table 20 of the datasheet. + Diode ideality factor. + Set this property to 1000000 times the real value. $ref: /schemas/types.yaml#/definitions/uint32 default: 0 "^rtd@": type: object - description: - Represents a rtd sensor which is connected to one of the device channels. + description: RTD sensor. properties: reg: @@ -212,35 +194,35 @@ patternProperties: maximum: 18 adi,rsense-handle: - description: - Phandle pointing to a rsense object associated with this RTD. + description: Associated sense resistor sensor. $ref: /schemas/types.yaml#/definitions/phandle adi,number-of-wires: description: - Identifies the number of wires used by the RTD. Setting this - property to 5 means 4 wires with Kelvin Rsense. + Number of wires used by the RTD. + 5 means 4 wires with Kelvin sense resistor. $ref: /schemas/types.yaml#/definitions/uint32 enum: [2, 3, 4, 5] default: 2 adi,rsense-share: description: - Boolean property which enables Rsense sharing, where one sense - resistor is used for multiple 2-, 3-, and/or 4-wire RTDs. + Whether to enable sense resistor sharing, where one sense + resistor is used by multiple sensors. type: boolean adi,excitation-current-microamp: - description: - This property controls the magnitude of the excitation current - applied to the RTD. + description: Excitation current applied to the RTD. enum: [5, 10, 25, 50, 100, 250, 500, 1000] default: 5 adi,rtd-curve: - description: - This property set the RTD curve used and the corresponding - Callendar-VanDusen constants. Look at table 30 of the datasheet. + description: | + RTD curve and the corresponding Callendar-VanDusen constants. + 0 - European + 1 - American + 2 - Japanese + 3 - ITS-90 $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 maximum: 3 @@ -248,9 +230,8 @@ patternProperties: adi,custom-rtd: description: - This is a table, where each entry should be a pair of - resistance(ohm)-temperature(K). The entries added here are in uohm - and uK. For more details values look at table 74 and 75. + Used for digitizing custom RTDs. + See Page 62 of the datasheet. $ref: /schemas/types.yaml#/definitions/uint64-matrix minItems: 3 maxItems: 64 @@ -288,9 +269,7 @@ patternProperties: "^thermistor@": type: object - description: - Represents a thermistor sensor which is connected to one of the device - channels. + description: Thermistor sensor. properties: adi,sensor-type: @@ -309,34 +288,29 @@ patternProperties: maximum: 27 adi,rsense-handle: - description: - Phandle pointing to a rsense object associated with this - thermistor. + description: Associated sense resistor sensor. $ref: /schemas/types.yaml#/definitions/phandle adi,single-ended: - description: - Boolean property which set's the thermistor as single-ended. + description: Whether the sensor is single-ended. type: boolean adi,rsense-share: description: - Boolean property which enables Rsense sharing, where one sense - resistor is used for multiple thermistors. Note that this property - is ignored if adi,single-ended is set. + Whether to enable sense resistor sharing, where one sense + resistor is used by multiple sensors. type: boolean adi,current-rotate: description: - Boolean property which enables excitation current rotation to - automatically remove parasitic thermocouple effects. + Whether to enable excitation current rotation to automatically + remove parasitic thermocouple effects. type: boolean adi,excitation-current-nanoamp: description: - This property controls the magnitude of the excitation current - applied to the thermistor. Value 0 set's the sensor in auto-range - mode. + Excitation current applied to the thermistor. + 0 sets the sensor in auto-range mode. $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000] @@ -344,10 +318,8 @@ patternProperties: adi,custom-thermistor: description: - This is a table, where each entry should be a pair of - resistance(ohm)-temperature(K). The entries added here are in uohm - and uK only for custom thermistors. For more details look at table - 78 and 79. + Used for digitizing custom thermistors. + See Page 65 of the datasheet. $ref: /schemas/types.yaml#/definitions/uint64-matrix minItems: 3 maxItems: 64 @@ -358,10 +330,9 @@ patternProperties: adi,custom-steinhart: description: - Steinhart-Hart coefficients are also supported and can - be programmed into the device memory using this property. For - Steinhart sensors the coefficients are given in the raw - format. Look at table 82 for more information. + Steinhart-Hart coefficients in raw format, used for digitizing + custom thermistors. + See Page 68 of the datasheet. $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 6 maxItems: 6 @@ -400,23 +371,21 @@ patternProperties: "^adc@": type: object - description: Represents a channel which is being used as a direct adc. + description: Direct ADC sensor. properties: adi,sensor-type: - description: Identifies the sensor as a direct adc. + description: Sensor type for direct ADC sensors. $ref: /schemas/types.yaml#/definitions/uint32 const: 30 adi,single-ended: - description: Boolean property which set's the adc as single-ended. + description: Whether the sensor is single-ended. type: boolean "^rsense@": type: object - description: - Represents a rsense which is connected to one of the device channels. - Rsense are used by thermistors and RTD's. + description: Sense resistor sensor. properties: reg: @@ -424,14 +393,12 @@ patternProperties: maximum: 20 adi,sensor-type: - description: Identifies the sensor as a rsense. + description: Sensor type sense resistor sensors. $ref: /schemas/types.yaml#/definitions/uint32 const: 29 adi,rsense-val-milli-ohms: - description: - Sets the value of the sense resistor. Look at table 20 of the - datasheet for information. + description: Value of the sense resistor. required: - adi,rsense-val-milli-ohms -- GitLab From 93144097f51bf01591da5b8f8e37b6c616a0b23a Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:38 +0200 Subject: [PATCH 0964/1480] dt-bindings: iio: temperature: ltc2983: describe broken mux delay property The 'adi,mux-delay-config-us' property is broken. It was supposed to be in us, but the value is actually written directly to the register. Describe the fact that it is broken and how it actually works. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-11-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 676801b036cf1..467e165e9b0b9 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -29,6 +29,9 @@ properties: Extra delay prior to each conversion, in addition to the internal 1ms delay, for the multiplexer to switch input configurations and excitation values. + + This property is supposed to be in microseconds, but to maintain + compatibility, this value will be multiplied by 100 before usage. maximum: 255 default: 0 -- GitLab From cf738c544da333f6a8b7927f848ea388d7e58421 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:39 +0200 Subject: [PATCH 0965/1480] dt-bindings: iio: temperature: ltc2983: use generic node name in example Examples should use the generic IIO node name of temperature-sensor. Fix it. Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221103130041.2153295-12-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 467e165e9b0b9..0e8333260a445 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -420,7 +420,7 @@ examples: #address-cells = <1>; #size-cells = <0>; - sensor_ltc2983: ltc2983@0 { + temperature-sensor@0 { compatible = "adi,ltc2983"; reg = <0>; -- GitLab From d24052695057eb5254d9fedcb5494428f23d3ecb Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:40 +0200 Subject: [PATCH 0966/1480] dt-bindings: iio: temperature: ltc2983: support more parts Add support for the following parts: * LTC2984 * LTC2986 * LTM2985 The LTC2984 is a variant of the LTC2983 with EEPROM. The LTC2986 is a variant of the LTC2983 with only 10 channels, EEPROM and support for active analog temperature sensors. The LTM2985 is software-compatible with the LTC2986. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221103130041.2153295-13-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/temperature/adi,ltc2983.yaml | 60 +++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 0e8333260a445..44f8b0672f533 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -4,19 +4,30 @@ $id: http://devicetree.org/schemas/iio/temperature/adi,ltc2983.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Analog Devices LTC2983 Multi-sensor Temperature system +title: Analog Devices LTC2983, LTC2986, LTM2985 Multi-sensor Temperature system maintainers: - Nuno Sá description: | - Analog Devices LTC2983 Multi-Sensor Digital Temperature Measurement System + Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital + Temperature Measurement Systems + https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/29861fa.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ltm2985.pdf properties: compatible: - enum: - - adi,ltc2983 + oneOf: + - enum: + - adi,ltc2983 + - adi,ltc2986 + - adi,ltm2985 + - items: + - const: adi,ltc2984 + - const: adi,ltc2983 reg: maxItems: 1 @@ -386,6 +397,35 @@ patternProperties: description: Whether the sensor is single-ended. type: boolean + "^temp@": + type: object + description: Active analog temperature sensor. + + properties: + adi,sensor-type: + description: Sensor type for active analog temperature sensors. + $ref: /schemas/types.yaml#/definitions/uint32 + const: 31 + + adi,single-ended: + description: Whether the sensor is single-ended. + type: boolean + + adi,custom-temp: + description: + Used for digitizing active analog temperature sensors. + See Page 67 of the LTM2985 datasheet. + $ref: /schemas/types.yaml#/definitions/uint64-matrix + minItems: 3 + maxItems: 64 + items: + items: + - description: Voltage point in nV, signed. + - description: Temperature point in uK. + + required: + - adi,custom-temp + "^rsense@": type: object description: Sense resistor sensor. @@ -413,6 +453,18 @@ required: additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + enum: + - adi,ltc2983 + - adi,ltc2984 + then: + patternProperties: + "^temp@": false + examples: - | #include -- GitLab From 6f7cadcf664b04df3b2e9b9c6d65bf626aa1b411 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:41 +0200 Subject: [PATCH 0967/1480] iio: temperature: ltc2983: support more parts Add support for the following parts: * LTC2984 * LTC2986 * LTM2985 The LTC2984 is a variant of the LTC2983 with EEPROM. The LTC2986 is a variant of the LTC2983 with only 10 channels, EEPROM and support for active analog temperature sensors. The LTM2985 is software-compatible with the LTC2986. Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221103130041.2153295-14-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/ltc2983.c | 183 ++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 7 deletions(-) diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 1117991ca2ab6..fcb96c44d9540 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -25,9 +25,12 @@ #define LTC2983_STATUS_REG 0x0000 #define LTC2983_TEMP_RES_START_REG 0x0010 #define LTC2983_TEMP_RES_END_REG 0x005F +#define LTC2983_EEPROM_KEY_REG 0x00B0 +#define LTC2983_EEPROM_READ_STATUS_REG 0x00D0 #define LTC2983_GLOBAL_CONFIG_REG 0x00F0 #define LTC2983_MULT_CHANNEL_START_REG 0x00F4 #define LTC2983_MULT_CHANNEL_END_REG 0x00F7 +#define LTC2986_EEPROM_STATUS_REG 0x00F9 #define LTC2983_MUX_CONFIG_REG 0x00FF #define LTC2983_CHAN_ASSIGN_START_REG 0x0200 #define LTC2983_CHAN_ASSIGN_END_REG 0x024F @@ -35,13 +38,21 @@ #define LTC2983_CUST_SENS_TBL_END_REG 0x03CF #define LTC2983_DIFFERENTIAL_CHAN_MIN 2 -#define LTC2983_MAX_CHANNELS_NR 20 #define LTC2983_MIN_CHANNELS_NR 1 #define LTC2983_SLEEP 0x97 #define LTC2983_CUSTOM_STEINHART_SIZE 24 #define LTC2983_CUSTOM_SENSOR_ENTRY_SZ 6 #define LTC2983_CUSTOM_STEINHART_ENTRY_SZ 4 +#define LTC2983_EEPROM_KEY 0xA53C0F5A +#define LTC2983_EEPROM_WRITE_CMD 0x15 +#define LTC2983_EEPROM_READ_CMD 0x16 +#define LTC2983_EEPROM_STATUS_FAILURE_MASK GENMASK(3, 1) +#define LTC2983_EEPROM_READ_FAILURE_MASK GENMASK(7, 0) + +#define LTC2983_EEPROM_WRITE_TIME_MS 2600 +#define LTC2983_EEPROM_READ_TIME_MS 20 + #define LTC2983_CHAN_START_ADDR(chan) \ (((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG) #define LTC2983_CHAN_RES_ADDR(chan) \ @@ -171,6 +182,7 @@ enum { LTC2983_SENSOR_DIODE = 28, LTC2983_SENSOR_SENSE_RESISTOR = 29, LTC2983_SENSOR_DIRECT_ADC = 30, + LTC2983_SENSOR_ACTIVE_TEMP = 31, }; #define to_thermocouple(_sensor) \ @@ -191,7 +203,17 @@ enum { #define to_adc(_sensor) \ container_of(_sensor, struct ltc2983_adc, sensor) +#define to_temp(_sensor) \ + container_of(_sensor, struct ltc2983_temp, sensor) + +struct ltc2983_chip_info { + unsigned int max_channels_nr; + bool has_temp; + bool has_eeprom; +}; + struct ltc2983_data { + const struct ltc2983_chip_info *info; struct regmap *regmap; struct spi_device *spi; struct mutex lock; @@ -210,6 +232,7 @@ struct ltc2983_data { */ __be32 temp __aligned(IIO_DMA_MINALIGN); __be32 chan_val; + __be32 eeprom_key; }; struct ltc2983_sensor { @@ -272,6 +295,12 @@ struct ltc2983_adc { bool single_ended; }; +struct ltc2983_temp { + struct ltc2983_sensor sensor; + struct ltc2983_custom_sensor *custom; + bool single_ended; +}; + /* * Convert to Q format numbers. These number's are integers where * the number of integer and fractional bits are specified. The resolution @@ -606,6 +635,22 @@ static int ltc2983_adc_assign_chan(struct ltc2983_data *st, return __ltc2983_chan_assign_common(st, sensor, chan_val); } +static int ltc2983_temp_assign_chan(struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) +{ + struct ltc2983_temp *temp = to_temp(sensor); + u32 chan_val; + int ret; + + chan_val = LTC2983_ADC_SINGLE_ENDED(temp->single_ended); + + ret = __ltc2983_chan_custom_sensor_assign(st, temp->custom, &chan_val); + if (ret) + return ret; + + return __ltc2983_chan_assign_common(st, sensor, chan_val); +} + static struct ltc2983_sensor * ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st, const struct ltc2983_sensor *sensor) @@ -771,10 +816,10 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st, if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) { /* 4-wire */ u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN, - max = LTC2983_MAX_CHANNELS_NR; + max = st->info->max_channels_nr; if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK) - max = LTC2983_MAX_CHANNELS_NR - 1; + max = st->info->max_channels_nr - 1; if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK) == LTC2983_RTD_KELVIN_R_SENSE_MASK) && @@ -1143,6 +1188,38 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child, return &adc->sensor; } +static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child, + struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) +{ + struct ltc2983_temp *temp; + + temp = devm_kzalloc(&st->spi->dev, sizeof(*temp), GFP_KERNEL); + if (!temp) + return ERR_PTR(-ENOMEM); + + if (fwnode_property_read_bool(child, "adi,single-ended")) + temp->single_ended = true; + + if (!temp->single_ended && + sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN) { + dev_err(&st->spi->dev, "Invalid chan:%d for differential temp\n", + sensor->chan); + return ERR_PTR(-EINVAL); + } + + temp->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-temp", + false, 4096, true); + if (IS_ERR(temp->custom)) + return ERR_CAST(temp->custom); + + /* set common parameters */ + temp->sensor.assign_chan = ltc2983_temp_assign_chan; + temp->sensor.fault_handler = ltc2983_common_fault_handler; + + return &temp->sensor; +} + static int ltc2983_chan_read(struct ltc2983_data *st, const struct ltc2983_sensor *sensor, int *val) { @@ -1302,10 +1379,10 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) /* check if we have a valid channel */ if (sensor.chan < LTC2983_MIN_CHANNELS_NR || - sensor.chan > LTC2983_MAX_CHANNELS_NR) { + sensor.chan > st->info->max_channels_nr) { ret = -EINVAL; dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan, - LTC2983_MIN_CHANNELS_NR, LTC2983_MAX_CHANNELS_NR); + LTC2983_MIN_CHANNELS_NR, st->info->max_channels_nr); goto put_child; } else if (channel_avail_mask & BIT(sensor.chan)) { ret = -EINVAL; @@ -1345,6 +1422,9 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) st->iio_channels--; } else if (sensor.type == LTC2983_SENSOR_DIRECT_ADC) { st->sensors[chan] = ltc2983_adc_new(child, st, &sensor); + } else if (st->info->has_temp && + sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) { + st->sensors[chan] = ltc2983_temp_new(child, st, &sensor); } else { dev_err(dev, "Unknown sensor type %d\n", sensor.type); ret = -EINVAL; @@ -1371,6 +1451,45 @@ put_child: return ret; } +static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd, + unsigned int wait_time, unsigned int status_reg, + unsigned long status_fail_mask) +{ + unsigned long time; + unsigned int val; + int ret; + + ret = regmap_bulk_write(st->regmap, LTC2983_EEPROM_KEY_REG, + &st->eeprom_key, sizeof(st->eeprom_key)); + if (ret) + return ret; + + reinit_completion(&st->completion); + + ret = regmap_write(st->regmap, LTC2983_STATUS_REG, + LTC2983_STATUS_START(true) | cmd); + if (ret) + return ret; + + time = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(wait_time)); + if (!time) { + dev_err(&st->spi->dev, "EEPROM command timed out\n"); + return -ETIMEDOUT; + } + + ret = regmap_read(st->regmap, status_reg, &val); + if (ret) + return ret; + + if (val & status_fail_mask) { + dev_err(&st->spi->dev, "EEPROM command failed: 0x%02X\n", val); + return -EINVAL; + } + + return 0; +} + static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) { u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status; @@ -1396,6 +1515,15 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) if (ret) return ret; + if (st->info->has_eeprom && !assign_iio) { + ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_READ_CMD, + LTC2983_EEPROM_READ_TIME_MS, + LTC2983_EEPROM_READ_STATUS_REG, + LTC2983_EEPROM_READ_FAILURE_MASK); + if (!ret) + return 0; + } + for (chan = 0; chan < st->num_channels; chan++) { u32 chan_type = 0, *iio_chan; @@ -1435,9 +1563,13 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) static const struct regmap_range ltc2983_reg_ranges[] = { regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG), regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG), + regmap_reg_range(LTC2983_EEPROM_KEY_REG, LTC2983_EEPROM_KEY_REG), + regmap_reg_range(LTC2983_EEPROM_READ_STATUS_REG, + LTC2983_EEPROM_READ_STATUS_REG), regmap_reg_range(LTC2983_GLOBAL_CONFIG_REG, LTC2983_GLOBAL_CONFIG_REG), regmap_reg_range(LTC2983_MULT_CHANNEL_START_REG, LTC2983_MULT_CHANNEL_END_REG), + regmap_reg_range(LTC2986_EEPROM_STATUS_REG, LTC2986_EEPROM_STATUS_REG), regmap_reg_range(LTC2983_MUX_CONFIG_REG, LTC2983_MUX_CONFIG_REG), regmap_reg_range(LTC2983_CHAN_ASSIGN_START_REG, LTC2983_CHAN_ASSIGN_END_REG), @@ -1482,6 +1614,12 @@ static int ltc2983_probe(struct spi_device *spi) st = iio_priv(indio_dev); + st->info = device_get_match_data(&spi->dev); + if (!st->info) + st->info = (void *)spi_get_device_id(spi)->driver_data; + if (!st->info) + return -ENODEV; + st->regmap = devm_regmap_init_spi(spi, <c2983_regmap_config); if (IS_ERR(st->regmap)) { dev_err(&spi->dev, "Failed to initialize regmap\n"); @@ -1491,6 +1629,7 @@ static int ltc2983_probe(struct spi_device *spi) mutex_init(&st->lock); init_completion(&st->completion); st->spi = spi; + st->eeprom_key = cpu_to_be32(LTC2983_EEPROM_KEY); spi_set_drvdata(spi, st); ret = ltc2983_parse_dt(st); @@ -1524,6 +1663,15 @@ static int ltc2983_probe(struct spi_device *spi) return ret; } + if (st->info->has_eeprom) { + ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_WRITE_CMD, + LTC2983_EEPROM_WRITE_TIME_MS, + LTC2986_EEPROM_STATUS_REG, + LTC2983_EEPROM_STATUS_FAILURE_MASK); + if (ret) + return ret; + } + indio_dev->name = name; indio_dev->num_channels = st->iio_channels; indio_dev->channels = st->iio_chan; @@ -1554,14 +1702,35 @@ static int ltc2983_suspend(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(ltc2983_pm_ops, ltc2983_suspend, ltc2983_resume); +static const struct ltc2983_chip_info ltc2983_chip_info_data = { + .max_channels_nr = 20, +}; + +static const struct ltc2983_chip_info ltc2984_chip_info_data = { + .max_channels_nr = 20, + .has_eeprom = true, +}; + +static const struct ltc2983_chip_info ltc2986_chip_info_data = { + .max_channels_nr = 10, + .has_temp = true, + .has_eeprom = true, +}; + static const struct spi_device_id ltc2983_id_table[] = { - { "ltc2983" }, + { "ltc2983", (kernel_ulong_t)<c2983_chip_info_data }, + { "ltc2984", (kernel_ulong_t)<c2984_chip_info_data }, + { "ltc2986", (kernel_ulong_t)<c2986_chip_info_data }, + { "ltm2985", (kernel_ulong_t)<c2986_chip_info_data }, {}, }; MODULE_DEVICE_TABLE(spi, ltc2983_id_table); static const struct of_device_id ltc2983_of_match[] = { - { .compatible = "adi,ltc2983" }, + { .compatible = "adi,ltc2983", .data = <c2983_chip_info_data }, + { .compatible = "adi,ltc2984", .data = <c2984_chip_info_data }, + { .compatible = "adi,ltc2986", .data = <c2986_chip_info_data }, + { .compatible = "adi,ltm2985", .data = <c2986_chip_info_data }, {}, }; MODULE_DEVICE_TABLE(of, ltc2983_of_match); -- GitLab From bcf22afd2ce0b8bd4fad50bfda92e8cbbc483c72 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Nov 2022 12:51:07 +0000 Subject: [PATCH 0968/1480] iio: temperature: mlx90632: Add error handling for devm_pm_runtime_enable() This call can fail so handling is necessary even if it is very unlikely. Reported-by: coverity-bot Addresses-Coverity-ID: 1527134 ("Error handling issues") Fixes: 2aebc223fc7c ("iio: temperature: mlx90632 Add runtime powermanagement modes") Signed-off-by: Jonathan Cameron Acked-off-by: Crt Mori Link: https://lore.kernel.org/r/20221105125108.383193-2-jic23@kernel.org --- drivers/iio/temperature/mlx90632.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index a17fe5f4967a6..7572ae3f84322 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1267,7 +1267,10 @@ static int mlx90632_probe(struct i2c_client *client, pm_runtime_get_noresume(&client->dev); pm_runtime_set_active(&client->dev); - devm_pm_runtime_enable(&client->dev); + ret = devm_pm_runtime_enable(&client->dev); + if (ret) + return ret; + pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); pm_runtime_put_autosuspend(&client->dev); -- GitLab From 99043ba702243f69d1853bd8aeca01e22836ede3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Nov 2022 12:51:08 +0000 Subject: [PATCH 0969/1480] iio: temperature: mlx90632: Add missing static marking on devm_pm_ops Only used within this file, so should be marked static. Fixes: 2aebc223fc7c ("iio: temperature: mlx90632 Add runtime powermanagement modes") Signed-off-by: Jonathan Cameron Acked-off-by: Crt Mori Link: https://lore.kernel.org/r/20221105125108.383193-3-jic23@kernel.org --- drivers/iio/temperature/mlx90632.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 7572ae3f84322..f1f5ebc145b14 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1326,7 +1326,7 @@ static int mlx90632_pm_runtime_suspend(struct device *dev) return mlx90632_pwr_set_sleep_step(data->regmap); } -const struct dev_pm_ops mlx90632_pm_ops = { +static const struct dev_pm_ops mlx90632_pm_ops = { SYSTEM_SLEEP_PM_OPS(mlx90632_pm_suspend, mlx90632_pm_resume) RUNTIME_PM_OPS(mlx90632_pm_runtime_suspend, NULL, NULL) }; -- GitLab From c486b7019398a7a451631d5d99b67480768bfd25 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Sat, 5 Nov 2022 15:51:57 -0700 Subject: [PATCH 0970/1480] iio: proximity: sx9360: Add a new ACPI hardware ID From https://treexy.com/products/driver-fusion/database/sensors/semtech/sx9360-proximity/ sx9360 SAR sensor can be presented with ACPI ID SAMM0208. Whilst this does not appear to be an official ACPI ID, it is in the wild (perhaps due to a typo on the SAM PnP ID). Reported-by: Jordi Torres Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20221105225157.10081-1-gwendal@chromium.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9360.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/proximity/sx9360.c b/drivers/iio/proximity/sx9360.c index 7fa2213d23baf..6e19d22e6a015 100644 --- a/drivers/iio/proximity/sx9360.c +++ b/drivers/iio/proximity/sx9360.c @@ -865,6 +865,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(sx9360_pm_ops, sx9360_suspend, sx9360_resume); static const struct acpi_device_id sx9360_acpi_match[] = { { "STH9360", SX9360_WHOAMI_VALUE }, + { "SAMM0208", SX9360_WHOAMI_VALUE }, { } }; MODULE_DEVICE_TABLE(acpi, sx9360_acpi_match); -- GitLab From 46975081f75105de5a6bda05af90323a4894d2be Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 6 Nov 2022 15:36:53 +0100 Subject: [PATCH 0971/1480] iio: imu: st_lsm6dsx: add support to LSM6DSV16X Add support to STM LSM6DSV16X (accelerometer and gyroscope) Mems sensor. The LSM6DSV16X sensor can use LSM6DSV as fallback device since it implements all the LSM6DSV16X features currently implemented in st_lsm6dsx. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dsv16x.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/284b251f861dff30c399e5736a843c8e3a497249.1667745215.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 3 ++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 6 +++++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 +++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 +++++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 1c68bac94bcee..37d02e0fc227a 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,7 +13,8 @@ config IIO_ST_LSM6DSX sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx, - lsm6dsv, the accelerometer/gyroscope of lsm9ds1 and lsm6dst. + lsm6dsv, lsm6dsv16x, the accelerometer/gyroscope of lsm9ds1 + and lsm6dst. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index ab61895cf0720..683cfadcf62ef 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -34,6 +34,7 @@ #define ST_ASM330LHHX_DEV_NAME "asm330lhhx" #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" #define ST_LSM6DSV_DEV_NAME "lsm6dsv" +#define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -55,6 +56,7 @@ enum st_lsm6dsx_hw_id { ST_ASM330LHHX_ID, ST_LSM6DSTX_ID, ST_LSM6DSV_ID, + ST_LSM6DSV16X_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 5e716a5071fd4..acb6101aec5d9 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX: + * LSM6DSTX/LSM6DSV/LSM6DSV16X: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -1180,6 +1180,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .hw_id = ST_LSM6DSV_ID, .name = ST_LSM6DSV_DEV_NAME, .wai = 0x70, + }, { + .hw_id = ST_LSM6DSV16X_ID, + .name = ST_LSM6DSV16X_DEV_NAME, + .wai = 0x70, }, }, .channels = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 239c8920a31f8..0faf1b4c11afe 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -113,6 +113,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dsv", .data = (void *)ST_LSM6DSV_ID, }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -137,6 +141,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, + { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 66705ef16ed04..57597aaa2a92a 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -113,6 +113,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dsv", .data = (void *)ST_LSM6DSV_ID, }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -137,6 +141,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, + { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- GitLab From 03e8373c070daf14eed069783e3cf343470ca5cd Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 6 Nov 2022 15:36:54 +0100 Subject: [PATCH 0972/1480] dt-bindings: iio: imu: st_lsm6dsx: add lsm6dsv16x Add device bindings for lsm6dsv16x IMU sensor. Use lsm6dsv as fallback device for lsm6dsv16x since it implements all the features currently supported by lsm6dsv16x. Signed-off-by: Lorenzo Bianconi Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/8d10a63ec6abd22863ab25addd8c2f578dbc9cd9.1667745215.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index e7349a3275dda..5933270799f55 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -39,6 +39,9 @@ properties: - items: - const: st,lsm6dstx - const: st,lsm6dst + - items: + - const: st,lsm6dsv16x + - const: st,lsm6dsv reg: maxItems: 1 -- GitLab From 84aea36299a411f46d4372dc2d51c037ae70341a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 11 Nov 2022 15:28:46 -0600 Subject: [PATCH 0973/1480] dt-bindings: iio: dac: adi,ad5758: Drop 'contains' from 'adi,dc-dc-mode' 'contains' applies to arrays, but 'adi,dc-dc-mode' is a scalar. So drop 'contains' from the 'if' schema. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20221111212846.4104059-1-robh@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml index e49e7556175df..4e508bfcc9d87 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml @@ -102,8 +102,7 @@ allOf: - if: properties: adi,dc-dc-mode: - contains: - enum: [1, 3] + enum: [1, 3] then: properties: adi,range-microvolt: false -- GitLab From 6809ec97686f00b667468f7e8e582a6e3d50169b Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 8 Nov 2022 09:43:53 +0530 Subject: [PATCH 0974/1480] dt-bindings: iio: adc: rockchip-saradc: Add saradc for rv1126 Add saradc compatible string for rockchip rv1126. Cc: linux-iio@vger.kernel.org Cc: Jonathan Cameron Signed-off-by: Jagan Teki Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221108041400.157052-4-jagan@edgeble.ai Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml index e512a14e41b43..da50b529c1576 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml @@ -22,6 +22,7 @@ properties: - rockchip,rk3328-saradc - rockchip,rk3568-saradc - rockchip,rv1108-saradc + - rockchip,rv1126-saradc - const: rockchip,rk3399-saradc reg: -- GitLab From c896b9f0920fdcb9a815014ca1917522ba2c9b9a Mon Sep 17 00:00:00 2001 From: Jay Greco Date: Thu, 10 Nov 2022 19:29:32 +0000 Subject: [PATCH 0975/1480] iio: imu: inv_icm42600: Add support for icm42631 Add the required WHOAMI and device_id definitions to support the icm42631. Signed-off-by: Jay Greco Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20221110192933.13616-2-grecojay@amazon.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 ++ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 5 +++++ drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 +++ drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 +++ 4 files changed, 13 insertions(+) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 3d91469beccbb..0e290c807b0f9 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -22,6 +22,7 @@ enum inv_icm42600_chip { INV_CHIP_ICM42602, INV_CHIP_ICM42605, INV_CHIP_ICM42622, + INV_CHIP_ICM42631, INV_CHIP_NB, }; @@ -303,6 +304,7 @@ struct inv_icm42600_state { #define INV_ICM42600_WHOAMI_ICM42602 0x41 #define INV_ICM42600_WHOAMI_ICM42605 0x42 #define INV_ICM42600_WHOAMI_ICM42622 0x46 +#define INV_ICM42600_WHOAMI_ICM42631 0x5C /* User bank 1 (MSB 0x10) */ #define INV_ICM42600_REG_SENSOR_CONFIG0 0x1003 diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index b63c5dab1a562..7b3a2a0dc2cb0 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -87,6 +87,11 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = { .name = "icm42622", .conf = &inv_icm42600_default_conf, }, + [INV_CHIP_ICM42631] = { + .whoami = INV_ICM42600_WHOAMI_ICM42631, + .name = "icm42631", + .conf = &inv_icm42600_default_conf, + }, }; const struct iio_mount_matrix * diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index 4f96989ddf4a1..eb2681ad375f2 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -84,6 +84,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = { }, { .compatible = "invensense,icm42622", .data = (void *)INV_CHIP_ICM42622, + }, { + .compatible = "invensense,icm42631", + .data = (void *)INV_CHIP_ICM42631, }, {} }; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index 486b46e531131..6be4ac7949379 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -80,6 +80,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = { }, { .compatible = "invensense,icm42622", .data = (void *)INV_CHIP_ICM42622, + }, { + .compatible = "invensense,icm42631", + .data = (void *)INV_CHIP_ICM42631, }, {} }; -- GitLab From 7b4452381a966de33707718aa8d79672cc8caa2f Mon Sep 17 00:00:00 2001 From: Jay Greco Date: Thu, 10 Nov 2022 19:29:33 +0000 Subject: [PATCH 0976/1480] dt-bindings: iio: imu: Add inv_icm42600 documentation Update the required documentation for the icm42631. Signed-off-by: Jay Greco Acked-by: Krzysztof Kozlowski Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20221110192933.13616-3-grecojay@amazon.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml index 488349755c99d..13c9abdd31314 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml @@ -31,6 +31,7 @@ properties: - invensense,icm42602 - invensense,icm42605 - invensense,icm42622 + - invensense,icm42631 reg: maxItems: 1 -- GitLab From 5ae34494cf37ae6383f4bd674f343ef20833024d Mon Sep 17 00:00:00 2001 From: Subhajit Ghosh Date: Thu, 10 Nov 2022 18:12:41 +0800 Subject: [PATCH 0977/1480] iio: light: apds9960: Fix iio_event_spec structures There is only one interrupt enable option for both ALS low and high thresholds, and one for both Proximity low and high thresholds. Signed-off-by: Subhajit Ghosh Reviewed-by: Matt Ranostay Link: https://lore.kernel.org/r/20221110101241.10576-1-subhajit.ghosh@vixtechnology.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9960.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index b62c139baf414..997aa01ecc115 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -223,14 +223,16 @@ static const struct iio_event_spec apds9960_pxs_event_spec[] = { { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_RISING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), }, { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_FALLING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), }, }; @@ -238,14 +240,16 @@ static const struct iio_event_spec apds9960_als_event_spec[] = { { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_RISING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), }, { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_FALLING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), }, }; -- GitLab From 572cc583c92e7b113a0d0f650b02d80505920eef Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Sun, 13 Nov 2022 10:58:20 +0530 Subject: [PATCH 0978/1480] staging: iio: meter: replace ternary operator by if condition Replace ternary operator by simple if based evaluation of the return value. Issue identified using coccicheck. Signed-off-by: Deepak R Varma Link: https://lore.kernel.org/r/Y3CAdCa17WdWDYUa@qemulion Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7854-i2c.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index a9a06e8dda51f..71b67dd3c8e98 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -61,7 +61,10 @@ static int ade7854_i2c_write_reg(struct device *dev, unlock: mutex_unlock(&st->buf_lock); - return ret < 0 ? ret : 0; + if (ret < 0) + return ret; + + return 0; } static int ade7854_i2c_read_reg(struct device *dev, -- GitLab From 10c4539d1d5581646997d7f9b430319bcb9245b1 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Mon, 14 Nov 2022 15:36:49 +0200 Subject: [PATCH 0979/1480] iio: adc: ad4130: depend on GPIOLIB Fixes undefined references to 'gpiochip_get_data' and 'devm_gpiochip_add_data_with_key'. Signed-off-by: Cosmin Tanislav Reported-by: kernel test robot Fixes: 62094060cf3a ("iio: adc: ad4130: add AD4130 driver") Link: https://lore.kernel.org/r/20221114133649.1737027-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8d719fbb6acc0..63f80d747cbd2 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -24,6 +24,7 @@ config AD_SIGMA_DELTA config AD4130 tristate "Analog Device AD4130 ADC Driver" depends on SPI + depends on GPIOLIB select IIO_BUFFER select IIO_KFIFO_BUF select REGMAP_SPI -- GitLab From d94fbd9231a2b4062cf5972629999402ea7dd6fa Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 14 Nov 2022 10:25:34 +0100 Subject: [PATCH 0980/1480] iio: imu: st_lsm6dsx: fix LSM6DSV sensor description Fix sensor ODR description for LSM6DSV/LSM6DSVX Fixes: a1c6d631ff12 ("iio: imu: st_lsm6dsx: add support to LSM6DSV") Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/653e14bf79bb88d8581d2bc42da2f784caaf3776.1668417770.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index acb6101aec5d9..b680682f98330 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,13 +27,20 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX/LSM6DSV/LSM6DSV16X: + * LSM6DSTX: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 * - FIFO size: 3KB * + * - LSM6DSV/LSM6DSV16X: + * - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240, + * 480, 960 + * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 + * - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000 + * - FIFO size: 3KB + * * - LSM9DS1/LSM6DS0: * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 -- GitLab From 2c5c45e236c4706a261042f67766b0486c72d603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:23 +0100 Subject: [PATCH 0981/1480] iio: accel: adxl372_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-50-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl372_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index 4efb70a5fe405..e5f310ea65fff 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -18,9 +18,9 @@ static const struct regmap_config adxl372_regmap_config = { .readable_noinc_reg = adxl372_readable_noinc_reg, }; -static int adxl372_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adxl372_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; unsigned int regval; int ret; @@ -58,7 +58,7 @@ static struct i2c_driver adxl372_i2c_driver = { .name = "adxl372_i2c", .of_match_table = adxl372_of_match, }, - .probe = adxl372_i2c_probe, + .probe_new = adxl372_i2c_probe, .id_table = adxl372_i2c_id, }; -- GitLab From c476246bd5abb1f6d40054d83fea3f1a407ccb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:24 +0100 Subject: [PATCH 0982/1480] iio: accel: bma180: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-51-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma180.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index d03fc3400f94e..eb697eeb4301b 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -921,9 +921,9 @@ static const struct iio_trigger_ops bma180_trigger_ops = { .reenable = bma180_trig_reen, }; -static int bma180_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bma180_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct bma180_data *data; struct iio_dev *indio_dev; @@ -1134,7 +1134,7 @@ static struct i2c_driver bma180_driver = { .pm = pm_sleep_ptr(&bma180_pm_ops), .of_match_table = bma180_of_match, }, - .probe = bma180_probe, + .probe_new = bma180_probe, .remove = bma180_remove, .id_table = bma180_ids, }; -- GitLab From e599500f96fb51417320b8b51ae4c36868672b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:25 +0100 Subject: [PATCH 0983/1480] iio: accel: bma400: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-52-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma400_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index 1ba2a982ea736..688b06dae669b 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -13,9 +13,9 @@ #include "bma400.h" -static int bma400_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bma400_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; regmap = devm_regmap_init_i2c(client, &bma400_regmap_config); @@ -44,7 +44,7 @@ static struct i2c_driver bma400_i2c_driver = { .name = "bma400", .of_match_table = bma400_of_i2c_match, }, - .probe = bma400_i2c_probe, + .probe_new = bma400_i2c_probe, .id_table = bma400_i2c_ids, }; -- GitLab From a141d225f6d62809d2b6a6c916929a8bbaaaaad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:26 +0100 Subject: [PATCH 0984/1480] iio: accel: bmc150: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-53-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c index be8cc598b88e3..509cab2bd6947 100644 --- a/drivers/iio/accel/bmc150-accel-i2c.c +++ b/drivers/iio/accel/bmc150-accel-i2c.c @@ -171,9 +171,9 @@ static void bmc150_acpi_dual_accel_probe(struct i2c_client *client) {} static void bmc150_acpi_dual_accel_remove(struct i2c_client *client) {} #endif -static int bmc150_accel_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmc150_accel_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; enum bmc150_type type = BOSCH_UNKNOWN; @@ -269,7 +269,7 @@ static struct i2c_driver bmc150_accel_driver = { .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match), .pm = &bmc150_accel_pm_ops, }, - .probe = bmc150_accel_probe, + .probe_new = bmc150_accel_probe, .remove = bmc150_accel_remove, .id_table = bmc150_accel_id, }; -- GitLab From a8fab44897dd959c01a88a806fd4252a29c62055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:27 +0100 Subject: [PATCH 0985/1480] iio: accel: da280: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-54-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da280.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c index 04e9c56789647..38a7d811610e7 100644 --- a/drivers/iio/accel/da280.c +++ b/drivers/iio/accel/da280.c @@ -105,9 +105,9 @@ static void da280_disable(void *client) da280_enable(client, false); } -static int da280_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int da280_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct iio_dev *indio_dev; struct da280_data *data; @@ -184,7 +184,7 @@ static struct i2c_driver da280_driver = { .acpi_match_table = ACPI_PTR(da280_acpi_match), .pm = pm_sleep_ptr(&da280_pm_ops), }, - .probe = da280_probe, + .probe_new = da280_probe, .id_table = da280_i2c_id, }; -- GitLab From 09cec0835243b17316995bce30532f5ad51db355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:28 +0100 Subject: [PATCH 0986/1480] iio: accel: kxcjk-1013: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-55-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index e626b6fa8a36a..98da4bda22dfe 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1424,9 +1424,9 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, return dev_name(dev); } -static int kxcjk1013_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int kxcjk1013_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); static const char * const regulator_names[] = { "vdd", "vddio" }; struct kxcjk1013_data *data; struct iio_dev *indio_dev; @@ -1732,7 +1732,7 @@ static struct i2c_driver kxcjk1013_driver = { .of_match_table = kxcjk1013_of_match, .pm = &kxcjk1013_pm_ops, }, - .probe = kxcjk1013_probe, + .probe_new = kxcjk1013_probe, .remove = kxcjk1013_remove, .id_table = kxcjk1013_id, }; -- GitLab From 17b9a72f4a11c64a12d7cd4a7951ba44c5f2f374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:29 +0100 Subject: [PATCH 0987/1480] iio: accel: mma7455_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-56-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma7455_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c index c63b321b01cda..a3864dbe27613 100644 --- a/drivers/iio/accel/mma7455_i2c.c +++ b/drivers/iio/accel/mma7455_i2c.c @@ -10,9 +10,9 @@ #include "mma7455.h" -static int mma7455_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int mma7455_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct regmap *regmap; const char *name = NULL; @@ -46,7 +46,7 @@ static const struct of_device_id mma7455_of_match[] = { MODULE_DEVICE_TABLE(of, mma7455_of_match); static struct i2c_driver mma7455_i2c_driver = { - .probe = mma7455_i2c_probe, + .probe_new = mma7455_i2c_probe, .remove = mma7455_i2c_remove, .id_table = mma7455_i2c_ids, .driver = { -- GitLab From 12491d35551df69709777bd7769e1e33641943cc Mon Sep 17 00:00:00 2001 From: Angel Iglesias Date: Sun, 13 Nov 2022 18:54:46 +0100 Subject: [PATCH 0988/1480] iio: pressure: bmp280: convert to i2c's .probe_new() Use i2c_client_get_device_id() to get the i2c_device_id* parameter in the .new_probe() callback. Signed-off-by: Angel Iglesias Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/5dcaa389ea2ffe7050091b07a3bc4b0c1c9d586b.1668361368.git.ang.iglesiasg@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c index 0c27211f3ea07..14eab086d24a6 100644 --- a/drivers/iio/pressure/bmp280-i2c.c +++ b/drivers/iio/pressure/bmp280-i2c.c @@ -5,11 +5,11 @@ #include "bmp280.h" -static int bmp280_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmp280_i2c_probe(struct i2c_client *client) { struct regmap *regmap; const struct regmap_config *regmap_config; + const struct i2c_device_id *id = i2c_client_get_device_id(client); switch (id->driver_data) { case BMP180_CHIP_ID: @@ -65,7 +65,7 @@ static struct i2c_driver bmp280_i2c_driver = { .of_match_table = bmp280_of_i2c_match, .pm = pm_ptr(&bmp280_dev_pm_ops), }, - .probe = bmp280_i2c_probe, + .probe_new = bmp280_i2c_probe, .id_table = bmp280_i2c_id, }; module_i2c_driver(bmp280_i2c_driver); -- GitLab From 226d6dbac88336f37b1fae76aabe6fa610e9b872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:30 +0100 Subject: [PATCH 0989/1480] iio: accel: mma8452: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-57-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 3ba28c2ff68a3..f97fb68e3a711 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1545,9 +1545,9 @@ static const struct of_device_id mma8452_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mma8452_dt_ids); -static int mma8452_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma8452_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma8452_data *data; struct iio_dev *indio_dev; int ret; @@ -1846,7 +1846,7 @@ static struct i2c_driver mma8452_driver = { .of_match_table = mma8452_dt_ids, .pm = &mma8452_pm_ops, }, - .probe = mma8452_probe, + .probe_new = mma8452_probe, .remove = mma8452_remove, .id_table = mma8452_id, }; -- GitLab From 6dae5d11e29d2935e7995d05468d72660dde5f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:31 +0100 Subject: [PATCH 0990/1480] iio: accel: mma9551: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-58-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9551.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index f7a793f4a8e34..aa4f5842859ef 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -446,9 +446,9 @@ static const char *mma9551_match_acpi_device(struct device *dev) return dev_name(dev); } -static int mma9551_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma9551_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma9551_data *data; struct iio_dev *indio_dev; const char *name = NULL; @@ -607,7 +607,7 @@ static struct i2c_driver mma9551_driver = { .acpi_match_table = ACPI_PTR(mma9551_acpi_match), .pm = pm_ptr(&mma9551_pm_ops), }, - .probe = mma9551_probe, + .probe_new = mma9551_probe, .remove = mma9551_remove, .id_table = mma9551_id, }; -- GitLab From 50434e4605d66a55e7422cb24804c88b57cfb2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:32 +0100 Subject: [PATCH 0991/1480] iio: accel: mma9553: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-59-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 2da0e005b13eb..0af578ef9d3d0 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1073,9 +1073,9 @@ static const char *mma9553_match_acpi_device(struct device *dev) return dev_name(dev); } -static int mma9553_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma9553_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma9553_data *data; struct iio_dev *indio_dev; const char *name = NULL; @@ -1246,7 +1246,7 @@ static struct i2c_driver mma9553_driver = { .acpi_match_table = ACPI_PTR(mma9553_acpi_match), .pm = pm_ptr(&mma9553_pm_ops), }, - .probe = mma9553_probe, + .probe_new = mma9553_probe, .remove = mma9553_remove, .id_table = mma9553_id, }; -- GitLab From fe44f0738dd142a173e1b62e13b59d134abca003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:33 +0100 Subject: [PATCH 0992/1480] iio: adc: ad7091r5: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-60-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7091r5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index 47f5763023a40..7d6709da1005f 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -69,9 +69,9 @@ static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { .vref_mV = 2500, }; -static int ad7091r5_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad7091r5_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); const struct ad7091r_chip_info *chip_info; struct regmap *map = devm_regmap_init_i2c(i2c, &ad7091r_regmap_config); @@ -103,7 +103,7 @@ static struct i2c_driver ad7091r5_driver = { .name = "ad7091r5", .of_match_table = ad7091r5_dt_ids, }, - .probe = ad7091r5_i2c_probe, + .probe_new = ad7091r5_i2c_probe, .id_table = ad7091r5_i2c_ids, }; module_i2c_driver(ad7091r5_driver); -- GitLab From 3ff5dd78f6b7e5aa73ddbc8f609f5ba53d1d49bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:34 +0100 Subject: [PATCH 0993/1480] iio: adc: ad7291: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-61-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7291.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index e9129dac762fe..3dd0105f63d71 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -465,9 +465,9 @@ static void ad7291_reg_disable(void *reg) regulator_disable(reg); } -static int ad7291_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7291_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ad7291_chip_info *chip; struct iio_dev *indio_dev; int ret; @@ -553,7 +553,7 @@ static struct i2c_driver ad7291_driver = { .name = KBUILD_MODNAME, .of_match_table = ad7291_of_match, }, - .probe = ad7291_probe, + .probe_new = ad7291_probe, .id_table = ad7291_id, }; module_i2c_driver(ad7291_driver); -- GitLab From 28ae41885ab2bec935a61a9c811713df6e70043e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:35 +0100 Subject: [PATCH 0994/1480] iio: adc: ad799x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-62-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad799x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 4730d8d0f4c3f..8f0a3a35e727e 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -775,9 +775,9 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { }, }; -static int ad799x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad799x_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; int extra_config = 0; struct ad799x_state *st; @@ -968,7 +968,7 @@ static struct i2c_driver ad799x_driver = { .name = "ad799x", .pm = pm_sleep_ptr(&ad799x_pm_ops), }, - .probe = ad799x_probe, + .probe_new = ad799x_probe, .remove = ad799x_remove, .id_table = ad799x_id, }; -- GitLab From 203a5e83dd3f7ea4d0d827563a317bd656d2f579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:36 +0100 Subject: [PATCH 0995/1480] iio: adc: ina2xx-adc: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-63-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 910e7e965fc48..38d9d7b2313ea 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -946,9 +946,9 @@ static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config) return ina2xx_set_calibration(chip); } -static int ina2xx_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ina2xx_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ina2xx_chip_info *chip; struct iio_dev *indio_dev; unsigned int val; @@ -1090,7 +1090,7 @@ static struct i2c_driver ina2xx_driver = { .name = KBUILD_MODNAME, .of_match_table = ina2xx_of_match, }, - .probe = ina2xx_probe, + .probe_new = ina2xx_probe, .remove = ina2xx_remove, .id_table = ina2xx_id, }; -- GitLab From 7b8c4fa43583ea1a7e60658ad23302608fe19ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:37 +0100 Subject: [PATCH 0996/1480] iio: adc: ltc2471: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-64-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2471.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ltc2471.c b/drivers/iio/adc/ltc2471.c index 0e0fe881a8e69..eeb2945829eb2 100644 --- a/drivers/iio/adc/ltc2471.c +++ b/drivers/iio/adc/ltc2471.c @@ -99,9 +99,9 @@ static const struct iio_info ltc2471_info = { .read_raw = ltc2471_read_raw, }; -static int ltc2471_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2471_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ltc2471_data *data; int ret; @@ -146,7 +146,7 @@ static struct i2c_driver ltc2471_i2c_driver = { .driver = { .name = "ltc2471", }, - .probe = ltc2471_i2c_probe, + .probe_new = ltc2471_i2c_probe, .id_table = ltc2471_i2c_id, }; -- GitLab From 11e67cc9675f1289556e1524fa7717cc95282487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:38 +0100 Subject: [PATCH 0997/1480] iio: adc: ltc2485: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-65-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2485.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c index 37c762f8218c9..6a23427344ecd 100644 --- a/drivers/iio/adc/ltc2485.c +++ b/drivers/iio/adc/ltc2485.c @@ -89,9 +89,9 @@ static const struct iio_info ltc2485_info = { .read_raw = ltc2485_read_raw, }; -static int ltc2485_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2485_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ltc2485_data *data; int ret; @@ -133,7 +133,7 @@ static struct i2c_driver ltc2485_driver = { .driver = { .name = "ltc2485", }, - .probe = ltc2485_probe, + .probe_new = ltc2485_probe, .id_table = ltc2485_id, }; module_i2c_driver(ltc2485_driver); -- GitLab From 3a79844428c39fa54a30ec11eaad5a8e577ef706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:39 +0100 Subject: [PATCH 0998/1480] iio: adc: ltc2497: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-66-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2497.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 556f10dfb5023..17370c5eb6fe3 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -94,9 +94,9 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata, return ret; } -static int ltc2497_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2497_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ltc2497_chip_info *chip_info; struct iio_dev *indio_dev; struct ltc2497_driverdata *st; @@ -165,7 +165,7 @@ static struct i2c_driver ltc2497_driver = { .name = "ltc2497", .of_match_table = ltc2497_of_match, }, - .probe = ltc2497_probe, + .probe_new = ltc2497_probe, .remove = ltc2497_remove, .id_table = ltc2497_id, }; -- GitLab From a69e45a411ea3ae0bbec474e4303c4281f3f8376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:40 +0100 Subject: [PATCH 0999/1480] iio: adc: max1363: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-67-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 42d3479cefb73..73b783b430d72 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1579,9 +1579,9 @@ static void max1363_reg_disable(void *reg) regulator_disable(reg); } -static int max1363_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max1363_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct max1363_state *st; struct iio_dev *indio_dev; @@ -1718,7 +1718,7 @@ static struct i2c_driver max1363_driver = { .name = "max1363", .of_match_table = max1363_of_match, }, - .probe = max1363_probe, + .probe_new = max1363_probe, .id_table = max1363_id, }; module_i2c_driver(max1363_driver); -- GitLab From d59ecbc48a1c74cfe6bc2d4ff503fb3e7455d19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:41 +0100 Subject: [PATCH 1000/1480] iio: adc: max9611: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Acked-by: Jacopo Mondi Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-68-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max9611.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index f982f00303dc0..cb7f4785423a2 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -510,8 +510,7 @@ static const struct of_device_id max9611_of_table[] = { }; MODULE_DEVICE_TABLE(of, max9611_of_table); -static int max9611_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9611_probe(struct i2c_client *client) { const char * const shunt_res_prop = "shunt-resistor-micro-ohms"; struct max9611_dev *max9611; @@ -557,7 +556,7 @@ static struct i2c_driver max9611_driver = { .name = DRIVER_NAME, .of_match_table = max9611_of_table, }, - .probe = max9611_probe, + .probe_new = max9611_probe, }; module_i2c_driver(max9611_driver); -- GitLab From 6168215dbfea1c1d42a7aff145efbbcbdb5d6051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:42 +0100 Subject: [PATCH 1001/1480] iio: adc: mcp3422: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-69-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3422.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index da353dcb1e9d4..ada844c3f7ecc 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -330,9 +330,9 @@ static const struct iio_info mcp3422_info = { .attrs = &mcp3422_attribute_group, }; -static int mcp3422_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mcp3422_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mcp3422 *adc; int err; @@ -417,7 +417,7 @@ static struct i2c_driver mcp3422_driver = { .name = "mcp3422", .of_match_table = mcp3422_of_match, }, - .probe = mcp3422_probe, + .probe_new = mcp3422_probe, .id_table = mcp3422_id, }; module_i2c_driver(mcp3422_driver); -- GitLab From 4b50867f6a328c13d40223937c34b4146eafd883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:43 +0100 Subject: [PATCH 1002/1480] iio: adc: ti-adc081c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-70-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-adc081c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index bd48b073e7200..c663dc59d4590 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -152,9 +152,9 @@ static void adc081c_reg_disable(void *reg) regulator_disable(reg); } -static int adc081c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adc081c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *iio; struct adc081c *adc; const struct adcxx1c_model *model; @@ -235,7 +235,7 @@ static struct i2c_driver adc081c_driver = { .of_match_table = adc081c_of_match, .acpi_match_table = adc081c_acpi_match, }, - .probe = adc081c_probe, + .probe_new = adc081c_probe, .id_table = adc081c_id, }; module_i2c_driver(adc081c_driver); -- GitLab From 0143ce1039f70e2656865d75c163ed4dbf40db30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:44 +0100 Subject: [PATCH 1003/1480] iio: adc: ti-ads1015: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-71-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads1015.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 8bceba6940260..56af5e1488022 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -974,9 +974,9 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode) mode << ADS1015_CFG_MOD_SHIFT); } -static int ads1015_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ads1015_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ads1015_chip_data *chip; struct iio_dev *indio_dev; struct ads1015_data *data; @@ -1195,7 +1195,7 @@ static struct i2c_driver ads1015_driver = { .of_match_table = ads1015_of_match, .pm = &ads1015_pm_ops, }, - .probe = ads1015_probe, + .probe_new = ads1015_probe, .remove = ads1015_remove, .id_table = ads1015_id, }; -- GitLab From 7558eaa9727dbf2efd41d29101d1639975cf778e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:45 +0100 Subject: [PATCH 1004/1480] iio: cdc: ad7150: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-72-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/cdc/ad7150.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c index 1113745890cae..79aeb0aaea67d 100644 --- a/drivers/iio/cdc/ad7150.c +++ b/drivers/iio/cdc/ad7150.c @@ -536,9 +536,9 @@ static const struct iio_info ad7150_info_no_irq = { .read_raw = &ad7150_read_raw, }; -static int ad7150_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7150_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ad7150_chip_info *chip; struct iio_dev *indio_dev; int ret; @@ -647,7 +647,7 @@ static struct i2c_driver ad7150_driver = { .name = "ad7150", .of_match_table = ad7150_of_match, }, - .probe = ad7150_probe, + .probe_new = ad7150_probe, .id_table = ad7150_id, }; module_i2c_driver(ad7150_driver); -- GitLab From 9b1cd21eafc34beb50194a060e1cd3902b763a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:46 +0100 Subject: [PATCH 1005/1480] iio: cdc: ad7746: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-73-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/cdc/ad7746.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/cdc/ad7746.c b/drivers/iio/cdc/ad7746.c index b266f53281409..6f68651ce1d5a 100644 --- a/drivers/iio/cdc/ad7746.c +++ b/drivers/iio/cdc/ad7746.c @@ -717,9 +717,9 @@ static const struct iio_info ad7746_info = { .write_raw = ad7746_write_raw, }; -static int ad7746_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7746_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct ad7746_chip_info *chip; struct iio_dev *indio_dev; @@ -810,7 +810,7 @@ static struct i2c_driver ad7746_driver = { .name = KBUILD_MODNAME, .of_match_table = ad7746_of_match, }, - .probe = ad7746_probe, + .probe_new = ad7746_probe, .id_table = ad7746_id, }; module_i2c_driver(ad7746_driver); -- GitLab From 89d63224e20c8409afb553d334d38bb2675757ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:47 +0100 Subject: [PATCH 1006/1480] iio: chemical: ams-iaq-core: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-74-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/ams-iaq-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 97be3669c5543..0a0fbcdd44692 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -135,8 +135,7 @@ static const struct iio_info ams_iaqcore_info = { .read_raw = ams_iaqcore_read_raw, }; -static int ams_iaqcore_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ams_iaqcore_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct ams_iaqcore_data *data; @@ -180,7 +179,7 @@ static struct i2c_driver ams_iaqcore_driver = { .name = "ams-iaq-core", .of_match_table = ams_iaqcore_dt_ids, }, - .probe = ams_iaqcore_probe, + .probe_new = ams_iaqcore_probe, .id_table = ams_iaqcore_id, }; module_i2c_driver(ams_iaqcore_driver); -- GitLab From e9c812ca569f1314f0a9c0420cb17c9db0a55457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:48 +0100 Subject: [PATCH 1007/1480] iio: chemical: atlas-ezo-sensor: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-75-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-ezo-sensor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c index bbcf5a59c1f4e..307c3488f4bdd 100644 --- a/drivers/iio/chemical/atlas-ezo-sensor.c +++ b/drivers/iio/chemical/atlas-ezo-sensor.c @@ -201,9 +201,9 @@ static const struct of_device_id atlas_ezo_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); -static int atlas_ezo_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int atlas_ezo_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct atlas_ezo_device *chip; struct atlas_ezo_data *data; struct iio_dev *indio_dev; @@ -238,7 +238,7 @@ static struct i2c_driver atlas_ezo_driver = { .name = ATLAS_EZO_DRV_NAME, .of_match_table = atlas_ezo_dt_ids, }, - .probe = atlas_ezo_probe, + .probe_new = atlas_ezo_probe, .id_table = atlas_ezo_id, }; module_i2c_driver(atlas_ezo_driver); -- GitLab From 50c359245069f7e64880fe01b06d40954df71d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:49 +0100 Subject: [PATCH 1008/1480] iio: chemical: atlas-sensor: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-76-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-sensor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 7cac77a931c70..024657bc59e17 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -608,9 +608,9 @@ static const struct of_device_id atlas_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atlas_dt_ids); -static int atlas_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int atlas_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct atlas_data *data; struct atlas_device *chip; struct iio_trigger *trig; @@ -767,7 +767,7 @@ static struct i2c_driver atlas_driver = { .of_match_table = atlas_dt_ids, .pm = pm_ptr(&atlas_pm_ops), }, - .probe = atlas_probe, + .probe_new = atlas_probe, .remove = atlas_remove, .id_table = atlas_id, }; -- GitLab From 5aa377658458cb7c4ea20dab7405b795a5cc8a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:50 +0100 Subject: [PATCH 1009/1480] iio: chemical: bme680_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-77-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/bme680_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c index 20f2c20b6b022..61b12079858d2 100644 --- a/drivers/iio/chemical/bme680_i2c.c +++ b/drivers/iio/chemical/bme680_i2c.c @@ -17,9 +17,9 @@ #include "bme680.h" -static int bme680_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bme680_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; @@ -52,7 +52,7 @@ static struct i2c_driver bme680_i2c_driver = { .name = "bme680_i2c", .of_match_table = bme680_of_i2c_match, }, - .probe = bme680_i2c_probe, + .probe_new = bme680_i2c_probe, .id_table = bme680_i2c_id, }; module_i2c_driver(bme680_i2c_driver); -- GitLab From 684e57366e68e4ba2abc5ab56041b4d6534f28ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:51 +0100 Subject: [PATCH 1010/1480] iio: chemical: ccs811: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-78-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/ccs811.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index ba4045e203035..6ead80c089240 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -401,9 +401,9 @@ static int ccs811_reset(struct i2c_client *client) return 0; } -static int ccs811_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ccs811_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ccs811_data *data; int ret; @@ -567,7 +567,7 @@ static struct i2c_driver ccs811_driver = { .name = "ccs811", .of_match_table = ccs811_dt_ids, }, - .probe = ccs811_probe, + .probe_new = ccs811_probe, .remove = ccs811_remove, .id_table = ccs811_id, }; -- GitLab From 2f2adc666335cad150b720a6b19cec33464e2680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:52 +0100 Subject: [PATCH 1011/1480] iio: chemical: scd4x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-79-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/scd4x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c index 54066532ea458..f7ed9455b3c8f 100644 --- a/drivers/iio/chemical/scd4x.c +++ b/drivers/iio/chemical/scd4x.c @@ -615,7 +615,7 @@ out: return IRQ_HANDLED; } -static int scd4x_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int scd4x_probe(struct i2c_client *client) { static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 }; struct device *dev = &client->dev; @@ -690,7 +690,7 @@ static struct i2c_driver scd4x_i2c_driver = { .of_match_table = scd4x_dt_ids, .pm = pm_sleep_ptr(&scd4x_pm_ops), }, - .probe = scd4x_probe, + .probe_new = scd4x_probe, }; module_i2c_driver(scd4x_i2c_driver); -- GitLab From 67eba68bfccbdf6598200d70f80971e454d1ee2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:53 +0100 Subject: [PATCH 1012/1480] iio: chemical: sgp30: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-80-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/sgp30.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/sgp30.c b/drivers/iio/chemical/sgp30.c index e2c13c78c7e05..9d0c68485b63f 100644 --- a/drivers/iio/chemical/sgp30.c +++ b/drivers/iio/chemical/sgp30.c @@ -496,9 +496,9 @@ static const struct of_device_id sgp_dt_ids[] = { { } }; -static int sgp_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgp_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp_data *data; @@ -575,7 +575,7 @@ static struct i2c_driver sgp_driver = { .name = "sgp30", .of_match_table = sgp_dt_ids, }, - .probe = sgp_probe, + .probe_new = sgp_probe, .remove = sgp_remove, .id_table = sgp_id, }; -- GitLab From 07eda54d92f7ae7439a77903b9a43bfe563ebf21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:54 +0100 Subject: [PATCH 1013/1480] iio: chemical: sgp40: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-81-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/sgp40.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/sgp40.c b/drivers/iio/chemical/sgp40.c index 8a56394cea4eb..c0ea013009081 100644 --- a/drivers/iio/chemical/sgp40.c +++ b/drivers/iio/chemical/sgp40.c @@ -311,9 +311,9 @@ static const struct iio_info sgp40_info = { .write_raw = sgp40_write_raw, }; -static int sgp40_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgp40_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp40_data *data; @@ -368,7 +368,7 @@ static struct i2c_driver sgp40_driver = { .name = "sgp40", .of_match_table = sgp40_dt_ids, }, - .probe = sgp40_probe, + .probe_new = sgp40_probe, .id_table = sgp40_id, }; module_i2c_driver(sgp40_driver); -- GitLab From 0d8535ee52f0392f6293e564e3ff4522d6c37cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:55 +0100 Subject: [PATCH 1014/1480] iio: chemical: vz89x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-82-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/vz89x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index e7e1c74a351ef..d4604f7ccd1e0 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -348,9 +348,9 @@ static const struct of_device_id vz89x_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, vz89x_dt_ids); -static int vz89x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vz89x_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct vz89x_data *data; @@ -402,7 +402,7 @@ static struct i2c_driver vz89x_driver = { .name = "vz89x", .of_match_table = vz89x_dt_ids, }, - .probe = vz89x_probe, + .probe_new = vz89x_probe, .id_table = vz89x_id, }; module_i2c_driver(vz89x_driver); -- GitLab From 16fb97c4aacf5db311f4fb54745f852d1183e662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:56 +0100 Subject: [PATCH 1015/1480] iio: dac: ad5064: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-83-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5064.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 4447b88118270..f01249c1ba93c 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -993,9 +993,9 @@ static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd, return 0; } -static int ad5064_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5064_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5064_probe(&i2c->dev, id->driver_data, id->name, ad5064_i2c_write); } @@ -1056,7 +1056,7 @@ static struct i2c_driver ad5064_i2c_driver = { .driver = { .name = "ad5064", }, - .probe = ad5064_i2c_probe, + .probe_new = ad5064_i2c_probe, .id_table = ad5064_i2c_ids, }; -- GitLab From 4b2b4370a8459982d78d5716361a7a51089fecbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:57 +0100 Subject: [PATCH 1016/1480] iio: dac: ad5380: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-84-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5380.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index a81bfa47a221a..64b4519f8f5e6 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -546,9 +546,9 @@ static inline void ad5380_spi_unregister_driver(void) #if IS_ENABLED(CONFIG_I2C) -static int ad5380_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5380_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct regmap *regmap; regmap = devm_regmap_init_i2c(i2c, &ad5380_regmap_config); @@ -589,7 +589,7 @@ static struct i2c_driver ad5380_i2c_driver = { .driver = { .name = "ad5380", }, - .probe = ad5380_i2c_probe, + .probe_new = ad5380_i2c_probe, .remove = ad5380_i2c_remove, .id_table = ad5380_i2c_ids, }; -- GitLab From 94e5ddbaac1ea9b5bda64af53d8a57b19be890ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:58 +0100 Subject: [PATCH 1017/1480] iio: dac: ad5446: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-85-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5446.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 7324065d37821..aa3130b334563 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -568,9 +568,9 @@ static const struct ad5446_chip_info ad5446_i2c_chip_info[] = { }, }; -static int ad5446_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5446_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5446_probe(&i2c->dev, id->name, &ad5446_i2c_chip_info[id->driver_data]); } @@ -595,7 +595,7 @@ static struct i2c_driver ad5446_i2c_driver = { .driver = { .name = "ad5446", }, - .probe = ad5446_i2c_probe, + .probe_new = ad5446_i2c_probe, .remove = ad5446_i2c_remove, .id_table = ad5446_i2c_ids, }; -- GitLab From a17c748115cb1f95675b322e955763cd9bb628ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:59 +0100 Subject: [PATCH 1018/1480] iio: dac: ad5593r: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-86-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5593r.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 8e5e014e0c28b..d311567ab324a 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -99,9 +99,9 @@ static const struct ad5592r_rw_ops ad5593r_rw_ops = { .gpio_read = ad5593r_gpio_read, }; -static int ad5593r_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5593r_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) return -EOPNOTSUPP; @@ -138,7 +138,7 @@ static struct i2c_driver ad5593r_driver = { .of_match_table = ad5593r_of_match, .acpi_match_table = ad5593r_acpi_match, }, - .probe = ad5593r_i2c_probe, + .probe_new = ad5593r_i2c_probe, .remove = ad5593r_i2c_remove, .id_table = ad5593r_i2c_ids, }; -- GitLab From 92cd05a0968d60b3d76dc8d3a5880b25b1af96b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:00 +0100 Subject: [PATCH 1019/1480] iio: dac: ad5696-i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-87-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5696-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index aa36cbf0137c1..160e80cf9135f 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -58,9 +58,9 @@ static int ad5686_i2c_write(struct ad5686_state *st, return (ret != 3) ? -EIO : 0; } -static int ad5686_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5686_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5686_probe(&i2c->dev, id->driver_data, id->name, ad5686_i2c_write, ad5686_i2c_read); } @@ -113,7 +113,7 @@ static struct i2c_driver ad5686_i2c_driver = { .name = "ad5696", .of_match_table = ad5686_of_match, }, - .probe = ad5686_i2c_probe, + .probe_new = ad5686_i2c_probe, .remove = ad5686_i2c_remove, .id_table = ad5686_i2c_id, }; -- GitLab From 53f46605c3656c181e49df0d5fdba014cffa498e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:01 +0100 Subject: [PATCH 1020/1480] iio: dac: ds4424: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-88-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ds4424.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index 3e17a681174e8..a16a6a934d9d9 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -213,9 +213,9 @@ static const struct iio_info ds4424_info = { .write_raw = ds4424_write_raw, }; -static int ds4424_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ds4424_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ds4424_data *data; struct iio_dev *indio_dev; int ret; @@ -312,7 +312,7 @@ static struct i2c_driver ds4424_driver = { .of_match_table = ds4424_of_match, .pm = pm_sleep_ptr(&ds4424_pm_ops), }, - .probe = ds4424_probe, + .probe_new = ds4424_probe, .remove = ds4424_remove, .id_table = ds4424_id, }; -- GitLab From 44d7a03c98f466c1567a8cad84908ce6a9d1f2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:02 +0100 Subject: [PATCH 1021/1480] iio: dac: m62332: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-89-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/m62332.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index 5a812f87970c0..b692459b0f231 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -176,8 +176,7 @@ static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = { M62332_CHANNEL(1) }; -static int m62332_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int m62332_probe(struct i2c_client *client) { struct m62332_data *data; struct iio_dev *indio_dev; @@ -239,7 +238,7 @@ static struct i2c_driver m62332_driver = { .name = "m62332", .pm = pm_sleep_ptr(&m62332_pm_ops), }, - .probe = m62332_probe, + .probe_new = m62332_probe, .remove = m62332_remove, .id_table = m62332_id, }; -- GitLab From 090515edf46dc1f2ff7dbc78a60ba7692ff8420f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:03 +0100 Subject: [PATCH 1022/1480] iio: dac: max517: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-90-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max517.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 373ce6ff83b78..25967c39365d2 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -141,9 +141,9 @@ static const struct iio_chan_spec max517_channels[] = { MAX517_CHANNEL(7), }; -static int max517_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max517_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max517_data *data; struct iio_dev *indio_dev; struct max517_platform_data *platform_data = client->dev.platform_data; @@ -203,7 +203,7 @@ static struct i2c_driver max517_driver = { .name = MAX517_DRV_NAME, .pm = pm_sleep_ptr(&max517_pm_ops), }, - .probe = max517_probe, + .probe_new = max517_probe, .id_table = max517_id, }; module_i2c_driver(max517_driver); -- GitLab From 62b001dad803e40274db2c712dd4dc0d3a4a37d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:04 +0100 Subject: [PATCH 1023/1480] iio: dac: max5821: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-91-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max5821.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index e001b594d5b19..23da345b9250c 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -300,9 +300,9 @@ static void max5821_regulator_disable(void *reg) regulator_disable(reg); } -static int max5821_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max5821_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max5821_data *data; struct iio_dev *indio_dev; u32 tmp; @@ -377,7 +377,7 @@ static struct i2c_driver max5821_driver = { .of_match_table = max5821_of_match, .pm = pm_sleep_ptr(&max5821_pm_ops), }, - .probe = max5821_probe, + .probe_new = max5821_probe, .id_table = max5821_id, }; module_i2c_driver(max5821_driver); -- GitLab From 818fe4546521f5e836ab02eeb6533bfd6aee6829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:05 +0100 Subject: [PATCH 1024/1480] iio: dac: mcp4725: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-92-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/mcp4725.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 446d1a8fe4bef..46bf758760f85 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -369,9 +369,9 @@ static int mcp4725_probe_dt(struct device *dev, return 0; } -static int mcp4725_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mcp4725_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mcp4725_data *data; struct iio_dev *indio_dev; struct mcp4725_platform_data *pdata, pdata_dt; @@ -524,7 +524,7 @@ static struct i2c_driver mcp4725_driver = { .of_match_table = mcp4725_of_match, .pm = pm_sleep_ptr(&mcp4725_pm_ops), }, - .probe = mcp4725_probe, + .probe_new = mcp4725_probe, .remove = mcp4725_remove, .id_table = mcp4725_id, }; -- GitLab From 3de8dd69fad2c2ee7ca623d78fb2806d7b8b5a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:06 +0100 Subject: [PATCH 1025/1480] iio: dac: ti-dac5571: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20221118224540.619276-93-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ti-dac5571.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 3210e3098f9ae..40191947fea32 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -306,9 +306,9 @@ static const struct iio_info dac5571_info = { .write_raw_get_fmt = dac5571_write_raw_get_fmt, }; -static int dac5571_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dac5571_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; const struct dac5571_spec *spec; struct dac5571_data *data; @@ -426,7 +426,7 @@ static struct i2c_driver dac5571_driver = { .name = "ti-dac5571", .of_match_table = dac5571_of_id, }, - .probe = dac5571_probe, + .probe_new = dac5571_probe, .remove = dac5571_remove, .id_table = dac5571_id, }; -- GitLab From 840ef016c202fc196c91f020750fab08c9a0779f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:07 +0100 Subject: [PATCH 1026/1480] iio: gyro: bmg160_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-94-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/bmg160_i2c.c b/drivers/iio/gyro/bmg160_i2c.c index 908ccc385254a..2b019ee5b2eb5 100644 --- a/drivers/iio/gyro/bmg160_i2c.c +++ b/drivers/iio/gyro/bmg160_i2c.c @@ -13,9 +13,9 @@ static const struct regmap_config bmg160_regmap_i2c_conf = { .max_register = 0x3f }; -static int bmg160_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmg160_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; @@ -70,7 +70,7 @@ static struct i2c_driver bmg160_i2c_driver = { .of_match_table = bmg160_of_match, .pm = &bmg160_pm_ops, }, - .probe = bmg160_i2c_probe, + .probe_new = bmg160_i2c_probe, .remove = bmg160_i2c_remove, .id_table = bmg160_i2c_id, }; -- GitLab From 8312841060b8bc4b463dcf6a2cb8cc2452c6ac8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:08 +0100 Subject: [PATCH 1027/1480] iio: gyro: itg3200_core: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-95-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 74ca224684968..ceacd863d3eaa 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -295,8 +295,7 @@ static const struct iio_info itg3200_info = { static const unsigned long itg3200_available_scan_masks[] = { 0xffffffff, 0x0 }; -static int itg3200_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int itg3200_probe(struct i2c_client *client) { int ret; struct itg3200 *st; @@ -406,7 +405,7 @@ static struct i2c_driver itg3200_driver = { .pm = pm_sleep_ptr(&itg3200_pm_ops), }, .id_table = itg3200_id, - .probe = itg3200_probe, + .probe_new = itg3200_probe, .remove = itg3200_remove, }; -- GitLab From b97db5284e9ae169de79f78c3f09514d661407a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:09 +0100 Subject: [PATCH 1028/1480] iio: gyro: mpu3050-i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-96-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/mpu3050-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/mpu3050-i2c.c b/drivers/iio/gyro/mpu3050-i2c.c index 12e3afa9dd11d..2116798226bf2 100644 --- a/drivers/iio/gyro/mpu3050-i2c.c +++ b/drivers/iio/gyro/mpu3050-i2c.c @@ -32,9 +32,9 @@ static int mpu3050_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id) return 0; } -static int mpu3050_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpu3050_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name; struct mpu3050 *mpu3050; @@ -108,7 +108,7 @@ static const struct of_device_id mpu3050_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, mpu3050_i2c_of_match); static struct i2c_driver mpu3050_i2c_driver = { - .probe = mpu3050_i2c_probe, + .probe_new = mpu3050_i2c_probe, .remove = mpu3050_i2c_remove, .id_table = mpu3050_i2c_id, .driver = { -- GitLab From 1522b453c153cd93fe295a6dbd589f0f62fb168b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:10 +0100 Subject: [PATCH 1029/1480] iio: gyro: st_gyro_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-97-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/st_gyro_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 8c7af42b65587..797a1c6a04020 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -58,8 +58,7 @@ static const struct of_device_id st_gyro_of_match[] = { }; MODULE_DEVICE_TABLE(of, st_gyro_of_match); -static int st_gyro_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_gyro_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *gdata; @@ -112,7 +111,7 @@ static struct i2c_driver st_gyro_driver = { .name = "st-gyro-i2c", .of_match_table = st_gyro_of_match, }, - .probe = st_gyro_i2c_probe, + .probe_new = st_gyro_i2c_probe, .id_table = st_gyro_id_table, }; module_i2c_driver(st_gyro_driver); -- GitLab From d4764a4045b14a938594a082662b780c2c8eec78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:11 +0100 Subject: [PATCH 1030/1480] iio: health: afe4404: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-98-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/afe4404.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 8fca787b25245..658dfc1a346ca 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -459,8 +459,7 @@ static int afe4404_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(afe4404_pm_ops, afe4404_suspend, afe4404_resume); -static int afe4404_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int afe4404_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct afe4404_data *afe; @@ -608,7 +607,7 @@ static struct i2c_driver afe4404_i2c_driver = { .of_match_table = afe4404_of_match, .pm = pm_sleep_ptr(&afe4404_pm_ops), }, - .probe = afe4404_probe, + .probe_new = afe4404_probe, .remove = afe4404_remove, .id_table = afe4404_ids, }; -- GitLab From 3ef7e6e019c66beb6e4c8749a70d09d26326be8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:12 +0100 Subject: [PATCH 1031/1480] iio: health: max30100: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-99-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30100.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 3aa5d037a1c35..a80fa9852c220 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -417,8 +417,7 @@ static const struct iio_info max30100_info = { .read_raw = max30100_read_raw, }; -static int max30100_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max30100_probe(struct i2c_client *client) { struct max30100_data *data; struct iio_dev *indio_dev; @@ -500,7 +499,7 @@ static struct i2c_driver max30100_driver = { .name = MAX30100_DRV_NAME, .of_match_table = max30100_dt_ids, }, - .probe = max30100_probe, + .probe_new = max30100_probe, .remove = max30100_remove, .id_table = max30100_id, }; -- GitLab From 15818f0890133372fb7eb875841dbcdb8c8ed592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:13 +0100 Subject: [PATCH 1032/1480] iio: health: max30102: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-100-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 66df4aaa31a7b..7edcf9e05687b 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -513,9 +513,9 @@ static const struct iio_info max30102_info = { .read_raw = max30102_read_raw, }; -static int max30102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max30102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max30102_data *data; struct iio_dev *indio_dev; int ret; @@ -631,7 +631,7 @@ static struct i2c_driver max30102_driver = { .name = MAX30102_DRV_NAME, .of_match_table = max30102_dt_ids, }, - .probe = max30102_probe, + .probe_new = max30102_probe, .remove = max30102_remove, .id_table = max30102_id, }; -- GitLab From 1b1a60e70b0cd7ec46df424f6e7d342585c446b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:14 +0100 Subject: [PATCH 1033/1480] iio: humidity: am2315: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-101-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/am2315.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index 4a39f10193471..f246516bd45ea 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -218,8 +218,7 @@ static const struct iio_info am2315_info = { .read_raw = am2315_read_raw, }; -static int am2315_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int am2315_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -263,7 +262,7 @@ static struct i2c_driver am2315_driver = { .driver = { .name = "am2315", }, - .probe = am2315_probe, + .probe_new = am2315_probe, .id_table = am2315_i2c_id, }; -- GitLab From c5f1c4fdbfa2ac6ca247bf5f32fb4c35ba0b1ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:15 +0100 Subject: [PATCH 1034/1480] iio: humidity: hdc100x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-102-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hdc100x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 47f8e8ef56d68..49a950d739e44 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -351,8 +351,7 @@ static const struct iio_info hdc100x_info = { .attrs = &hdc100x_attribute_group, }; -static int hdc100x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hdc100x_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct hdc100x_data *data; @@ -429,7 +428,7 @@ static struct i2c_driver hdc100x_driver = { .of_match_table = hdc100x_dt_ids, .acpi_match_table = hdc100x_acpi_match, }, - .probe = hdc100x_probe, + .probe_new = hdc100x_probe, .id_table = hdc100x_id, }; module_i2c_driver(hdc100x_driver); -- GitLab From 0a78deeb639a464c9160f6bba912c97567f18b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:16 +0100 Subject: [PATCH 1035/1480] iio: humidity: hdc2010: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-103-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hdc2010.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/hdc2010.c b/drivers/iio/humidity/hdc2010.c index d6858ccb056e4..c8fddd612e060 100644 --- a/drivers/iio/humidity/hdc2010.c +++ b/drivers/iio/humidity/hdc2010.c @@ -251,8 +251,7 @@ static const struct iio_info hdc2010_info = { .attrs = &hdc2010_attribute_group, }; -static int hdc2010_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hdc2010_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct hdc2010_data *data; @@ -339,7 +338,7 @@ static struct i2c_driver hdc2010_driver = { .name = "hdc2010", .of_match_table = hdc2010_dt_ids, }, - .probe = hdc2010_probe, + .probe_new = hdc2010_probe, .remove = hdc2010_remove, .id_table = hdc2010_id, }; -- GitLab From 7b64a83ce6f94bbb91d91a66555f17bf3e9bc085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:17 +0100 Subject: [PATCH 1036/1480] iio: humidity: hts221_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-104-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hts221_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c index afbc611f7712f..d81869423cf03 100644 --- a/drivers/iio/humidity/hts221_i2c.c +++ b/drivers/iio/humidity/hts221_i2c.c @@ -25,8 +25,7 @@ static const struct regmap_config hts221_i2c_regmap_config = { .read_flag_mask = HTS221_I2C_AUTO_INCREMENT, }; -static int hts221_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hts221_i2c_probe(struct i2c_client *client) { struct regmap *regmap; @@ -66,7 +65,7 @@ static struct i2c_driver hts221_driver = { .of_match_table = hts221_i2c_of_match, .acpi_match_table = ACPI_PTR(hts221_acpi_match), }, - .probe = hts221_i2c_probe, + .probe_new = hts221_i2c_probe, .id_table = hts221_i2c_id_table, }; module_i2c_driver(hts221_driver); -- GitLab From 1a144b6320f32feec3e54dbbda8b4c58b69f86c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:18 +0100 Subject: [PATCH 1037/1480] iio: humidity: htu21: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-105-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/htu21.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index fd9e2565f8a2d..8411a9f3e828a 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -177,9 +177,9 @@ static const struct iio_info htu21_info = { .attrs = &htu21_attribute_group, }; -static int htu21_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int htu21_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms_ht_dev *dev_data; struct iio_dev *indio_dev; int ret; @@ -244,7 +244,7 @@ static const struct of_device_id htu21_of_match[] = { MODULE_DEVICE_TABLE(of, htu21_of_match); static struct i2c_driver htu21_driver = { - .probe = htu21_probe, + .probe_new = htu21_probe, .id_table = htu21_id, .driver = { .name = "htu21", -- GitLab From e18594f6d87f8f7f2623263eb230139382e1a080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:19 +0100 Subject: [PATCH 1038/1480] iio: humidity: si7005: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-106-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7005.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/si7005.c b/drivers/iio/humidity/si7005.c index 160b3d92df619..fa1faf168c8d9 100644 --- a/drivers/iio/humidity/si7005.c +++ b/drivers/iio/humidity/si7005.c @@ -123,8 +123,7 @@ static const struct iio_info si7005_info = { .read_raw = si7005_read_raw, }; -static int si7005_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si7005_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct si7005_data *data; @@ -174,7 +173,7 @@ static struct i2c_driver si7005_driver = { .driver = { .name = "si7005", }, - .probe = si7005_probe, + .probe_new = si7005_probe, .id_table = si7005_id, }; module_i2c_driver(si7005_driver); -- GitLab From e6b610550e2c17b9eb83b10109462fc88f9a6367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:20 +0100 Subject: [PATCH 1039/1480] iio: humidity: si7020: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-107-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7020.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index ab6537f136ba1..3e50592e8e68b 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -103,8 +103,7 @@ static const struct iio_info si7020_info = { .read_raw = si7020_read_raw, }; -static int si7020_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si7020_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct i2c_client **data; @@ -156,7 +155,7 @@ static struct i2c_driver si7020_driver = { .name = "si7020", .of_match_table = si7020_dt_ids, }, - .probe = si7020_probe, + .probe_new = si7020_probe, .id_table = si7020_id, }; -- GitLab From 97202c55041806ba3fcddd6ca1b467154b5812cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:21 +0100 Subject: [PATCH 1040/1480] iio: imu: bmi160/bmi160_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-108-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/bmi160/bmi160_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index d93f4fa2ad554..2ca907d396a01 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -15,9 +15,9 @@ #include "bmi160.h" -static int bmi160_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmi160_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name; @@ -60,7 +60,7 @@ static struct i2c_driver bmi160_i2c_driver = { .acpi_match_table = bmi160_acpi_match, .of_match_table = bmi160_of_match, }, - .probe = bmi160_i2c_probe, + .probe_new = bmi160_i2c_probe, .id_table = bmi160_i2c_id, }; module_i2c_driver(bmi160_i2c_driver); -- GitLab From 4fee985aaf3afaa4ce908342a854439fd8480196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:22 +0100 Subject: [PATCH 1041/1480] iio: imu: fxos8700_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-109-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/fxos8700_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/fxos8700_i2c.c b/drivers/iio/imu/fxos8700_i2c.c index 40a570325b0ac..a74a15fda8cbb 100644 --- a/drivers/iio/imu/fxos8700_i2c.c +++ b/drivers/iio/imu/fxos8700_i2c.c @@ -18,9 +18,9 @@ #include "fxos8700.h" -static int fxos8700_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int fxos8700_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; @@ -60,7 +60,7 @@ static struct i2c_driver fxos8700_i2c_driver = { .acpi_match_table = ACPI_PTR(fxos8700_acpi_match), .of_match_table = fxos8700_of_match, }, - .probe = fxos8700_i2c_probe, + .probe_new = fxos8700_i2c_probe, .id_table = fxos8700_i2c_id, }; module_i2c_driver(fxos8700_i2c_driver); -- GitLab From 4f218ae01c5c365f78f97e5d5b2c8cb15b503fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:23 +0100 Subject: [PATCH 1042/1480] iio: imu: inv_mpu6050: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Jean-Baptiste Maneyrol Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-110-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 7a8d60a5afa9a..2f2da4cb73215 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -91,13 +91,12 @@ static int inv_mpu_i2c_aux_setup(struct iio_dev *indio_dev) /** * inv_mpu_probe() - probe function. * @client: i2c client. - * @id: i2c device id. * * Returns 0 on success, a negative error code otherwise. */ -static int inv_mpu_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int inv_mpu_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const void *match; struct inv_mpu6050_state *st; int result; @@ -260,7 +259,7 @@ static const struct acpi_device_id inv_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, inv_acpi_match); static struct i2c_driver inv_mpu_driver = { - .probe = inv_mpu_probe, + .probe_new = inv_mpu_probe, .remove = inv_mpu_remove, .id_table = inv_mpu_id, .driver = { -- GitLab From 4bf718bc3b7f07f82895d4e56a2af93b9a89f43a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:24 +0100 Subject: [PATCH 1043/1480] iio: imu: kmx61: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-111-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/kmx61.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index b10c0dcac0bbe..e692dfeeda44c 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1276,9 +1276,9 @@ static struct iio_trigger *kmx61_trigger_setup(struct kmx61_data *data, return trig; } -static int kmx61_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int kmx61_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct kmx61_data *data; const char *name = NULL; @@ -1517,7 +1517,7 @@ static struct i2c_driver kmx61_driver = { .acpi_match_table = ACPI_PTR(kmx61_acpi_match), .pm = pm_ptr(&kmx61_pm_ops), }, - .probe = kmx61_probe, + .probe_new = kmx61_probe, .remove = kmx61_remove, .id_table = kmx61_id, }; -- GitLab From b7dbc0aecb2f4ca38475f0ef9d1b6ab6137be599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:25 +0100 Subject: [PATCH 1044/1480] iio: imu: st_lsm6dsx: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-112-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 0faf1b4c11afe..3570fac1b6125 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -21,9 +21,9 @@ static const struct regmap_config st_lsm6dsx_i2c_regmap_config = { .val_bits = 8, }; -static int st_lsm6dsx_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_lsm6dsx_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int hw_id = id->driver_data; struct regmap *regmap; @@ -152,7 +152,7 @@ static struct i2c_driver st_lsm6dsx_driver = { .pm = pm_sleep_ptr(&st_lsm6dsx_pm_ops), .of_match_table = st_lsm6dsx_i2c_of_match, }, - .probe = st_lsm6dsx_i2c_probe, + .probe_new = st_lsm6dsx_i2c_probe, .id_table = st_lsm6dsx_i2c_id_table, }; module_i2c_driver(st_lsm6dsx_driver); -- GitLab From 39c7d963d54a4dee2c6d95a4c5461600b26ca295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:26 +0100 Subject: [PATCH 1045/1480] iio: light: adjd_s311: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-113-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/adjd_s311.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 6b33975c8d738..210a90f44c532 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -233,8 +233,7 @@ static const struct iio_info adjd_s311_info = { .write_raw = adjd_s311_write_raw, }; -static int adjd_s311_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adjd_s311_probe(struct i2c_client *client) { struct adjd_s311_data *data; struct iio_dev *indio_dev; @@ -271,7 +270,7 @@ static struct i2c_driver adjd_s311_driver = { .driver = { .name = ADJD_S311_DRV_NAME, }, - .probe = adjd_s311_probe, + .probe_new = adjd_s311_probe, .id_table = adjd_s311_id, }; module_i2c_driver(adjd_s311_driver); -- GitLab From fd63b0a46acf4b00ff69e6c60ecdd3c78a68fc71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:27 +0100 Subject: [PATCH 1046/1480] iio: light: adux1020: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-114-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/adux1020.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/adux1020.c b/drivers/iio/light/adux1020.c index 9aa28695e6f19..606075350d01c 100644 --- a/drivers/iio/light/adux1020.c +++ b/drivers/iio/light/adux1020.c @@ -774,8 +774,7 @@ static int adux1020_chip_init(struct adux1020_data *data) ADUX1020_MODE_INT_MASK, ADUX1020_MODE_INT_DISABLE); } -static int adux1020_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adux1020_probe(struct i2c_client *client) { struct adux1020_data *data; struct iio_dev *indio_dev; @@ -838,7 +837,7 @@ static struct i2c_driver adux1020_driver = { .name = ADUX1020_DRV_NAME, .of_match_table = adux1020_of_match, }, - .probe = adux1020_probe, + .probe_new = adux1020_probe, .id_table = adux1020_id, }; module_i2c_driver(adux1020_driver); -- GitLab From ad428de325d27964f1c471ae496232df89b22885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:28 +0100 Subject: [PATCH 1047/1480] iio: light: al3010: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: David Heidelberg Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-115-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/al3010.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c index ce5363845b225..69cc723e2ac4a 100644 --- a/drivers/iio/light/al3010.c +++ b/drivers/iio/light/al3010.c @@ -164,8 +164,7 @@ static const struct iio_info al3010_info = { .attrs = &al3010_attribute_group, }; -static int al3010_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int al3010_probe(struct i2c_client *client) { struct al3010_data *data; struct iio_dev *indio_dev; @@ -230,7 +229,7 @@ static struct i2c_driver al3010_driver = { .of_match_table = al3010_of_match, .pm = pm_sleep_ptr(&al3010_pm_ops), }, - .probe = al3010_probe, + .probe_new = al3010_probe, .id_table = al3010_id, }; module_i2c_driver(al3010_driver); -- GitLab From a76c90301f86107240eebb404d9881f16344f779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:29 +0100 Subject: [PATCH 1048/1480] iio: light: al3320a: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-116-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/al3320a.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index bc99179728edc..9ff28bbf34bbe 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -187,8 +187,7 @@ static const struct iio_info al3320a_info = { .attrs = &al3320a_attribute_group, }; -static int al3320a_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int al3320a_probe(struct i2c_client *client) { struct al3320a_data *data; struct iio_dev *indio_dev; @@ -254,7 +253,7 @@ static struct i2c_driver al3320a_driver = { .of_match_table = al3320a_of_match, .pm = pm_sleep_ptr(&al3320a_pm_ops), }, - .probe = al3320a_probe, + .probe_new = al3320a_probe, .id_table = al3320a_id, }; -- GitLab From debe8c7568242ae7e49803c6bffc56362e43bfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:30 +0100 Subject: [PATCH 1049/1480] iio: light: apds9300: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-117-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9300.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index b70f2681bcb33..15dfb753734fa 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -398,8 +398,7 @@ static irqreturn_t apds9300_interrupt_handler(int irq, void *private) return IRQ_HANDLED; } -static int apds9300_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds9300_probe(struct i2c_client *client) { struct apds9300_data *data; struct iio_dev *indio_dev; @@ -505,7 +504,7 @@ static struct i2c_driver apds9300_driver = { .name = APDS9300_DRV_NAME, .pm = pm_sleep_ptr(&apds9300_pm_ops), }, - .probe = apds9300_probe, + .probe_new = apds9300_probe, .remove = apds9300_remove, .id_table = apds9300_id, }; -- GitLab From 783964ae9752541356e40f47b677069151543c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:31 +0100 Subject: [PATCH 1050/1480] iio: light: apds9960: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Acked-by: Matt Ranostay Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-118-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9960.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 997aa01ecc115..ee6acc6a36eef 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -988,8 +988,7 @@ static int apds9960_chip_init(struct apds9960_data *data) return apds9960_set_powermode(data, 1); } -static int apds9960_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds9960_probe(struct i2c_client *client) { struct apds9960_data *data; struct iio_dev *indio_dev; @@ -1132,7 +1131,7 @@ static struct i2c_driver apds9960_driver = { .pm = &apds9960_pm_ops, .acpi_match_table = apds9960_acpi_match, }, - .probe = apds9960_probe, + .probe_new = apds9960_probe, .remove = apds9960_remove, .id_table = apds9960_id, }; -- GitLab From 058d6333ea4fe069cce36adb12d6a6341ddcb540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:32 +0100 Subject: [PATCH 1051/1480] iio: light: bh1750: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-119-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/bh1750.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/bh1750.c b/drivers/iio/light/bh1750.c index 3e92820bc8200..390c5b3ad4f67 100644 --- a/drivers/iio/light/bh1750.c +++ b/drivers/iio/light/bh1750.c @@ -228,9 +228,9 @@ static const struct iio_chan_spec bh1750_channels[] = { } }; -static int bh1750_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bh1750_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret, usec; struct bh1750_data *data; struct iio_dev *indio_dev; @@ -320,7 +320,7 @@ static struct i2c_driver bh1750_driver = { .of_match_table = bh1750_of_match, .pm = pm_sleep_ptr(&bh1750_pm_ops), }, - .probe = bh1750_probe, + .probe_new = bh1750_probe, .remove = bh1750_remove, .id_table = bh1750_id, -- GitLab From ed5c6b1ce4e1d412f9a97973348c7b8f3e12025a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:33 +0100 Subject: [PATCH 1052/1480] iio: light: bh1780: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-120-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/bh1780.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index 90bca392b2620..da9039e5a8391 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c @@ -141,8 +141,7 @@ static const struct iio_chan_spec bh1780_channels[] = { } }; -static int bh1780_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bh1780_probe(struct i2c_client *client) { int ret; struct bh1780_data *bh1780; @@ -270,7 +269,7 @@ static const struct of_device_id of_bh1780_match[] = { MODULE_DEVICE_TABLE(of, of_bh1780_match); static struct i2c_driver bh1780_driver = { - .probe = bh1780_probe, + .probe_new = bh1780_probe, .remove = bh1780_remove, .id_table = bh1780_id, .driver = { -- GitLab From f8232aad7609a946d4bbb76b747cb9d73b8180f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:34 +0100 Subject: [PATCH 1053/1480] iio: light: cm3232: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-121-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3232.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index 5214cd014cf8b..43e492f5051d1 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -325,9 +325,9 @@ static const struct iio_info cm3232_info = { .attrs = &cm3232_attribute_group, }; -static int cm3232_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm3232_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct cm3232_chip *chip; struct iio_dev *indio_dev; int ret; @@ -417,7 +417,7 @@ static struct i2c_driver cm3232_driver = { .pm = pm_sleep_ptr(&cm3232_pm_ops), }, .id_table = cm3232_id, - .probe = cm3232_probe, + .probe_new = cm3232_probe, .remove = cm3232_remove, }; -- GitLab From ebbcdb1a9ddec05b37347d3fbf537e1741876901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:35 +0100 Subject: [PATCH 1054/1480] iio: light: cm3323: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-122-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3323.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index fd9a8c27de2e2..e5ce7d0fd272e 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c @@ -214,8 +214,7 @@ static const struct iio_info cm3323_info = { .attrs = &cm3323_attribute_group, }; -static int cm3323_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm3323_probe(struct i2c_client *client) { struct cm3323_data *data; struct iio_dev *indio_dev; @@ -267,7 +266,7 @@ static struct i2c_driver cm3323_driver = { .name = CM3323_DRV_NAME, .of_match_table = cm3323_of_match, }, - .probe = cm3323_probe, + .probe_new = cm3323_probe, .id_table = cm3323_id, }; -- GitLab From 31ceb2f5b4fbd7dd46d7d679b990e9195f1b3db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:36 +0100 Subject: [PATCH 1055/1480] iio: light: cm36651: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-123-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm36651.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 6615c98b601c3..1707dbf2ce267 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -618,9 +618,9 @@ static const struct iio_info cm36651_info = { .attrs = &cm36651_attribute_group, }; -static int cm36651_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm36651_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct cm36651_data *cm36651; struct iio_dev *indio_dev; int ret; @@ -730,7 +730,7 @@ static struct i2c_driver cm36651_driver = { .name = "cm36651", .of_match_table = cm36651_of_match, }, - .probe = cm36651_probe, + .probe_new = cm36651_probe, .remove = cm36651_remove, .id_table = cm36651_id, }; -- GitLab From b3f8e22e737e7991a3754675c7418215cdb461b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:37 +0100 Subject: [PATCH 1056/1480] iio: light: gp2ap002: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-124-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap002.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index 8000fa347344f..c0430db0038af 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -425,8 +425,7 @@ static struct regmap_bus gp2ap002_regmap_bus = { .reg_write = gp2ap002_regmap_i2c_write, }; -static int gp2ap002_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gp2ap002_probe(struct i2c_client *client) { struct gp2ap002 *gp2ap002; struct iio_dev *indio_dev; @@ -711,7 +710,7 @@ static struct i2c_driver gp2ap002_driver = { .of_match_table = gp2ap002_of_match, .pm = pm_ptr(&gp2ap002_dev_pm_ops), }, - .probe = gp2ap002_probe, + .probe_new = gp2ap002_probe, .remove = gp2ap002_remove, .id_table = gp2ap002_id_table, }; -- GitLab From a969195001bcf0d8baa5363fc8a1b4d3fc5aff0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:38 +0100 Subject: [PATCH 1057/1480] iio: light: gp2ap020a00f: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-125-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap020a00f.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 826439299e8b0..a5bf9da0d2f38 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1467,9 +1467,9 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { .predisable = &gp2ap020a00f_buffer_predisable, }; -static int gp2ap020a00f_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gp2ap020a00f_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct gp2ap020a00f_data *data; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1609,7 +1609,7 @@ static struct i2c_driver gp2ap020a00f_driver = { .name = GP2A_I2C_NAME, .of_match_table = gp2ap020a00f_of_match, }, - .probe = gp2ap020a00f_probe, + .probe_new = gp2ap020a00f_probe, .remove = gp2ap020a00f_remove, .id_table = gp2ap020a00f_id, }; -- GitLab From ee6e0241f854b23f2177b05a6cdd538bcfe8d9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:39 +0100 Subject: [PATCH 1058/1480] iio: light: isl29018: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-126-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29018.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index b36f8b7ca68e7..141845fb47f96 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -711,9 +711,9 @@ static void isl29018_disable_regulator_action(void *_data) pr_err("failed to disable isl29018's VCC regulator!\n"); } -static int isl29018_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29018_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct isl29018_chip *chip; struct iio_dev *indio_dev; int err; @@ -865,7 +865,7 @@ static struct i2c_driver isl29018_driver = { .pm = pm_sleep_ptr(&isl29018_pm_ops), .of_match_table = isl29018_of_match, }, - .probe = isl29018_probe, + .probe_new = isl29018_probe, .id_table = isl29018_id, }; module_i2c_driver(isl29018_driver); -- GitLab From 2086bafffdf7200238ba887a4ac9bdba0c4503e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:40 +0100 Subject: [PATCH 1059/1480] iio: light: isl29028: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-127-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29028.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c index 32d58e18f26da..bcf3a556e41ad 100644 --- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -565,9 +565,9 @@ static const struct regmap_config isl29028_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int isl29028_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29028_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct isl29028_chip *chip; struct iio_dev *indio_dev; int ret; @@ -698,7 +698,7 @@ static struct i2c_driver isl29028_driver = { .pm = pm_ptr(&isl29028_pm_ops), .of_match_table = isl29028_of_match, }, - .probe = isl29028_probe, + .probe_new = isl29028_probe, .remove = isl29028_remove, .id_table = isl29028_id, }; -- GitLab From 3059126a449c8c62c6b766da7744f853cce6ad36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:41 +0100 Subject: [PATCH 1060/1480] iio: light: isl29125: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-128-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29125.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index c199e63cce828..b4bd656ca1698 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -241,8 +241,7 @@ static const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = { .predisable = isl29125_buffer_predisable, }; -static int isl29125_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29125_probe(struct i2c_client *client) { struct isl29125_data *data; struct iio_dev *indio_dev; @@ -338,7 +337,7 @@ static struct i2c_driver isl29125_driver = { .name = ISL29125_DRV_NAME, .pm = pm_sleep_ptr(&isl29125_pm_ops), }, - .probe = isl29125_probe, + .probe_new = isl29125_probe, .remove = isl29125_remove, .id_table = isl29125_id, }; -- GitLab From dd97aab4f02c72d053335424752ee648a572ff81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:42 +0100 Subject: [PATCH 1061/1480] iio: light: jsa1212: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-129-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/jsa1212.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index 57ce6d75966c6..d3834d0a0635a 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -308,8 +308,7 @@ static const struct regmap_config jsa1212_regmap_config = { .volatile_reg = jsa1212_is_volatile_reg, }; -static int jsa1212_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int jsa1212_probe(struct i2c_client *client) { struct jsa1212_data *data; struct iio_dev *indio_dev; @@ -441,7 +440,7 @@ static struct i2c_driver jsa1212_driver = { .pm = pm_sleep_ptr(&jsa1212_pm_ops), .acpi_match_table = ACPI_PTR(jsa1212_acpi_match), }, - .probe = jsa1212_probe, + .probe_new = jsa1212_probe, .remove = jsa1212_remove, .id_table = jsa1212_id, }; -- GitLab From 958f5a0de0f67289e6bc0fa7850056b2af0c14f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:43 +0100 Subject: [PATCH 1062/1480] iio: light: ltr501: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-130-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/ltr501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 453b845ef265b..bdbd918213e45 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -1432,9 +1432,9 @@ static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx) return dev_name(dev); } -static int ltr501_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltr501_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); static const char * const regulator_names[] = { "vdd", "vddio" }; struct ltr501_data *data; struct iio_dev *indio_dev; @@ -1641,7 +1641,7 @@ static struct i2c_driver ltr501_driver = { .pm = pm_sleep_ptr(<r501_pm_ops), .acpi_match_table = ACPI_PTR(ltr_acpi_match), }, - .probe = ltr501_probe, + .probe_new = ltr501_probe, .remove = ltr501_remove, .id_table = ltr501_id, }; -- GitLab From f0a6f7674ef29e01e8db2986f534476f60aac3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:44 +0100 Subject: [PATCH 1063/1480] iio: light: lv0104cs: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-131-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/lv0104cs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/lv0104cs.c b/drivers/iio/light/lv0104cs.c index c2aef88f4e634..c041fa0faa5df 100644 --- a/drivers/iio/light/lv0104cs.c +++ b/drivers/iio/light/lv0104cs.c @@ -474,8 +474,7 @@ static const struct iio_chan_spec lv0104cs_channels[] = { }, }; -static int lv0104cs_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lv0104cs_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct lv0104cs_private *lv0104cs; @@ -521,7 +520,7 @@ static struct i2c_driver lv0104cs_i2c_driver = { .name = "lv0104cs", }, .id_table = lv0104cs_id, - .probe = lv0104cs_probe, + .probe_new = lv0104cs_probe, }; module_i2c_driver(lv0104cs_i2c_driver); -- GitLab From 0978ef36b24cb10937417e94d49d5a3f1092e3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:45 +0100 Subject: [PATCH 1064/1480] iio: light: max44000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-132-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/max44000.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index 85689dffbcbf7..5dcabc43a30e6 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -523,8 +523,7 @@ out_unlock: return IRQ_HANDLED; } -static int max44000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max44000_probe(struct i2c_client *client) { struct max44000_data *data; struct iio_dev *indio_dev; @@ -617,7 +616,7 @@ static struct i2c_driver max44000_driver = { .name = MAX44000_DRV_NAME, .acpi_match_table = ACPI_PTR(max44000_acpi_match), }, - .probe = max44000_probe, + .probe_new = max44000_probe, .id_table = max44000_id, }; -- GitLab From c49135d99f5285a3e781a50ee7111f68150d5cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:47 +0100 Subject: [PATCH 1065/1480] iio: light: noa1305: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-134-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/noa1305.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c index be3536b390fcb..eaf548d4649ea 100644 --- a/drivers/iio/light/noa1305.c +++ b/drivers/iio/light/noa1305.c @@ -186,8 +186,7 @@ static const struct regmap_config noa1305_regmap_config = { .writeable_reg = noa1305_writable_reg, }; -static int noa1305_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int noa1305_probe(struct i2c_client *client) { struct noa1305_priv *priv; struct iio_dev *indio_dev; @@ -279,7 +278,7 @@ static struct i2c_driver noa1305_driver = { .name = NOA1305_DRIVER_NAME, .of_match_table = noa1305_of_match, }, - .probe = noa1305_probe, + .probe_new = noa1305_probe, .id_table = noa1305_ids, }; -- GitLab From 06d10073283e5b301bd850a9ded6f592fb74a803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:48 +0100 Subject: [PATCH 1066/1480] iio: light: opt3001: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-135-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt3001.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index a26d1c3f95437..ec4f5c2369c42 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -735,8 +735,7 @@ out: return IRQ_HANDLED; } -static int opt3001_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int opt3001_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -835,7 +834,7 @@ static const struct of_device_id opt3001_of_match[] = { MODULE_DEVICE_TABLE(of, opt3001_of_match); static struct i2c_driver opt3001_driver = { - .probe = opt3001_probe, + .probe_new = opt3001_probe, .remove = opt3001_remove, .id_table = opt3001_id, -- GitLab From e16302076d8a42b760878fe603593e2c59106948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:49 +0100 Subject: [PATCH 1067/1480] iio: light: pa12203001: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-136-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/pa12203001.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/pa12203001.c b/drivers/iio/light/pa12203001.c index 3cb2de51f4aa8..15a666f15c275 100644 --- a/drivers/iio/light/pa12203001.c +++ b/drivers/iio/light/pa12203001.c @@ -338,8 +338,7 @@ out: return ret; } -static int pa12203001_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pa12203001_probe(struct i2c_client *client) { struct pa12203001_data *data; struct iio_dev *indio_dev; @@ -475,7 +474,7 @@ static struct i2c_driver pa12203001_driver = { .pm = &pa12203001_pm_ops, .acpi_match_table = ACPI_PTR(pa12203001_acpi_match), }, - .probe = pa12203001_probe, + .probe_new = pa12203001_probe, .remove = pa12203001_remove, .id_table = pa12203001_id, -- GitLab From 314ba3b4208b8fdc66ca6a94dac778ab673444e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:50 +0100 Subject: [PATCH 1068/1480] iio: light: rpr0521: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-137-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/rpr0521.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index d1c16dd760583..668e444f60498 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -927,8 +927,7 @@ static const struct regmap_config rpr0521_regmap_config = { .volatile_reg = rpr0521_is_volatile_reg, }; -static int rpr0521_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rpr0521_probe(struct i2c_client *client) { struct rpr0521_data *data; struct iio_dev *indio_dev; @@ -1122,7 +1121,7 @@ static struct i2c_driver rpr0521_driver = { .pm = pm_ptr(&rpr0521_pm_ops), .acpi_match_table = ACPI_PTR(rpr0521_acpi_match), }, - .probe = rpr0521_probe, + .probe_new = rpr0521_probe, .remove = rpr0521_remove, .id_table = rpr0521_id, }; -- GitLab From 122b0c0ba505a2faebb883bbfc178449d47c4fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:51 +0100 Subject: [PATCH 1069/1480] iio: light: si1133: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-138-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/si1133.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/si1133.c b/drivers/iio/light/si1133.c index f8c9b2cc322e8..a08fbc8f5adb1 100644 --- a/drivers/iio/light/si1133.c +++ b/drivers/iio/light/si1133.c @@ -990,9 +990,9 @@ static int si1133_validate_ids(struct iio_dev *iio_dev) return 0; } -static int si1133_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si1133_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct si1133_data *data; struct iio_dev *iio_dev; int err; @@ -1064,7 +1064,7 @@ static struct i2c_driver si1133_driver = { .driver = { .name = "si1133", }, - .probe = si1133_probe, + .probe_new = si1133_probe, .id_table = si1133_ids, }; -- GitLab From fb006652dc597b2807bab56d25fe3b3404f87e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:52 +0100 Subject: [PATCH 1070/1480] iio: light: si1145: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-139-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/si1145.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index e8f6cdf26f22a..f7126235f94c9 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -1269,9 +1269,9 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev) return 0; } -static int si1145_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si1145_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct si1145_data *data; struct iio_dev *indio_dev; u8 part_id, rev_id, seq_id; @@ -1352,7 +1352,7 @@ static struct i2c_driver si1145_driver = { .driver = { .name = "si1145", }, - .probe = si1145_probe, + .probe_new = si1145_probe, .id_table = si1145_ids, }; -- GitLab From c3ff326a9d3c809b493775bd65c07dccb73258cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:53 +0100 Subject: [PATCH 1071/1480] iio: light: st_uvis25_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-140-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/st_uvis25_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/st_uvis25_i2c.c b/drivers/iio/light/st_uvis25_i2c.c index c982b0b255cf8..2160e87bb498e 100644 --- a/drivers/iio/light/st_uvis25_i2c.c +++ b/drivers/iio/light/st_uvis25_i2c.c @@ -25,8 +25,7 @@ static const struct regmap_config st_uvis25_i2c_regmap_config = { .read_flag_mask = UVIS25_I2C_AUTO_INCREMENT, }; -static int st_uvis25_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_uvis25_i2c_probe(struct i2c_client *client) { struct regmap *regmap; @@ -58,7 +57,7 @@ static struct i2c_driver st_uvis25_driver = { .pm = pm_sleep_ptr(&st_uvis25_pm_ops), .of_match_table = st_uvis25_i2c_of_match, }, - .probe = st_uvis25_i2c_probe, + .probe_new = st_uvis25_i2c_probe, .id_table = st_uvis25_i2c_id_table, }; module_i2c_driver(st_uvis25_driver); -- GitLab From 9046d80dce04c65c92ea5550f220a2de236e3ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:54 +0100 Subject: [PATCH 1072/1480] iio: light: stk3310: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-141-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/stk3310.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 7b8e0da6aabc1..48ae6ff0015e1 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -586,8 +586,7 @@ out: return IRQ_HANDLED; } -static int stk3310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk3310_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -715,7 +714,7 @@ static struct i2c_driver stk3310_driver = { .pm = pm_sleep_ptr(&stk3310_pm_ops), .acpi_match_table = ACPI_PTR(stk3310_acpi_id), }, - .probe = stk3310_probe, + .probe_new = stk3310_probe, .remove = stk3310_remove, .id_table = stk3310_i2c_id, }; -- GitLab From b30cfdeb9f7fe03103472c4c79e65e382935082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:55 +0100 Subject: [PATCH 1073/1480] iio: light: tcs3414: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-142-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tcs3414.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index 3951536022b3d..5100732fbaf0a 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -279,8 +279,7 @@ static void tcs3414_powerdown_cleanup(void *data) tcs3414_powerdown(data); } -static int tcs3414_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tcs3414_probe(struct i2c_client *client) { struct tcs3414_data *data; struct iio_dev *indio_dev; @@ -374,7 +373,7 @@ static struct i2c_driver tcs3414_driver = { .name = TCS3414_DRV_NAME, .pm = pm_sleep_ptr(&tcs3414_pm_ops), }, - .probe = tcs3414_probe, + .probe_new = tcs3414_probe, .id_table = tcs3414_id, }; module_i2c_driver(tcs3414_driver); -- GitLab From e498cc544eae9b6264c9a535f8784aafe5788965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:56 +0100 Subject: [PATCH 1074/1480] iio: light: tcs3472: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-143-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tcs3472.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index db17fec634be1..6187c54879162 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -442,8 +442,7 @@ static const struct iio_info tcs3472_info = { .attrs = &tcs3472_attribute_group, }; -static int tcs3472_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tcs3472_probe(struct i2c_client *client) { struct tcs3472_data *data; struct iio_dev *indio_dev; @@ -610,7 +609,7 @@ static struct i2c_driver tcs3472_driver = { .name = TCS3472_DRV_NAME, .pm = pm_sleep_ptr(&tcs3472_pm_ops), }, - .probe = tcs3472_probe, + .probe_new = tcs3472_probe, .remove = tcs3472_remove, .id_table = tcs3472_id, }; -- GitLab From 74cd01b3f9041ef3e44cc043b8bb10f79ec52c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:57 +0100 Subject: [PATCH 1075/1480] iio: light: tsl2563: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-144-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2563.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 951f35ef3f41d..d0e42b73203a6 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -699,8 +699,7 @@ static const struct iio_info tsl2563_info = { .write_event_config = &tsl2563_write_interrupt_config, }; -static int tsl2563_probe(struct i2c_client *client, - const struct i2c_device_id *device_id) +static int tsl2563_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct tsl2563_chip *chip; @@ -880,7 +879,7 @@ static struct i2c_driver tsl2563_i2c_driver = { .of_match_table = tsl2563_of_match, .pm = pm_sleep_ptr(&tsl2563_pm_ops), }, - .probe = tsl2563_probe, + .probe_new = tsl2563_probe, .remove = tsl2563_remove, .id_table = tsl2563_id, }; -- GitLab From dcc484a21108441f7970c4813b1223154dd23ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:58 +0100 Subject: [PATCH 1076/1480] iio: light: tsl2583: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-145-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2583.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c index 7bcb5c7189224..a05f1c0453d16 100644 --- a/drivers/iio/light/tsl2583.c +++ b/drivers/iio/light/tsl2583.c @@ -809,8 +809,7 @@ static const struct iio_info tsl2583_info = { .write_raw = tsl2583_write_raw, }; -static int tsl2583_probe(struct i2c_client *clientp, - const struct i2c_device_id *idp) +static int tsl2583_probe(struct i2c_client *clientp) { int ret; struct tsl2583_chip *chip; @@ -943,7 +942,7 @@ static struct i2c_driver tsl2583_driver = { .of_match_table = tsl2583_of_match, }, .id_table = tsl2583_idtable, - .probe = tsl2583_probe, + .probe_new = tsl2583_probe, .remove = tsl2583_remove, }; module_i2c_driver(tsl2583_driver); -- GitLab From e723b95135b1510873c832eaf8361e6b8d76bfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:37:59 +0100 Subject: [PATCH 1077/1480] iio: light: tsl2772: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-146-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2772.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index dd9051f1cc1a0..ad50baa0202cc 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -1750,9 +1750,9 @@ static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = { }, }; -static int tsl2772_probe(struct i2c_client *clientp, - const struct i2c_device_id *id) +static int tsl2772_probe(struct i2c_client *clientp) { + const struct i2c_device_id *id = i2c_client_get_device_id(clientp); struct iio_dev *indio_dev; struct tsl2772_chip *chip; int ret; @@ -1931,7 +1931,7 @@ static struct i2c_driver tsl2772_driver = { .pm = &tsl2772_pm_ops, }, .id_table = tsl2772_idtable, - .probe = tsl2772_probe, + .probe_new = tsl2772_probe, }; module_i2c_driver(tsl2772_driver); -- GitLab From 081f6b9dc055f9ccb19a86346b80df691972120b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:00 +0100 Subject: [PATCH 1078/1480] iio: light: tsl4531: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-147-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl4531.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c index 090038fed8891..d95397eb15263 100644 --- a/drivers/iio/light/tsl4531.c +++ b/drivers/iio/light/tsl4531.c @@ -160,8 +160,7 @@ static int tsl4531_check_id(struct i2c_client *client) } } -static int tsl4531_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsl4531_probe(struct i2c_client *client) { struct tsl4531_data *data; struct iio_dev *indio_dev; @@ -238,7 +237,7 @@ static struct i2c_driver tsl4531_driver = { .name = TSL4531_DRV_NAME, .pm = pm_sleep_ptr(&tsl4531_pm_ops), }, - .probe = tsl4531_probe, + .probe_new = tsl4531_probe, .remove = tsl4531_remove, .id_table = tsl4531_id, }; -- GitLab From 3ed2b14de4d36a9335e93798bf966c521df42a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:01 +0100 Subject: [PATCH 1079/1480] iio: light: us5182d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-148-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 3e652d7f3b0eb..8b2a0c99c8e6f 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -832,8 +832,7 @@ static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) return IRQ_HANDLED; } -static int us5182d_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int us5182d_probe(struct i2c_client *client) { struct us5182d_data *data; struct iio_dev *indio_dev; @@ -975,7 +974,7 @@ static struct i2c_driver us5182d_driver = { .of_match_table = us5182d_of_match, .acpi_match_table = ACPI_PTR(us5182d_acpi_match), }, - .probe = us5182d_probe, + .probe_new = us5182d_probe, .remove = us5182d_remove, .id_table = us5182d_id, -- GitLab From e61295e0d7cf6de3d7cc25e7f387ffe021f0b0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:02 +0100 Subject: [PATCH 1080/1480] iio: light: vcnl4000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-149-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index fdb3922ae4acd..cc1a2062e76d6 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -1180,9 +1180,9 @@ static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) return devm_iio_trigger_register(&client->dev, trigger); } -static int vcnl4000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vcnl4000_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct vcnl4000_data *data; struct iio_dev *indio_dev; int ret; @@ -1326,7 +1326,7 @@ static struct i2c_driver vcnl4000_driver = { .pm = pm_ptr(&vcnl4000_pm_ops), .of_match_table = vcnl_4000_of_match, }, - .probe = vcnl4000_probe, + .probe_new = vcnl4000_probe, .id_table = vcnl4000_id, .remove = vcnl4000_remove, }; -- GitLab From 9da43dcc54a19fe40e3aa7dc03fbca3f8c0395ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:03 +0100 Subject: [PATCH 1081/1480] iio: light: vcnl4035: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-150-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4035.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index 3ed37f6057fbf..84148b9440006 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -539,8 +539,7 @@ static int vcnl4035_probe_trigger(struct iio_dev *indio_dev) return ret; } -static int vcnl4035_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vcnl4035_probe(struct i2c_client *client) { struct vcnl4035_data *data; struct iio_dev *indio_dev; @@ -668,7 +667,7 @@ static struct i2c_driver vcnl4035_driver = { .pm = pm_ptr(&vcnl4035_pm_ops), .of_match_table = vcnl4035_of_match, }, - .probe = vcnl4035_probe, + .probe_new = vcnl4035_probe, .remove = vcnl4035_remove, .id_table = vcnl4035_id, }; -- GitLab From e465524d64d11fbd25a9eb65ce4e77b965979291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:04 +0100 Subject: [PATCH 1082/1480] iio: light: veml6030: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-151-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6030.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 9a7800cdfee26..e7d2d5d177d43 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -786,8 +786,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) return ret; } -static int veml6030_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int veml6030_probe(struct i2c_client *client) { int ret; struct veml6030_data *data; @@ -893,7 +892,7 @@ static struct i2c_driver veml6030_driver = { .of_match_table = veml6030_of_match, .pm = pm_ptr(&veml6030_pm_ops), }, - .probe = veml6030_probe, + .probe_new = veml6030_probe, .id_table = veml6030_id, }; module_i2c_driver(veml6030_driver); -- GitLab From f90b8694f355566c2ff70564942d4932d76e28e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:05 +0100 Subject: [PATCH 1083/1480] iio: light: veml6070: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-152-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6070.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index cfa4e9e7c8038..ee76a68deb24a 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -135,8 +135,7 @@ static const struct iio_info veml6070_info = { .read_raw = veml6070_read_raw, }; -static int veml6070_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int veml6070_probe(struct i2c_client *client) { struct veml6070_data *data; struct iio_dev *indio_dev; @@ -199,7 +198,7 @@ static struct i2c_driver veml6070_driver = { .driver = { .name = VEML6070_DRV_NAME, }, - .probe = veml6070_probe, + .probe_new = veml6070_probe, .remove = veml6070_remove, .id_table = veml6070_id, }; -- GitLab From 6811c7a52f025ab50f53b3107e6071132a8fe1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:06 +0100 Subject: [PATCH 1084/1480] iio: light: zopt2201: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-153-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/zopt2201.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/zopt2201.c b/drivers/iio/light/zopt2201.c index e0bc9df9c88b0..e3bac8b563807 100644 --- a/drivers/iio/light/zopt2201.c +++ b/drivers/iio/light/zopt2201.c @@ -501,8 +501,7 @@ static const struct iio_info zopt2201_info = { .attrs = &zopt2201_attribute_group, }; -static int zopt2201_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int zopt2201_probe(struct i2c_client *client) { struct zopt2201_data *data; struct iio_dev *indio_dev; @@ -555,7 +554,7 @@ static struct i2c_driver zopt2201_driver = { .driver = { .name = ZOPT2201_DRV_NAME, }, - .probe = zopt2201_probe, + .probe_new = zopt2201_probe, .id_table = zopt2201_id, }; -- GitLab From 149a5043b6f9b100471a1fdbdc22a395602fadd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:07 +0100 Subject: [PATCH 1085/1480] iio: magnetometer: ak8974: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-154-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8974.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 7ec9ab3beb45a..45abdcce6bc0a 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -814,8 +814,7 @@ static const struct regmap_config ak8974_regmap_config = { .precious_reg = ak8974_precious_reg, }; -static int ak8974_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak8974_probe(struct i2c_client *i2c) { struct iio_dev *indio_dev; struct ak8974 *ak8974; @@ -1047,7 +1046,7 @@ static struct i2c_driver ak8974_driver = { .pm = pm_ptr(&ak8974_dev_pm_ops), .of_match_table = ak8974_of_match, }, - .probe = ak8974_probe, + .probe_new = ak8974_probe, .remove = ak8974_remove, .id_table = ak8974_id, }; -- GitLab From f64eecea19ba974f03e3614ebcc3749d9a24da77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:08 +0100 Subject: [PATCH 1086/1480] iio: magnetometer: ak8975: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-155-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index caf03a2a98a5d..924b481a3034a 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -876,9 +876,9 @@ static irqreturn_t ak8975_handle_trigger(int irq, void *p) return IRQ_HANDLED; } -static int ak8975_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ak8975_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ak8975_data *data; struct iio_dev *indio_dev; struct gpio_desc *eoc_gpiod; @@ -1110,7 +1110,7 @@ static struct i2c_driver ak8975_driver = { .of_match_table = ak8975_of_match, .acpi_match_table = ak_acpi_match, }, - .probe = ak8975_probe, + .probe_new = ak8975_probe, .remove = ak8975_remove, .id_table = ak8975_id, }; -- GitLab From f23215c1e5a1255ed2097afe3e564dec96f73911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:09 +0100 Subject: [PATCH 1087/1480] iio: magnetometer: bmc150_magn_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-156-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/bmc150_magn_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c index 570deaa87836b..44b8960eea175 100644 --- a/drivers/iio/magnetometer/bmc150_magn_i2c.c +++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c @@ -16,9 +16,9 @@ #include "bmc150_magn.h" -static int bmc150_magn_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmc150_magn_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; @@ -71,7 +71,7 @@ static struct i2c_driver bmc150_magn_driver = { .acpi_match_table = ACPI_PTR(bmc150_magn_acpi_match), .pm = &bmc150_magn_pm_ops, }, - .probe = bmc150_magn_i2c_probe, + .probe_new = bmc150_magn_i2c_probe, .remove = bmc150_magn_i2c_remove, .id_table = bmc150_magn_i2c_id, }; -- GitLab From bcf73c37f7c7e7c1d0cac6ebea36cfd7bf626727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:10 +0100 Subject: [PATCH 1088/1480] iio: magnetometer: hmc5843: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-157-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/hmc5843_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/hmc5843_i2c.c b/drivers/iio/magnetometer/hmc5843_i2c.c index 18a13dd512961..7ef2b1d562898 100644 --- a/drivers/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/iio/magnetometer/hmc5843_i2c.c @@ -52,9 +52,9 @@ static const struct regmap_config hmc5843_i2c_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int hmc5843_i2c_probe(struct i2c_client *cli, - const struct i2c_device_id *id) +static int hmc5843_i2c_probe(struct i2c_client *cli) { + const struct i2c_device_id *id = i2c_client_get_device_id(cli); struct regmap *regmap = devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config); if (IS_ERR(regmap)) @@ -95,7 +95,7 @@ static struct i2c_driver hmc5843_driver = { .of_match_table = hmc5843_of_match, }, .id_table = hmc5843_id, - .probe = hmc5843_i2c_probe, + .probe_new = hmc5843_i2c_probe, .remove = hmc5843_i2c_remove, }; module_i2c_driver(hmc5843_driver); -- GitLab From cee51403c696aac364fd991bc3a95a90722678b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:11 +0100 Subject: [PATCH 1089/1480] iio: magnetometer: mag3110: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-158-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/mag3110.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index b870ad8038626..661176a885ad7 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -469,9 +469,9 @@ static const struct iio_info mag3110_info = { static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0}; -static int mag3110_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mag3110_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mag3110_data *data; struct iio_dev *indio_dev; int ret; @@ -641,7 +641,7 @@ static struct i2c_driver mag3110_driver = { .of_match_table = mag3110_of_match, .pm = pm_sleep_ptr(&mag3110_pm_ops), }, - .probe = mag3110_probe, + .probe_new = mag3110_probe, .remove = mag3110_remove, .id_table = mag3110_id, }; -- GitLab From e7a45a76351b6b5163af4a581ab46fdad137d62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:12 +0100 Subject: [PATCH 1090/1480] iio: magnetometer: mmc35240: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-159-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/mmc35240.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c index 186edfcda0b70..756dadbad106f 100644 --- a/drivers/iio/magnetometer/mmc35240.c +++ b/drivers/iio/magnetometer/mmc35240.c @@ -481,8 +481,7 @@ static const struct regmap_config mmc35240_regmap_config = { .num_reg_defaults = ARRAY_SIZE(mmc35240_reg_defaults), }; -static int mmc35240_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mmc35240_probe(struct i2c_client *client) { struct mmc35240_data *data; struct iio_dev *indio_dev; @@ -576,7 +575,7 @@ static struct i2c_driver mmc35240_driver = { .pm = pm_sleep_ptr(&mmc35240_pm_ops), .acpi_match_table = ACPI_PTR(mmc35240_acpi_match), }, - .probe = mmc35240_probe, + .probe_new = mmc35240_probe, .id_table = mmc35240_id, }; -- GitLab From fcd969675290cd3cbe911b350502332be58f100b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:13 +0100 Subject: [PATCH 1091/1480] iio: magnetometer: yamaha-yas530: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-160-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/yamaha-yas530.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c index 801c760feb4d1..753717158b073 100644 --- a/drivers/iio/magnetometer/yamaha-yas530.c +++ b/drivers/iio/magnetometer/yamaha-yas530.c @@ -1384,9 +1384,9 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { }, }; -static int yas5xx_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int yas5xx_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct iio_dev *indio_dev; struct device *dev = &i2c->dev; struct yas5xx *yas5xx; @@ -1605,7 +1605,7 @@ static struct i2c_driver yas5xx_driver = { .of_match_table = yas5xx_of_match, .pm = pm_ptr(&yas5xx_dev_pm_ops), }, - .probe = yas5xx_probe, + .probe_new = yas5xx_probe, .remove = yas5xx_remove, .id_table = yas5xx_id, }; -- GitLab From b11df8374c0d0581474e0b8f74a7ba8f4a10be7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:14 +0100 Subject: [PATCH 1092/1480] iio: potentiometer: ad5272: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-161-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/ad5272.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c index ed5fc0b50fe97..aa140d6321016 100644 --- a/drivers/iio/potentiometer/ad5272.c +++ b/drivers/iio/potentiometer/ad5272.c @@ -158,9 +158,9 @@ static int ad5272_reset(struct ad5272_data *data) return 0; } -static int ad5272_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad5272_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct ad5272_data *data; @@ -218,7 +218,7 @@ static struct i2c_driver ad5272_driver = { .name = "ad5272", .of_match_table = ad5272_dt_ids, }, - .probe = ad5272_probe, + .probe_new = ad5272_probe, .id_table = ad5272_id, }; -- GitLab From 705f1ce22b967b8fd7fc3cb0de31830ec9eda3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:15 +0100 Subject: [PATCH 1093/1480] iio: potentiometer: ds1803: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-162-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/ds1803.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c index 5c212ed7a9313..0b5e475807cbc 100644 --- a/drivers/iio/potentiometer/ds1803.c +++ b/drivers/iio/potentiometer/ds1803.c @@ -202,8 +202,9 @@ static const struct iio_info ds1803_info = { .read_avail = ds1803_read_avail, }; -static int ds1803_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int ds1803_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct ds1803_data *data; struct iio_dev *indio_dev; @@ -251,7 +252,7 @@ static struct i2c_driver ds1803_driver = { .name = "ds1803", .of_match_table = ds1803_dt_ids, }, - .probe = ds1803_probe, + .probe_new = ds1803_probe, .id_table = ds1803_id, }; -- GitLab From e005024112dd3800e78d056facf958fc6451ba10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:16 +0100 Subject: [PATCH 1094/1480] iio: potentiometer: max5432: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-163-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/max5432.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/potentiometer/max5432.c b/drivers/iio/potentiometer/max5432.c index aed3b6ab82a21..94ef27ef3fb57 100644 --- a/drivers/iio/potentiometer/max5432.c +++ b/drivers/iio/potentiometer/max5432.c @@ -85,8 +85,7 @@ static const struct iio_info max5432_info = { .write_raw = max5432_write_raw, }; -static int max5432_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max5432_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct iio_dev *indio_dev; @@ -124,7 +123,7 @@ static struct i2c_driver max5432_driver = { .name = "max5432", .of_match_table = max5432_dt_ids, }, - .probe = max5432_probe, + .probe_new = max5432_probe, }; module_i2c_driver(max5432_driver); -- GitLab From 4c1142cc436842eefffcd800ca41f8327bf61f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:17 +0100 Subject: [PATCH 1095/1480] iio: potentiometer: tpl0102: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-164-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/tpl0102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index d996dc367fb77..a3465b413b0ca 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c @@ -120,9 +120,9 @@ static const struct iio_info tpl0102_info = { .write_raw = tpl0102_write_raw, }; -static int tpl0102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tpl0102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct tpl0102_data *data; struct iio_dev *indio_dev; @@ -161,7 +161,7 @@ static struct i2c_driver tpl0102_driver = { .driver = { .name = "tpl0102", }, - .probe = tpl0102_probe, + .probe_new = tpl0102_probe, .id_table = tpl0102_id, }; -- GitLab From 7d8b3e100abeeff40f54853ce82bc1d900cb2bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:18 +0100 Subject: [PATCH 1096/1480] iio: potentiostat: lmp91000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-165-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiostat/lmp91000.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 5ec7060d31d90..b82f093f1e6a4 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -292,8 +292,7 @@ static const struct iio_buffer_setup_ops lmp91000_buffer_setup_ops = { .predisable = lmp91000_buffer_predisable, }; -static int lmp91000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lmp91000_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct lmp91000_data *data; @@ -417,7 +416,7 @@ static struct i2c_driver lmp91000_driver = { .name = LMP91000_DRV_NAME, .of_match_table = lmp91000_of_match, }, - .probe = lmp91000_probe, + .probe_new = lmp91000_probe, .remove = lmp91000_remove, .id_table = lmp91000_id, }; -- GitLab From 576306ab4ceb16a032b5f67aeb635f385390193c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:19 +0100 Subject: [PATCH 1097/1480] iio: pressure: abp060mg: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-166-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/abp060mg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/abp060mg.c b/drivers/iio/pressure/abp060mg.c index e1c3bdb371ee6..c0140779366af 100644 --- a/drivers/iio/pressure/abp060mg.c +++ b/drivers/iio/pressure/abp060mg.c @@ -174,9 +174,9 @@ static void abp060mg_init_device(struct iio_dev *indio_dev, unsigned long id) state->offset -= ABP060MG_NUM_COUNTS >> 1; } -static int abp060mg_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int abp060mg_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct abp_state *state; unsigned long cfg_id = id->driver_data; @@ -255,7 +255,7 @@ static struct i2c_driver abp060mg_driver = { .driver = { .name = "abp060mg", }, - .probe = abp060mg_probe, + .probe_new = abp060mg_probe, .id_table = abp060mg_id_table, }; module_i2c_driver(abp060mg_driver); -- GitLab From 046ae105f266aae218f76dc6321eebebeead6b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:21 +0100 Subject: [PATCH 1098/1480] iio: pressure: dlhl60d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-168-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dlhl60d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index f0b0d198c6d47..43650b048d629 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -282,9 +282,9 @@ static irqreturn_t dlh_interrupt(int irq, void *private) return IRQ_HANDLED; }; -static int dlh_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dlh_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct dlh_state *st; struct iio_dev *indio_dev; int ret; @@ -362,7 +362,7 @@ static struct i2c_driver dlh_driver = { .name = "dlhl60d", .of_match_table = dlh_of_match, }, - .probe = dlh_probe, + .probe_new = dlh_probe, .id_table = dlh_id, }; module_i2c_driver(dlh_driver); -- GitLab From 92a54a29cf39f8f18632f9af43aa5baf4ff805bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:22 +0100 Subject: [PATCH 1099/1480] iio: pressure: dps310: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-169-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dps310.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 984a3f511a1ae..2af275a24ff9e 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -827,9 +827,9 @@ static const struct iio_info dps310_info = { .write_raw = dps310_write_raw, }; -static int dps310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dps310_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct dps310_data *data; struct iio_dev *iio; int rc; @@ -887,7 +887,7 @@ static struct i2c_driver dps310_driver = { .name = DPS310_DEV_NAME, .acpi_match_table = dps310_acpi_match, }, - .probe = dps310_probe, + .probe_new = dps310_probe, .id_table = dps310_id, }; module_i2c_driver(dps310_driver); -- GitLab From 3d5f5d599f61a2ab99768471cf56c61b1751f98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:23 +0100 Subject: [PATCH 1100/1480] iio: pressure: hp03: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-170-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/hp03.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/hp03.c b/drivers/iio/pressure/hp03.c index 9538118c96489..bd1f71a99cfa3 100644 --- a/drivers/iio/pressure/hp03.c +++ b/drivers/iio/pressure/hp03.c @@ -208,9 +208,9 @@ static const struct iio_info hp03_info = { .read_raw = &hp03_read_raw, }; -static int hp03_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hp03_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct hp03_priv *priv; @@ -282,7 +282,7 @@ static struct i2c_driver hp03_driver = { .name = "hp03", .of_match_table = hp03_of_match, }, - .probe = hp03_probe, + .probe_new = hp03_probe, .id_table = hp03_id, }; module_i2c_driver(hp03_driver); -- GitLab From 240c69e09d3f77673653f56867aba2c69a66264d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:24 +0100 Subject: [PATCH 1101/1480] iio: pressure: hp206c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-171-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/hp206c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/hp206c.c b/drivers/iio/pressure/hp206c.c index 986b7a59712e0..b6d2ff4643419 100644 --- a/drivers/iio/pressure/hp206c.c +++ b/drivers/iio/pressure/hp206c.c @@ -352,9 +352,9 @@ static const struct iio_info hp206c_info = { .write_raw = hp206c_write_raw, }; -static int hp206c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hp206c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct hp206c_data *data; int ret; @@ -409,7 +409,7 @@ MODULE_DEVICE_TABLE(acpi, hp206c_acpi_match); #endif static struct i2c_driver hp206c_driver = { - .probe = hp206c_probe, + .probe_new = hp206c_probe, .id_table = hp206c_id, .driver = { .name = "hp206c", -- GitLab From 7a5da8b28618426a81f53f496de3a83d47df2634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:25 +0100 Subject: [PATCH 1102/1480] iio: pressure: icp10100: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20221118224540.619276-172-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/icp10100.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/icp10100.c b/drivers/iio/pressure/icp10100.c index b62f28585db5b..407cf25ea0e33 100644 --- a/drivers/iio/pressure/icp10100.c +++ b/drivers/iio/pressure/icp10100.c @@ -530,8 +530,7 @@ static void icp10100_pm_disable(void *data) pm_runtime_disable(dev); } -static int icp10100_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int icp10100_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct icp10100_state *st; @@ -649,7 +648,7 @@ static struct i2c_driver icp10100_driver = { .pm = pm_ptr(&icp10100_pm), .of_match_table = icp10100_of_match, }, - .probe = icp10100_probe, + .probe_new = icp10100_probe, .id_table = icp10100_id, }; module_i2c_driver(icp10100_driver); -- GitLab From 8afce858762fc767dbd52d313adf058098332aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:26 +0100 Subject: [PATCH 1103/1480] iio: pressure: mpl115_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-173-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl115_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index 555bda1146fb9..ade4dd854ddf1 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -35,9 +35,9 @@ static const struct mpl115_ops mpl115_i2c_ops = { .write = mpl115_i2c_write, }; -static int mpl115_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpl115_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -EOPNOTSUPP; @@ -55,7 +55,7 @@ static struct i2c_driver mpl115_i2c_driver = { .name = "mpl115", .pm = pm_ptr(&mpl115_dev_pm_ops), }, - .probe = mpl115_i2c_probe, + .probe_new = mpl115_i2c_probe, .id_table = mpl115_i2c_id, }; module_i2c_driver(mpl115_i2c_driver); -- GitLab From 0586ce78a70c2792c4dfd415d1a427ea447bebd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:27 +0100 Subject: [PATCH 1104/1480] iio: pressure: mpl3115: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-174-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl3115.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 2f22aba61e4dd..72e811a5c96e6 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -230,9 +230,9 @@ static const struct iio_info mpl3115_info = { .read_raw = &mpl3115_read_raw, }; -static int mpl3115_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpl3115_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mpl3115_data *data; struct iio_dev *indio_dev; int ret; @@ -335,7 +335,7 @@ static struct i2c_driver mpl3115_driver = { .of_match_table = mpl3115_of_match, .pm = pm_sleep_ptr(&mpl3115_pm_ops), }, - .probe = mpl3115_probe, + .probe_new = mpl3115_probe, .remove = mpl3115_remove, .id_table = mpl3115_id, }; -- GitLab From eba7dcb65337dc2b081508317e10d0f1187121a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:28 +0100 Subject: [PATCH 1105/1480] iio: pressure: ms5611_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-175-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5611_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index b681a41839098..caf882497656d 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -79,9 +79,9 @@ static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st, return ms5611_i2c_read_adc(st, pressure); } -static int ms5611_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ms5611_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms5611_state *st; struct iio_dev *indio_dev; @@ -130,7 +130,7 @@ static struct i2c_driver ms5611_driver = { .of_match_table = ms5611_i2c_matches, }, .id_table = ms5611_id, - .probe = ms5611_i2c_probe, + .probe_new = ms5611_i2c_probe, .remove = ms5611_i2c_remove, }; module_i2c_driver(ms5611_driver); -- GitLab From f80ccc71c3f38d55662a6cfdec5a9e0907f6dfb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:29 +0100 Subject: [PATCH 1106/1480] iio: pressure: ms5637: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-176-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5637.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index 70c70019142ae..c4981b29dccb1 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -142,9 +142,9 @@ static const struct iio_info ms5637_info = { .attrs = &ms5637_attribute_group, }; -static int ms5637_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ms5637_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ms_tp_data *data; struct ms_tp_dev *dev_data; struct iio_dev *indio_dev; @@ -238,7 +238,7 @@ static const struct of_device_id ms5637_of_match[] = { MODULE_DEVICE_TABLE(of, ms5637_of_match); static struct i2c_driver ms5637_driver = { - .probe = ms5637_probe, + .probe_new = ms5637_probe, .id_table = ms5637_id, .driver = { .name = "ms5637", -- GitLab From a52833a526b5e38be1aaf3e8f2e74a21bc679cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:30 +0100 Subject: [PATCH 1107/1480] iio: pressure: st_pressure_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-177-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/st_pressure_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 58fede8618911..f2c3bb568d16b 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -76,8 +76,7 @@ static const struct i2c_device_id st_press_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, st_press_id_table); -static int st_press_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_press_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *press_data; @@ -117,7 +116,7 @@ static struct i2c_driver st_press_driver = { .of_match_table = st_press_of_match, .acpi_match_table = ACPI_PTR(st_press_acpi_match), }, - .probe = st_press_i2c_probe, + .probe_new = st_press_i2c_probe, .id_table = st_press_id_table, }; module_i2c_driver(st_press_driver); -- GitLab From aa9b3321735d42d3a2a2e58ce25be5586396c8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:31 +0100 Subject: [PATCH 1108/1480] iio: pressure: t5403: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-178-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/t5403.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/t5403.c b/drivers/iio/pressure/t5403.c index 685fcf65334fc..2fbf14aff0339 100644 --- a/drivers/iio/pressure/t5403.c +++ b/drivers/iio/pressure/t5403.c @@ -208,9 +208,9 @@ static const struct iio_info t5403_info = { .attrs = &t5403_attribute_group, }; -static int t5403_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int t5403_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct t5403_data *data; struct iio_dev *indio_dev; int ret; @@ -260,7 +260,7 @@ static struct i2c_driver t5403_driver = { .driver = { .name = "t5403", }, - .probe = t5403_probe, + .probe_new = t5403_probe, .id_table = t5403_id, }; module_i2c_driver(t5403_driver); -- GitLab From 1bee48f48a69013cdd5ed5fdbff1e0410a18a381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:32 +0100 Subject: [PATCH 1109/1480] iio: pressure: zpa2326_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-179-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/zpa2326_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index f26dd8cbb387c..ade465014be1e 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -38,9 +38,9 @@ static unsigned int zpa2326_i2c_hwid(const struct i2c_client *client) (ZPA2326_SA0(client->addr) << ZPA2326_DEVICE_ID_SA0_SHIFT)); } -static int zpa2326_probe_i2c(struct i2c_client *client, - const struct i2c_device_id *i2c_id) +static int zpa2326_probe_i2c(struct i2c_client *client) { + const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client); struct regmap *regmap; regmap = devm_regmap_init_i2c(client, &zpa2326_regmap_i2c_config); @@ -76,7 +76,7 @@ static struct i2c_driver zpa2326_i2c_driver = { .of_match_table = zpa2326_i2c_matches, .pm = ZPA2326_PM_OPS, }, - .probe = zpa2326_probe_i2c, + .probe_new = zpa2326_probe_i2c, .remove = zpa2326_remove_i2c, .id_table = zpa2326_i2c_ids, }; -- GitLab From 9d6f774dd4ff150ce7a5bb2bf64918b3b72cda11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:33 +0100 Subject: [PATCH 1110/1480] iio: proximity: isl29501: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-180-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/isl29501.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index 5b6ea783795d9..7b8f40b7ccf33 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -949,8 +949,7 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) return IRQ_HANDLED; } -static int isl29501_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29501_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct isl29501_private *isl29501; @@ -1009,7 +1008,7 @@ static struct i2c_driver isl29501_driver = { .name = "isl29501", }, .id_table = isl29501_id, - .probe = isl29501_probe, + .probe_new = isl29501_probe, }; module_i2c_driver(isl29501_driver); -- GitLab From 5c5c482e02bcd09bf113853b7520ad121dba081b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:34 +0100 Subject: [PATCH 1111/1480] iio: proximity: mb1232: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-181-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/mb1232.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/mb1232.c b/drivers/iio/proximity/mb1232.c index 0bca5f74de68a..e70cac8240afc 100644 --- a/drivers/iio/proximity/mb1232.c +++ b/drivers/iio/proximity/mb1232.c @@ -180,9 +180,9 @@ static const struct iio_info mb1232_info = { .read_raw = mb1232_read_raw, }; -static int mb1232_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mb1232_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mb1232_data *data; int ret; @@ -264,7 +264,7 @@ static struct i2c_driver mb1232_driver = { .name = "maxbotix-mb1232", .of_match_table = of_mb1232_match, }, - .probe = mb1232_probe, + .probe_new = mb1232_probe, .id_table = mb1232_id, }; module_i2c_driver(mb1232_driver); -- GitLab From 94c80ea7677c9d1886673a4f6764e19c5309b11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:35 +0100 Subject: [PATCH 1112/1480] iio: proximity: pulsedlight-lidar-lite-v2: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-182-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 791a33d5286c6..c9eead01a0314 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -253,8 +253,7 @@ static const struct iio_info lidar_info = { .read_raw = lidar_read_raw, }; -static int lidar_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lidar_probe(struct i2c_client *client) { struct lidar_data *data; struct iio_dev *indio_dev; @@ -366,7 +365,7 @@ static struct i2c_driver lidar_driver = { .of_match_table = lidar_dt_ids, .pm = pm_ptr(&lidar_pm_ops), }, - .probe = lidar_probe, + .probe_new = lidar_probe, .remove = lidar_remove, .id_table = lidar_id, }; -- GitLab From 576eb2b091084425eea6edd36d4407d139387d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:36 +0100 Subject: [PATCH 1113/1480] iio: proximity: rfd77402: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-183-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/rfd77402.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/rfd77402.c b/drivers/iio/proximity/rfd77402.c index cb80b3c9d0735..44f72b78bd506 100644 --- a/drivers/iio/proximity/rfd77402.c +++ b/drivers/iio/proximity/rfd77402.c @@ -257,8 +257,7 @@ static void rfd77402_disable(void *client) rfd77402_powerdown(client); } -static int rfd77402_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rfd77402_probe(struct i2c_client *client) { struct rfd77402_data *data; struct iio_dev *indio_dev; @@ -319,7 +318,7 @@ static struct i2c_driver rfd77402_driver = { .name = RFD77402_DRV_NAME, .pm = pm_sleep_ptr(&rfd77402_pm_ops), }, - .probe = rfd77402_probe, + .probe_new = rfd77402_probe, .id_table = rfd77402_id, }; -- GitLab From 038b0fac0abe2f5d9beee2511434f231a58f41fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:37 +0100 Subject: [PATCH 1114/1480] iio: proximity: srf08: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-184-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/srf08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c index 7ed11339c31e1..61866d0440f76 100644 --- a/drivers/iio/proximity/srf08.c +++ b/drivers/iio/proximity/srf08.c @@ -443,9 +443,9 @@ static const struct iio_info srf02_info = { .read_raw = srf08_read_raw, }; -static int srf08_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int srf08_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct srf08_data *data; int ret; @@ -549,7 +549,7 @@ static struct i2c_driver srf08_driver = { .name = "srf08", .of_match_table = of_srf08_match, }, - .probe = srf08_probe, + .probe_new = srf08_probe, .id_table = srf08_id, }; module_i2c_driver(srf08_driver); -- GitLab From 7660d32e6f9608b5bea7d066c74d63fc7666c510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:38 +0100 Subject: [PATCH 1115/1480] iio: proximity: sx9500: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-185-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9500.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index d4670864ddc7e..8794e75e5bf9c 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -901,8 +901,7 @@ static void sx9500_gpio_probe(struct i2c_client *client, } } -static int sx9500_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sx9500_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -1056,7 +1055,7 @@ static struct i2c_driver sx9500_driver = { .of_match_table = of_match_ptr(sx9500_of_match), .pm = pm_sleep_ptr(&sx9500_pm_ops), }, - .probe = sx9500_probe, + .probe_new = sx9500_probe, .remove = sx9500_remove, .id_table = sx9500_id, }; -- GitLab From 160c7140bb25a1921c4f3845bb15423721bcc0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:39 +0100 Subject: [PATCH 1116/1480] iio: temperature: mlx90614: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Crt Mori Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-186-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90614.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index 8eb0f962ed25c..909fadb623491 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -537,9 +537,9 @@ static int mlx90614_probe_num_ir_sensors(struct i2c_client *client) return (ret & MLX90614_CONFIG_DUAL_MASK) ? 1 : 0; } -static int mlx90614_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mlx90614_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mlx90614_data *data; int ret; @@ -675,7 +675,7 @@ static struct i2c_driver mlx90614_driver = { .of_match_table = mlx90614_of_match, .pm = pm_ptr(&mlx90614_pm_ops), }, - .probe = mlx90614_probe, + .probe_new = mlx90614_probe, .remove = mlx90614_remove, .id_table = mlx90614_id, }; -- GitLab From 40fbb59b9c132e401b7487ab2792e6dcd3f14809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:40 +0100 Subject: [PATCH 1117/1480] iio: temperature: mlx90632: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Crt Mori Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-187-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index f1f5ebc145b14..753b7a4ccfddc 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1168,9 +1168,9 @@ static int mlx90632_enable_regulator(struct mlx90632_data *data) return ret; } -static int mlx90632_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mlx90632_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mlx90632_data *mlx90632; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1337,7 +1337,7 @@ static struct i2c_driver mlx90632_driver = { .of_match_table = mlx90632_of_match, .pm = pm_ptr(&mlx90632_pm_ops), }, - .probe = mlx90632_probe, + .probe_new = mlx90632_probe, .id_table = mlx90632_id, }; module_i2c_driver(mlx90632_driver); -- GitLab From 89824f4cb65e7a7174cb24e4c0835e4c37f74a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:41 +0100 Subject: [PATCH 1118/1480] iio: temperature: tmp006: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-188-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tmp006.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 706a760f30b47..cdf08477e63f7 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -212,8 +212,7 @@ static void tmp006_powerdown_cleanup(void *dev) tmp006_power(dev, false); } -static int tmp006_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tmp006_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct tmp006_data *data; @@ -284,7 +283,7 @@ static struct i2c_driver tmp006_driver = { .name = "tmp006", .pm = pm_sleep_ptr(&tmp006_pm_ops), }, - .probe = tmp006_probe, + .probe_new = tmp006_probe, .id_table = tmp006_id, }; module_i2c_driver(tmp006_driver); -- GitLab From f1e7d53ddfc309149521a2812c3ffcd54eb67b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:42 +0100 Subject: [PATCH 1119/1480] iio: temperature: tmp007: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-189-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tmp007.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index f3420d8a0e359..8d27aa3bdd6da 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -446,9 +446,9 @@ static void tmp007_powerdown_action_cb(void *priv) tmp007_powerdown(data); } -static int tmp007_probe(struct i2c_client *client, - const struct i2c_device_id *tmp007_id) +static int tmp007_probe(struct i2c_client *client) { + const struct i2c_device_id *tmp007_id = i2c_client_get_device_id(client); struct tmp007_data *data; struct iio_dev *indio_dev; int ret; @@ -574,7 +574,7 @@ static struct i2c_driver tmp007_driver = { .of_match_table = tmp007_of_match, .pm = pm_sleep_ptr(&tmp007_pm_ops), }, - .probe = tmp007_probe, + .probe_new = tmp007_probe, .id_table = tmp007_id, }; module_i2c_driver(tmp007_driver); -- GitLab From d7c9422850aad0e57316f74c2f9cdfc18be39459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:43 +0100 Subject: [PATCH 1120/1480] iio: temperature: tsys01: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-190-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tsys01.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 60d58ec5b0636..30b268ba82ccf 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -176,8 +176,7 @@ static int tsys01_probe(struct iio_dev *indio_dev, struct device *dev) return devm_iio_device_register(dev, indio_dev); } -static int tsys01_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsys01_i2c_probe(struct i2c_client *client) { struct tsys01_dev *dev_data; struct iio_dev *indio_dev; @@ -219,7 +218,7 @@ static const struct of_device_id tsys01_of_match[] = { MODULE_DEVICE_TABLE(of, tsys01_of_match); static struct i2c_driver tsys01_driver = { - .probe = tsys01_i2c_probe, + .probe_new = tsys01_i2c_probe, .id_table = tsys01_id, .driver = { .name = "tsys01", -- GitLab From 6a9113195fff8e48d8898cdab82c96bb77780228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:38:44 +0100 Subject: [PATCH 1121/1480] iio: temperature: tsys02d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-191-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tsys02d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/temperature/tsys02d.c b/drivers/iio/temperature/tsys02d.c index 49c275e4f5106..cdefe046ab17d 100644 --- a/drivers/iio/temperature/tsys02d.c +++ b/drivers/iio/temperature/tsys02d.c @@ -121,9 +121,9 @@ static const struct iio_info tsys02d_info = { .attrs = &tsys02d_attribute_group, }; -static int tsys02d_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsys02d_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms_ht_dev *dev_data; struct iio_dev *indio_dev; int ret; @@ -174,7 +174,7 @@ static const struct i2c_device_id tsys02d_id[] = { MODULE_DEVICE_TABLE(i2c, tsys02d_id); static struct i2c_driver tsys02d_driver = { - .probe = tsys02d_probe, + .probe_new = tsys02d_probe, .id_table = tsys02d_id, .driver = { .name = "tsys02d", -- GitLab From 8282ef72a6e5e075f7f2f2f905b2a1adcc0bdcc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:00 +0100 Subject: [PATCH 1122/1480] staging: iio: adt7316: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-567-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/addac/adt7316-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 5543cc9097070..7e3d1a6f30ba9 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -93,9 +93,9 @@ static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) * device probe and remove */ -static int adt7316_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adt7316_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct adt7316_bus bus = { .client = client, .irq = client->irq, @@ -138,7 +138,7 @@ static struct i2c_driver adt7316_driver = { .of_match_table = adt7316_of_match, .pm = ADT7316_PM_OPS, }, - .probe = adt7316_i2c_probe, + .probe_new = adt7316_i2c_probe, .id_table = adt7316_i2c_id, }; module_i2c_driver(adt7316_driver); -- GitLab From 67ab4155b2391b7901c83c69a6dec97a4e0f709d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:01 +0100 Subject: [PATCH 1123/1480] staging: iio: ad5933: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-568-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/impedance-analyzer/ad5933.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index f177b20f0f2d9..b3152f7153fbb 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -674,9 +674,9 @@ static void ad5933_clk_disable(void *data) clk_disable_unprepare(st->mclk); } -static int ad5933_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad5933_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct ad5933_state *st; struct iio_dev *indio_dev; @@ -781,7 +781,7 @@ static struct i2c_driver ad5933_driver = { .name = "ad5933", .of_match_table = ad5933_of_match, }, - .probe = ad5933_probe, + .probe_new = ad5933_probe, .id_table = ad5933_id, }; module_i2c_driver(ad5933_driver); -- GitLab From 9fe1614f96af91ffd876da529cf9d667992e73a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:45:02 +0100 Subject: [PATCH 1124/1480] staging: iio: ade7854: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221118224540.619276-569-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7854-i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 71b67dd3c8e98..572d714eb0ddb 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -112,8 +112,7 @@ unlock: return ret; } -static int ade7854_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ade7854_i2c_probe(struct i2c_client *client) { struct ade7854_state *st; struct iio_dev *indio_dev; @@ -144,7 +143,7 @@ static struct i2c_driver ade7854_i2c_driver = { .driver = { .name = "ade7854", }, - .probe = ade7854_i2c_probe, + .probe_new = ade7854_i2c_probe, .id_table = ade7854_id, }; module_i2c_driver(ade7854_i2c_driver); -- GitLab From 9ee95ae4cffd04e0773f16118b343104bab80634 Mon Sep 17 00:00:00 2001 From: Rajat Khandelwal Date: Tue, 22 Nov 2022 23:23:00 +0530 Subject: [PATCH 1125/1480] iio: temperature: Add driver support for Maxim MAX30208 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maxim MAX30208 is a digital temperature sensor with 0.1°C accuracy. Add support for max30208 driver in iio subsystem. Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX30208.pdf Signed-off-by: Rajat Khandelwal Link: https://lore.kernel.org/r/20221122175300.800956-1-rajat.khandelwal@linux.intel.com Signed-off-by: Jonathan Cameron --- MAINTAINERS | 6 + drivers/iio/temperature/Kconfig | 10 ++ drivers/iio/temperature/Makefile | 1 + drivers/iio/temperature/max30208.c | 252 +++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+) create mode 100644 drivers/iio/temperature/max30208.c diff --git a/MAINTAINERS b/MAINTAINERS index be373dfae4dd4..f1e1ac23a1c66 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12518,6 +12518,12 @@ S: Maintained F: Documentation/devicetree/bindings/regulator/maxim,max20086.yaml F: drivers/regulator/max20086-regulator.c +MAXIM MAX30208 TEMPERATURE SENSOR DRIVER +M: Rajat Khandelwal +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/temperature/max30208.c + MAXIM MAX77650 PMIC MFD DRIVER M: Bartosz Golaszewski L: linux-kernel@vger.kernel.org diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig index e8ed849e3b766..ed384f33e0c76 100644 --- a/drivers/iio/temperature/Kconfig +++ b/drivers/iio/temperature/Kconfig @@ -128,6 +128,16 @@ config TSYS02D This driver can also be built as a module. If so, the module will be called tsys02d. +config MAX30208 + tristate "Maxim MAX30208 digital temperature sensor" + depends on I2C + help + If you say yes here you get support for Maxim MAX30208 + digital temperature sensor connected via I2C. + + This driver can also be built as a module. If so, the module + will be called max30208. + config MAX31856 tristate "MAX31856 thermocouple sensor" depends on SPI diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile index dd08e562ffe0e..dfec8c6d30193 100644 --- a/drivers/iio/temperature/Makefile +++ b/drivers/iio/temperature/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_IQS620AT_TEMP) += iqs620at-temp.o obj-$(CONFIG_LTC2983) += ltc2983.o obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o +obj-$(CONFIG_MAX30208) += max30208.o obj-$(CONFIG_MAX31856) += max31856.o obj-$(CONFIG_MAX31865) += max31865.o obj-$(CONFIG_MLX90614) += mlx90614.o diff --git a/drivers/iio/temperature/max30208.c b/drivers/iio/temperature/max30208.c new file mode 100644 index 0000000000000..c85c21474711f --- /dev/null +++ b/drivers/iio/temperature/max30208.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) Rajat Khandelwal + * + * Maxim MAX30208 digital temperature sensor with 0.1°C accuracy + * (7-bit I2C slave address (0x50 - 0x53)) + */ + +#include +#include +#include +#include +#include +#include + +#define MAX30208_STATUS 0x00 +#define MAX30208_STATUS_TEMP_RDY BIT(0) +#define MAX30208_INT_ENABLE 0x01 +#define MAX30208_INT_ENABLE_TEMP_RDY BIT(0) + +#define MAX30208_FIFO_OVF_CNTR 0x06 +#define MAX30208_FIFO_DATA_CNTR 0x07 +#define MAX30208_FIFO_DATA 0x08 + +#define MAX30208_FIFO_CONFIG 0x0a +#define MAX30208_FIFO_CONFIG_RO BIT(1) + +#define MAX30208_SYSTEM_CTRL 0x0c +#define MAX30208_SYSTEM_CTRL_RESET 0x01 + +#define MAX30208_TEMP_SENSOR_SETUP 0x14 +#define MAX30208_TEMP_SENSOR_SETUP_CONV BIT(0) + +struct max30208_data { + struct i2c_client *client; + struct iio_dev *indio_dev; + struct mutex lock; /* Lock to prevent concurrent reads of temperature readings */ +}; + +static const struct iio_chan_spec max30208_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +/** + * max30208_request() - Request a reading + * @data: Struct comprising member elements of the device + * + * Requests a reading from the device and waits until the conversion is ready. + */ +static int max30208_request(struct max30208_data *data) +{ + /* + * Sensor can take up to 500 ms to respond so execute a total of + * 10 retries to give the device sufficient time. + */ + int retries = 10; + u8 regval; + int ret; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP); + if (ret < 0) + return ret; + + regval = ret | MAX30208_TEMP_SENSOR_SETUP_CONV; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP, regval); + if (ret) + return ret; + + while (retries--) { + ret = i2c_smbus_read_byte_data(data->client, MAX30208_STATUS); + if (ret < 0) + return ret; + + if (ret & MAX30208_STATUS_TEMP_RDY) + return 0; + + msleep(50); + } + dev_err(&data->client->dev, "Temperature conversion failed\n"); + + return -ETIMEDOUT; +} + +static int max30208_update_temp(struct max30208_data *data) +{ + u8 data_count; + int ret; + + mutex_lock(&data->lock); + + ret = max30208_request(data); + if (ret) + goto unlock; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_OVF_CNTR); + if (ret < 0) + goto unlock; + else if (!ret) { + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_DATA_CNTR); + if (ret < 0) + goto unlock; + + data_count = ret; + } else + data_count = 1; + + while (data_count) { + ret = i2c_smbus_read_word_swapped(data->client, MAX30208_FIFO_DATA); + if (ret < 0) + goto unlock; + + data_count--; + } + +unlock: + mutex_unlock(&data->lock); + return ret; +} + +/** + * max30208_config_setup() - Set up FIFO configuration register + * @data: Struct comprising member elements of the device + * + * Sets the rollover bit to '1' to enable overwriting FIFO during overflow. + */ +static int max30208_config_setup(struct max30208_data *data) +{ + u8 regval; + int ret; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_CONFIG); + if (ret < 0) + return ret; + + regval = ret | MAX30208_FIFO_CONFIG_RO; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_FIFO_CONFIG, regval); + if (ret) + return ret; + + return 0; +} + +static int max30208_read(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max30208_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = max30208_update_temp(data); + if (ret < 0) + return ret; + + *val = sign_extend32(ret, 15); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 5; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static const struct iio_info max30208_info = { + .read_raw = max30208_read, +}; + +static int max30208_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct max30208_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = i2c; + mutex_init(&data->lock); + + indio_dev->name = "max30208"; + indio_dev->channels = max30208_channels; + indio_dev->num_channels = ARRAY_SIZE(max30208_channels); + indio_dev->info = &max30208_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_SYSTEM_CTRL, + MAX30208_SYSTEM_CTRL_RESET); + if (ret) { + dev_err(dev, "Failure in performing reset\n"); + return ret; + } + + msleep(50); + + ret = max30208_config_setup(data); + if (ret) + return ret; + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) { + dev_err(dev, "Failed to register IIO device\n"); + return ret; + } + + return 0; +} + +static const struct i2c_device_id max30208_id_table[] = { + { "max30208" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max30208_id_table); + +static const struct acpi_device_id max30208_acpi_match[] = { + { "MAX30208" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, max30208_acpi_match); + +static const struct of_device_id max30208_of_match[] = { + { .compatible = "maxim,max30208" }, + { } +}; +MODULE_DEVICE_TABLE(of, max30208_of_match); + +static struct i2c_driver max30208_driver = { + .driver = { + .name = "max30208", + .of_match_table = max30208_of_match, + .acpi_match_table = max30208_acpi_match, + }, + .probe_new = max30208_probe, + .id_table = max30208_id_table, +}; +module_i2c_driver(max30208_driver); + +MODULE_AUTHOR("Rajat Khandelwal "); +MODULE_DESCRIPTION("Maxim MAX30208 digital temperature sensor"); +MODULE_LICENSE("GPL"); -- GitLab From 1140f96cd4af9bcf0065b0295c4486e1dba8426e Mon Sep 17 00:00:00 2001 From: Edmund Berenson Date: Tue, 22 Nov 2022 17:14:37 +0100 Subject: [PATCH 1126/1480] dt-bindings: iio: adc: ad7923: adjust documentation - The ad7927 is fully compatible with ad7928 driver, add documentation for device. - ad7923 and ad7924 are treated the same in the driver, show the relationship in the documentation. Suggested-by: Lukasz Zemla Signed-off-by: Edmund Berenson Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221122161437.18937-1-edmund.berenson@emlix.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/adi,ad7923.yaml | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7923.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7923.yaml index 07f9d1c09c7da..85148338c597c 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7923.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7923.yaml @@ -11,7 +11,7 @@ maintainers: description: | Analog Devices AD7904, AD7914, AD7923, AD7924 4 Channel ADCs, and AD7908, - AD7918, AD7928 8 Channels ADCs. + AD7918, AD7927, AD7928 8 Channels ADCs. Specifications about the part can be found at: https://www.analog.com/media/en/technical-documentation/data-sheets/AD7923.pdf @@ -20,14 +20,22 @@ description: | properties: compatible: - enum: - - adi,ad7904 - - adi,ad7914 - - adi,ad7923 - - adi,ad7924 - - adi,ad7908 - - adi,ad7918 - - adi,ad7928 + oneOf: + - enum: + - adi,ad7904 + - adi,ad7908 + - adi,ad7914 + - adi,ad7918 + - adi,ad7923 + - adi,ad7928 + - const: adi,ad7924 + deprecated: true + - items: + - const: adi,ad7924 + - const: adi,ad7923 + - items: + - const: adi,ad7927 + - const: adi,ad7928 reg: maxItems: 1 -- GitLab From 99b43a15915543484d7538cb32f49901e802628a Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Tue, 22 Nov 2022 14:47:18 +0300 Subject: [PATCH 1127/1480] iio: adc: max11410: fix incomplete vref buffer mask VREFP bit was missing from channel configuration mask and VREFN bit was included twice instead which fails to enable positive reference buffer when requested by a channel. Channels that don't enable vrefp buffer were not affected. Fixes: a44ef7c46097 ("iio: adc: add max11410 adc driver") Reported-by: kernel test robot Reported-by: Julia Lawall Signed-off-by: Ibrahim Tilki Link: https://lore.kernel.org/r/20221122114718.17557-1-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max11410.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c index 8cd5663671874..fdc9f03135b54 100644 --- a/drivers/iio/adc/max11410.c +++ b/drivers/iio/adc/max11410.c @@ -370,7 +370,7 @@ static int max11410_configure_channel(struct max11410_state *st, FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, MAX11410_CTRL_REFSEL_MASK | - MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_VREFP_BUF_BIT | MAX11410_CTRL_VREFN_BUF_BIT | MAX11410_CTRL_UNIPOLAR_BIT, regval); if (ret) -- GitLab From 99c05e4283a19a02a256f14100ca4ec3b2da3f62 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:49 +0200 Subject: [PATCH 1128/1480] iio: adis: add '__adis_enable_irq()' implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add '__adis_enable_irq()' implementation which is the unlocked version of 'adis_enable_irq()'. Call '__adis_enable_irq()' instead of 'adis_enable_irq()' from '__adis_intial_startup()' to keep the expected unlocked functionality. This fix is needed to remove a deadlock for all devices which are using 'adis_initial_startup()'. The deadlock occurs because the same mutex is acquired twice, without releasing it. The mutex is acquired once inside 'adis_initial_startup()', before calling '__adis_initial_startup()', and once inside 'adis_enable_irq()', which is called by '__adis_initial_startup()'. The deadlock is removed by calling '__adis_enable_irq()', instead of 'adis_enable_irq()' from within '__adis_initial_startup()'. Fixes: b600bd7eb3335 ("iio: adis: do not disabe IRQs in 'adis_init()'") Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-2-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis.c | 28 ++++++++++------------------ include/linux/iio/imu/adis.h | 13 ++++++++++++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index f7fcfd04f659d..bc40240b29e26 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -270,23 +270,19 @@ EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB); #endif /** - * adis_enable_irq() - Enable or disable data ready IRQ + * __adis_enable_irq() - Enable or disable data ready IRQ (unlocked) * @adis: The adis device * @enable: Whether to enable the IRQ * * Returns 0 on success, negative error code otherwise */ -int adis_enable_irq(struct adis *adis, bool enable) +int __adis_enable_irq(struct adis *adis, bool enable) { - int ret = 0; + int ret; u16 msc; - mutex_lock(&adis->state_lock); - - if (adis->data->enable_irq) { - ret = adis->data->enable_irq(adis, enable); - goto out_unlock; - } + if (adis->data->enable_irq) + return adis->data->enable_irq(adis, enable); if (adis->data->unmasked_drdy) { if (enable) @@ -294,12 +290,12 @@ int adis_enable_irq(struct adis *adis, bool enable) else disable_irq(adis->spi->irq); - goto out_unlock; + return 0; } ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); if (ret) - goto out_unlock; + return ret; msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH; msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2; @@ -308,13 +304,9 @@ int adis_enable_irq(struct adis *adis, bool enable) else msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN; - ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); - -out_unlock: - mutex_unlock(&adis->state_lock); - return ret; + return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); } -EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB); +EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB); /** * __adis_check_status() - Check the device for error conditions (unlocked) @@ -445,7 +437,7 @@ int __adis_initial_startup(struct adis *adis) * with 'IRQF_NO_AUTOEN' anyways. */ if (!adis->data->unmasked_drdy) - adis_enable_irq(adis, false); + __adis_enable_irq(adis, false); if (!adis->data->prod_id_reg) return 0; diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 515ca09764fe4..bcbefb7574751 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -402,9 +402,20 @@ static inline int adis_update_bits_base(struct adis *adis, unsigned int reg, __adis_update_bits_base(adis, reg, mask, val, sizeof(val)); \ }) -int adis_enable_irq(struct adis *adis, bool enable); int __adis_check_status(struct adis *adis); int __adis_initial_startup(struct adis *adis); +int __adis_enable_irq(struct adis *adis, bool enable); + +static inline int adis_enable_irq(struct adis *adis, bool enable) +{ + int ret; + + mutex_lock(&adis->state_lock); + ret = __adis_enable_irq(adis, enable); + mutex_unlock(&adis->state_lock); + + return ret; +} static inline int adis_check_status(struct adis *adis) { -- GitLab From 594ff4c49e9dd7aba84d82052643c1e4b09b8788 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:50 +0200 Subject: [PATCH 1129/1480] iio: accel: adis16201: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16201_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-3-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adis16201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index dfb8e2e5bdf58..d054721859b3b 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -281,7 +281,7 @@ static int adis16201_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- GitLab From 09f8360f3a8843733d9e54960405c902982062f4 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:51 +0200 Subject: [PATCH 1130/1480] iio: accel: adis16209: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16209_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-4-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adis16209.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 5a9c6e2296f1d..0035e4f4db63f 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -291,7 +291,7 @@ static int adis16209_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- GitLab From c5de7d4c026f4c4310e6cb1e06e1ae0bd57cd838 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:52 +0200 Subject: [PATCH 1131/1480] iio: gyro: adis16136: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16136_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-5-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16136.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 71295709f2b96..c95cf41be34b6 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -429,7 +429,7 @@ static int adis16136_initial_setup(struct iio_dev *indio_dev) uint16_t prod_id; int ret; - ret = adis_initial_startup(&adis16136->adis); + ret = __adis_initial_startup(&adis16136->adis); if (ret) return ret; -- GitLab From 2647f0e4d397fa5f80c78370d514b05a2110f987 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:53 +0200 Subject: [PATCH 1132/1480] iio: gyro: adis16260: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16260_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-6-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16260.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index eaf57bd339edd..112d635b7dfd3 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -395,7 +395,7 @@ static int adis16260_probe(struct spi_device *spi) return ret; /* Get the device into a sane initial state */ - ret = adis_initial_startup(&adis16260->adis); + ret = __adis_initial_startup(&adis16260->adis); if (ret) return ret; -- GitLab From 40fd61b0698c1ecf73f8da61b461937b7d91ee26 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:54 +0200 Subject: [PATCH 1133/1480] iio: imu: adis16400: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16400_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-7-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis16400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 17bb0c40a1495..c02fc35dceb40 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -445,7 +445,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) st->adis.spi->mode = SPI_MODE_3; spi_setup(st->adis.spi); - ret = adis_initial_startup(&st->adis); + ret = __adis_initial_startup(&st->adis); if (ret) return ret; -- GitLab From f3b0ab42a875d3c4b05311bd1ebcc0322a55c30c Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:55 +0200 Subject: [PATCH 1134/1480] staging: iio: accel: adis16203: Call '__adis_initial_startup()' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16203_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-8-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16203.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index 62d5397ff1f98..c0e4c9266b5f4 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -285,7 +285,7 @@ static int adis16203_probe(struct spi_device *spi) return ret; /* Get the device into a sane initial state */ - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- GitLab From 60105b59cc12813267b922fa5969e38f9e8f9b50 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:56 +0200 Subject: [PATCH 1135/1480] staging: iio: accel: adis16240: Call '__adis_initial_startup()' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16240_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-9-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16240.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index bca857eef92e2..337492785f04c 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -414,7 +414,7 @@ static int adis16240_probe(struct spi_device *spi) return ret; /* Get the device into a sane initial state */ - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- GitLab From c613afc1f257e1e3229b8dcade43a104a26541c8 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:57 +0200 Subject: [PATCH 1136/1480] iio: imu: adis: Remove adis_initial_startup function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove adis_initial_startup function since it is not used anymore. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-10-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- include/linux/iio/imu/adis.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index bcbefb7574751..dc9ea299e0885 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -428,18 +428,6 @@ static inline int adis_check_status(struct adis *adis) return ret; } -/* locked version of __adis_initial_startup() */ -static inline int adis_initial_startup(struct adis *adis) -{ - int ret; - - mutex_lock(&adis->state_lock); - ret = __adis_initial_startup(adis); - mutex_unlock(&adis->state_lock); - - return ret; -} - static inline void adis_dev_lock(struct adis *adis) { mutex_lock(&adis->state_lock); -- GitLab From 8aa2e715ca65757e0eb625862491f95e8baf0328 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Tue, 22 Nov 2022 09:35:33 +0800 Subject: [PATCH 1137/1480] iio: use devm_platform_get_and_ioremap_resource() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Minghao Chi Signed-off-by: ye xingchen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/202211220935338446115@zte.com.cn Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7606_par.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index b912b4df9b563..d8408052262e4 100644 --- a/drivers/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -57,8 +57,7 @@ static int ad7606_par_probe(struct platform_device *pdev) if (irq < 0) return irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - addr = devm_ioremap_resource(&pdev->dev, res); + addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(addr)) return PTR_ERR(addr); -- GitLab From 980389d06d08442fad0139874bff455c76125e47 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 18 Nov 2022 13:32:08 +0100 Subject: [PATCH 1138/1480] iio: addac: ad74413r: fix integer promotion bug in ad74413_get_input_current_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The constant AD74413R_ADC_RESULT_MAX is defined via GENMASK, so its type is "unsigned long". Hence in the expression voltage_offset * AD74413R_ADC_RESULT_MAX, voltage_offset is first promoted to unsigned long, and since it may be negative, that results in a garbage value. For example, when range is AD74413R_ADC_RANGE_5V_BI_DIR, voltage_offset is -2500 and voltage_range is 5000, so the RHS of this assignment is, depending on sizeof(long), either 826225UL or 3689348814709142UL, which after truncation to int then results in either 826225 or 1972216214 being the output from in_currentX_offset. Casting to int avoids that promotion and results in the correct -32767 output. Signed-off-by: Rasmus Villemoes Fixes: fea251b6a5db (iio: addac: add AD74413R driver) Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221118123209.1658420-1-linux@rasmusvillemoes.dk Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 899bcd83f40bc..e0e130ba9d3ec 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -691,7 +691,7 @@ static int ad74413_get_input_current_offset(struct ad74413r_state *st, if (ret) return ret; - *val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range; + *val = voltage_offset * (int)AD74413R_ADC_RESULT_MAX / voltage_range; return IIO_VAL_INT; } -- GitLab From 0e69ba0dd56700b173100984f8a89fe4605591a5 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 17 Nov 2022 10:09:15 +0200 Subject: [PATCH 1139/1480] dt-bindings: iio: addac: add AD74115 The AD74115H is a single-channel, software-configurable, input and output device for industrial control applications. The AD74115H provides a wide range of use cases, integrated on a single chip. These use cases include analog output, analog input, digital output, digital input, resistance temperature detector (RTD), and thermocouple measurement capability. The AD74115H also has an integrated HART modem. A serial peripheral interface (SPI) is used to handle all communications to the device, including communications with the HART modem. The digital input and digital outputs can be accessed via the SPI or the general-purpose input and output (GPIO) pins to support higher speed data rates. The device features a 16-bit, sigma-delta analog-to-digital converter (ADC) and a 14-bit digital-to-analog converter (DAC). The AD74115H contains a high accuracy 2.5 V on-chip reference that can be used as the DAC and ADC reference. Signed-off-by: Cosmin Tanislav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20221117080916.411766-2-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/addac/adi,ad74115.yaml | 373 ++++++++++++++++++ MAINTAINERS | 7 + 2 files changed, 380 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml diff --git a/Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml b/Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml new file mode 100644 index 0000000000000..72d2e910f2065 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml @@ -0,0 +1,373 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/addac/adi,ad74115.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD74115H device + +maintainers: + - Cosmin Tanislav + +description: | + The AD74115H is a single-channel software configurable input/output + device for industrial control applications. It contains functionality for + analog output, analog input, digital output, digital input, resistance + temperature detector, and thermocouple measurements integrated into a single + chip solution with an SPI interface. The device features a 16-bit ADC and a + 14-bit DAC. + + https://www.analog.com/en/products/ad74115h.html + +properties: + compatible: + enum: + - adi,ad74115h + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 24000000 + + spi-cpol: true + + reset-gpios: true + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - adc_rdy + - alert + + avdd-supply: true + avcc-supply: true + dvcc-supply: true + dovdd-supply: true + refin-supply: true + + adi,ch-func: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Channel function. + 0 - High impedance + 1 - Voltage output + 2 - Current output + 3 - Voltage input + 4 - Current input, externally-powered + 5 - Current input, loop-powered + 6 - Resistance input + 7 - RTD measure + 8 - Digital input logic + 9 - Digital input, loop-powered + 10 - Current output with HART + 11 - Current input, externally-powered, with HART + 12 - Current input, loop-powered, with HART + minimum: 0 + maximum: 12 + default: 0 + + adi,conv2-mux: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Input node for ADC conversion 2. + 0 - SENSE_EXT1 to AGND_SENSE + 1 - SENSE_EXT2 to AGND_SENSE + 2 - SENSE_EXT2 to SENSE_EXT1 + 3 - AGND to AGND + minimum: 0 + maximum: 3 + default: 0 + + adi,conv2-range-microvolt: + description: Conversion range for ADC conversion 2. + oneOf: + - items: + - enum: [-2500000, 0] + - const: 2500000 + - items: + - enum: [-12000000, 0] + - const: 12000000 + - items: + - const: -2500000 + - const: 0 + - items: + - const: -104000 + - const: 104000 + - items: + - const: 0 + - const: 625000 + + adi,sense-agnd-buffer-low-power: + type: boolean + description: + Whether to enable low-power buffered mode for the AGND sense pin. + + adi,lf-buffer-low-power: + type: boolean + description: + Whether to enable low-power buffered mode for the low-side filtered + sense pin. + + adi,hf-buffer-low-power: + type: boolean + description: + Whether to enable low-power buffered mode for the high-side filtered + sense pin. + + adi,ext2-buffer-low-power: + type: boolean + description: Whether to enable low-power buffered mode for the EXT2 pin. + + adi,ext1-buffer-low-power: + type: boolean + description: Whether to enable low-power buffered mode for the EXT1 pin. + + adi,comparator-invert: + type: boolean + description: Whether to invert the comparator output. + + adi,digital-input-sink-range-high: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + When not present, the digital input range is from 0 to 3700uA in steps + of 120uA, with a ~2k series resistance. + When present, the digital input range is from 0 to 7400uA in steps + of 240uA, with a ~1k series resistance. + + adi,digital-input-sink-microamp: + description: Sink current in digital input mode. + minimum: 0 + maximum: 3700 + default: 0 + + adi,digital-input-debounce-mode-counter-reset: + type: boolean + description: | + When not present, a counter increments when the signal is asserted + and decrements when the signal is de-asserted. + When present, a counter increments while the signal is asserted and + resets when the signal de-asserts + + adi,digital-input-unbuffered: + type: boolean + description: Whether to buffer digital input signals. + + adi,digital-input-short-circuit-detection: + type: boolean + description: Whether to detect digital input short circuits. + + adi,digital-input-open-circuit-detection: + type: boolean + description: Whether to detect digital input open circuits. + + adi,digital-input-threshold-mode-fixed: + type: boolean + description: | + When not present, the digital input threshold range is -0.96 * AVDD + to AVDD. + When present, the threshold range is fixed from -19V to 30V. + + adi,dac-bipolar: + type: boolean + description: | + When not present, the DAC operates in the 0V to 12V range. + When present, the DAC operates in the -12V to 12V range. + + adi,charge-pump: + type: boolean + description: Whether to enable the internal charge pump. + + adi,dac-hart-slew: + type: boolean + description: Whether to use a HART-compatible slew rate. + + adi,dac-current-limit-low: + type: boolean + description: | + When not present, the DAC short-circuit current limit is 32mA in + either source or sink for VOUT and 4mA sink for IOUT. + When present, the limit is 16mA in either source or sink for VOUT, + 1mA sink for IOUT. + + adi,4-wire-rtd: + type: boolean + description: | + When not present, the ADC should be used for measuring 3-wire RTDs. + When present, the ADC should be used for measuring 4-wire RTDs. + + adi,3-wire-rtd-excitation-swap: + type: boolean + description: Whether to swap the excitation for 3-wire RTD. + + adi,rtd-excitation-current-microamp: + description: Excitation current to apply to RTD. + enum: [250, 500, 750, 1000] + default: 250 + + adi,ext1-burnout: + type: boolean + description: Whether to enable burnout current for EXT1. + + adi,ext1-burnout-current-nanoamp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Burnout current in nanoamps to be applied to EXT1. + enum: [0, 50, 500, 1000, 10000] + default: 0 + + adi,ext1-burnout-current-polarity-sourcing: + type: boolean + description: | + When not present, the burnout current polarity for EXT1 is sinking. + When present, the burnout current polarity for EXT1 is sourcing. + + adi,ext2-burnout: + type: boolean + description: Whether to enable burnout current for EXT2. + + adi,ext2-burnout-current-nanoamp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Burnout current in nanoamps to be applied to EXT2. + enum: [0, 50, 500, 1000, 10000] + default: 0 + + adi,ext2-burnout-current-polarity-sourcing: + type: boolean + description: | + When not present, the burnout current polarity for EXT2 is sinking. + When present, the burnout current polarity for EXT2 is sourcing. + + adi,viout-burnout: + type: boolean + description: Whether to enable burnout current for VIOUT. + + adi,viout-burnout-current-nanoamp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Burnout current in nanoamps to be applied to VIOUT. + enum: [0, 1000, 10000] + default: 0 + + adi,viout-burnout-current-polarity-sourcing: + type: boolean + description: | + When not present, the burnout current polarity for VIOUT is sinking. + When present, the burnout current polarity for VIOUT is sourcing. + + adi,gpio0-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + GPIO functions. + 0 - Disabled + 1 - Logic I/O + 2 - Comparator output + 3 - Control HART CD + 4 - Monitor HART CD + 5 - Monitor HART EOM status + minimum: 0 + maximum: 5 + default: 0 + + adi,gpio1-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + GPIO functions. + 0 - Disabled + 1 - Logic I/O + 2 - Drive external digital output FET + 3 - Control HART RXD + 4 - Monitor HART RXD + 5 - Monitor HART SOM status + minimum: 0 + maximum: 5 + default: 0 + + adi,gpio2-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + GPIO functions. + 0 - Disabled + 1 - Logic I/O + 2 - Drive internal digital output FET + 3 - Control HART TXD + 4 - Monitor HART TXD + 5 - Monitor HART TX complete status + minimum: 0 + maximum: 5 + default: 0 + + adi,gpio3-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + GPIO functions. + 0 - Disabled + 1 - Logic I/O + 2 - High impedance + 3 - Control HART RTS + 4 - Monitor HART RTS + 5 - Monitor HART CD complete status + minimum: 0 + maximum: 5 + default: 0 + +required: + - compatible + - reg + - spi-cpol + - avdd-supply + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - if: + required: + - adi,digital-input-sink-range-high + then: + properties: + adi,digital-input-sink-microamp: + maximum: 7400 + +unevaluatedProperties: false + +examples: + - | + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + addac@0 { + compatible = "adi,ad74115h"; + reg = <0>; + + spi-max-frequency = <12000000>; + spi-cpol; + + reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + + interrupt-parent = <&gpio>; + interrupts = <26 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "adc_rdy"; + + avdd-supply = <&ad74115_avdd>; + + adi,ch-func = <1>; + adi,conv2-mux = <2>; + adi,conv2-range-microvolt = <(-12000000) 12000000>; + + adi,gpio0-mode = <1>; + adi,gpio1-mode = <1>; + adi,gpio2-mode = <1>; + adi,gpio3-mode = <1>; + + adi,dac-bipolar; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index f1e1ac23a1c66..d1ba33eb0ceca 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1175,6 +1175,13 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml F: drivers/iio/adc/ad7780.c +ANALOG DEVICES INC AD74115 DRIVER +M: Cosmin Tanislav +L: linux-iio@vger.kernel.org +S: Supported +W: http://ez.analog.com/community/linux-device-drivers +F: Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml + ANALOG DEVICES INC AD74413R DRIVER M: Cosmin Tanislav L: linux-iio@vger.kernel.org -- GitLab From 48ea75598db2b38e4a4b5738d65f226be717bd59 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 17 Nov 2022 10:09:16 +0200 Subject: [PATCH 1140/1480] iio: addac: add AD74115 driver The AD74115H is a single-channel, software-configurable, input and output device for industrial control applications. The AD74115H provides a wide range of use cases, integrated on a single chip. These use cases include analog output, analog input, digital output, digital input, resistance temperature detector (RTD), and thermocouple measurement capability. The AD74115H also has an integrated HART modem. A serial peripheral interface (SPI) is used to handle all communications to the device, including communications with the HART modem. The digital input and digital outputs can be accessed via the SPI or the general-purpose input and output (GPIO) pins to support higher speed data rates. The device features a 16-bit, sigma-delta analog-to-digital converter (ADC) and a 14-bit digital-to-analog converter (DAC). The AD74115H contains a high accuracy 2.5 V on-chip reference that can be used as the DAC and ADC reference. Signed-off-by: Cosmin Tanislav Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20221117080916.411766-3-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- MAINTAINERS | 1 + drivers/iio/addac/Kconfig | 14 + drivers/iio/addac/Makefile | 1 + drivers/iio/addac/ad74115.c | 1947 +++++++++++++++++++++++++++++++++++ 4 files changed, 1963 insertions(+) create mode 100644 drivers/iio/addac/ad74115.c diff --git a/MAINTAINERS b/MAINTAINERS index d1ba33eb0ceca..860075c493dd2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1181,6 +1181,7 @@ L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers F: Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml +F: drivers/iio/addac/ad74115.c ANALOG DEVICES INC AD74413R DRIVER M: Cosmin Tanislav diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig index fcf6d2269bfc2..2843fcb70e24b 100644 --- a/drivers/iio/addac/Kconfig +++ b/drivers/iio/addac/Kconfig @@ -5,6 +5,20 @@ menu "Analog to digital and digital to analog converters" +config AD74115 + tristate "Analog Devices AD74115H driver" + depends on GPIOLIB && SPI + select CRC8 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select REGMAP_SPI + help + Say yes here to build support for Analog Devices AD74115H + single-channel software configurable input/output solution. + + To compile this driver as a module, choose M here: the + module will be called ad74115. + config AD74413R tristate "Analog Devices AD74412R/AD74413R driver" depends on GPIOLIB && SPI diff --git a/drivers/iio/addac/Makefile b/drivers/iio/addac/Makefile index 17de20ef0d8e9..577777276e439 100644 --- a/drivers/iio/addac/Makefile +++ b/drivers/iio/addac/Makefile @@ -4,5 +4,6 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_AD74115) += ad74115.o obj-$(CONFIG_AD74413R) += ad74413r.o obj-$(CONFIG_STX104) += stx104.o diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c new file mode 100644 index 0000000000000..383b92e7b6826 --- /dev/null +++ b/drivers/iio/addac/ad74115.c @@ -0,0 +1,1947 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Analog Devices, Inc. + * Author: Cosmin Tanislav + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define AD74115_NAME "ad74115" + +#define AD74115_CH_FUNC_SETUP_REG 0x01 + +#define AD74115_ADC_CONFIG_REG 0x02 +#define AD74115_ADC_CONFIG_CONV2_RATE_MASK GENMASK(15, 13) +#define AD74115_ADC_CONFIG_CONV1_RATE_MASK GENMASK(12, 10) +#define AD74115_ADC_CONFIG_CONV2_RANGE_MASK GENMASK(9, 7) +#define AD74115_ADC_CONFIG_CONV1_RANGE_MASK GENMASK(6, 4) + +#define AD74115_PWR_OPTIM_CONFIG_REG 0x03 + +#define AD74115_DIN_CONFIG1_REG 0x04 +#define AD74115_DIN_COMPARATOR_EN_MASK BIT(13) +#define AD74115_DIN_SINK_MASK GENMASK(11, 7) +#define AD74115_DIN_DEBOUNCE_MASK GENMASK(4, 0) + +#define AD74115_DIN_CONFIG2_REG 0x05 +#define AD74115_COMP_THRESH_MASK GENMASK(6, 0) + +#define AD74115_OUTPUT_CONFIG_REG 0x06 +#define AD74115_OUTPUT_SLEW_EN_MASK GENMASK(6, 5) +#define AD74115_OUTPUT_SLEW_LIN_STEP_MASK GENMASK(4, 3) +#define AD74115_OUTPUT_SLEW_LIN_RATE_MASK GENMASK(2, 1) + +#define AD74115_RTD3W4W_CONFIG_REG 0x07 + +#define AD74115_BURNOUT_CONFIG_REG 0x0a +#define AD74115_BURNOUT_EXT2_EN_MASK BIT(10) +#define AD74115_BURNOUT_EXT1_EN_MASK BIT(5) +#define AD74115_BURNOUT_VIOUT_EN_MASK BIT(0) + +#define AD74115_DAC_CODE_REG 0x0b + +#define AD74115_DAC_ACTIVE_REG 0x0d + +#define AD74115_GPIO_CONFIG_X_REG(x) (0x35 + (x)) +#define AD74115_GPIO_CONFIG_GPI_DATA BIT(5) +#define AD74115_GPIO_CONFIG_GPO_DATA BIT(4) +#define AD74115_GPIO_CONFIG_SELECT_MASK GENMASK(2, 0) + +#define AD74115_CHARGE_PUMP_REG 0x3a + +#define AD74115_ADC_CONV_CTRL_REG 0x3b +#define AD74115_ADC_CONV_SEQ_MASK GENMASK(13, 12) + +#define AD74115_DIN_COMP_OUT_REG 0x40 + +#define AD74115_LIVE_STATUS_REG 0x42 +#define AD74115_ADC_DATA_RDY_MASK BIT(3) + +#define AD74115_READ_SELECT_REG 0x64 + +#define AD74115_CMD_KEY_REG 0x78 +#define AD74115_CMD_KEY_RESET1 0x15fa +#define AD74115_CMD_KEY_RESET2 0xaf51 + +#define AD74115_CRC_POLYNOMIAL 0x7 +DECLARE_CRC8_TABLE(ad74115_crc8_table); + +#define AD74115_ADC_CODE_MAX ((int)GENMASK(15, 0)) +#define AD74115_ADC_CODE_HALF (AD74115_ADC_CODE_MAX / 2) + +#define AD74115_DAC_VOLTAGE_MAX 12000 +#define AD74115_DAC_CURRENT_MAX 25 +#define AD74115_DAC_CODE_MAX ((int)GENMASK(13, 0)) +#define AD74115_DAC_CODE_HALF (AD74115_DAC_CODE_MAX / 2) + +#define AD74115_COMP_THRESH_MAX 98 + +#define AD74115_SENSE_RESISTOR_OHMS 100 +#define AD74115_REF_RESISTOR_OHMS 2100 + +#define AD74115_DIN_SINK_LOW_STEP 120 +#define AD74115_DIN_SINK_HIGH_STEP 240 +#define AD74115_DIN_SINK_MAX 31 + +#define AD74115_FRAME_SIZE 4 +#define AD74115_GPIO_NUM 4 + +#define AD74115_CONV_TIME_US 1000000 + +enum ad74115_dac_ch { + AD74115_DAC_CH_MAIN, + AD74115_DAC_CH_COMPARATOR, +}; + +enum ad74115_adc_ch { + AD74115_ADC_CH_CONV1, + AD74115_ADC_CH_CONV2, + AD74115_ADC_CH_NUM +}; + +enum ad74115_ch_func { + AD74115_CH_FUNC_HIGH_IMPEDANCE, + AD74115_CH_FUNC_VOLTAGE_OUTPUT, + AD74115_CH_FUNC_CURRENT_OUTPUT, + AD74115_CH_FUNC_VOLTAGE_INPUT, + AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER, + AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER, + AD74115_CH_FUNC_2_WIRE_RESISTANCE_INPUT, + AD74115_CH_FUNC_3_4_WIRE_RESISTANCE_INPUT, + AD74115_CH_FUNC_DIGITAL_INPUT_LOGIC, + AD74115_CH_FUNC_DIGITAL_INPUT_LOOP_POWER, + AD74115_CH_FUNC_CURRENT_OUTPUT_HART, + AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER_HART, + AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART, + AD74115_CH_FUNC_MAX = AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART, + AD74115_CH_FUNC_NUM +}; + +enum ad74115_adc_range { + AD74115_ADC_RANGE_12V, + AD74115_ADC_RANGE_12V_BIPOLAR, + AD74115_ADC_RANGE_2_5V_BIPOLAR, + AD74115_ADC_RANGE_2_5V_NEG, + AD74115_ADC_RANGE_2_5V, + AD74115_ADC_RANGE_0_625V, + AD74115_ADC_RANGE_104MV_BIPOLAR, + AD74115_ADC_RANGE_12V_OTHER, + AD74115_ADC_RANGE_MAX = AD74115_ADC_RANGE_12V_OTHER, + AD74115_ADC_RANGE_NUM +}; + +enum ad74115_adc_conv_seq { + AD74115_ADC_CONV_SEQ_STANDBY = 0b00, + AD74115_ADC_CONV_SEQ_SINGLE = 0b01, + AD74115_ADC_CONV_SEQ_CONTINUOUS = 0b10, +}; + +enum ad74115_din_threshold_mode { + AD74115_DIN_THRESHOLD_MODE_AVDD, + AD74115_DIN_THRESHOLD_MODE_FIXED, + AD74115_DIN_THRESHOLD_MODE_MAX = AD74115_DIN_THRESHOLD_MODE_FIXED, +}; + +enum ad74115_slew_mode { + AD74115_SLEW_MODE_DISABLED, + AD74115_SLEW_MODE_LINEAR, + AD74115_SLEW_MODE_HART, +}; + +enum ad74115_slew_step { + AD74115_SLEW_STEP_0_8_PERCENT, + AD74115_SLEW_STEP_1_5_PERCENT, + AD74115_SLEW_STEP_6_1_PERCENT, + AD74115_SLEW_STEP_22_2_PERCENT, +}; + +enum ad74115_slew_rate { + AD74115_SLEW_RATE_4KHZ, + AD74115_SLEW_RATE_64KHZ, + AD74115_SLEW_RATE_150KHZ, + AD74115_SLEW_RATE_240KHZ, +}; + +enum ad74115_gpio_config { + AD74115_GPIO_CONFIG_OUTPUT_BUFFERED = 0b010, + AD74115_GPIO_CONFIG_INPUT = 0b011, +}; + +enum ad74115_gpio_mode { + AD74115_GPIO_MODE_LOGIC = 1, + AD74115_GPIO_MODE_SPECIAL = 2, +}; + +struct ad74115_channels { + struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +struct ad74115_state { + struct spi_device *spi; + struct regmap *regmap; + struct iio_trigger *trig; + struct regulator *avdd; + + /* + * Synchronize consecutive operations when doing a one-shot + * conversion and when updating the ADC samples SPI message. + */ + struct mutex lock; + struct gpio_chip gc; + struct gpio_chip comp_gc; + int irq; + + unsigned int avdd_mv; + unsigned long gpio_valid_mask; + bool dac_bipolar; + bool dac_hart_slew; + bool rtd_mode_4_wire; + enum ad74115_ch_func ch_func; + enum ad74115_din_threshold_mode din_threshold_mode; + + struct completion adc_data_completion; + struct spi_message adc_samples_msg; + struct spi_transfer adc_samples_xfer[AD74115_ADC_CH_NUM + 1]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 reg_tx_buf[AD74115_FRAME_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 reg_rx_buf[AD74115_FRAME_SIZE]; + u8 adc_samples_tx_buf[AD74115_FRAME_SIZE * AD74115_ADC_CH_NUM]; + u8 adc_samples_rx_buf[AD74115_FRAME_SIZE * AD74115_ADC_CH_NUM]; +}; + +struct ad74115_fw_prop { + const char *name; + bool is_boolean; + bool negate; + unsigned int max; + unsigned int reg; + unsigned int mask; + const unsigned int *lookup_tbl; + unsigned int lookup_tbl_len; +}; + +#define AD74115_FW_PROP(_name, _max, _reg, _mask) \ +{ \ + .name = (_name), \ + .max = (_max), \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +#define AD74115_FW_PROP_TBL(_name, _tbl, _reg, _mask) \ +{ \ + .name = (_name), \ + .reg = (_reg), \ + .mask = (_mask), \ + .lookup_tbl = (_tbl), \ + .lookup_tbl_len = ARRAY_SIZE(_tbl), \ +} + +#define AD74115_FW_PROP_BOOL(_name, _reg, _mask) \ +{ \ + .name = (_name), \ + .is_boolean = true, \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +#define AD74115_FW_PROP_BOOL_NEG(_name, _reg, _mask) \ +{ \ + .name = (_name), \ + .is_boolean = true, \ + .negate = true, \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +static const int ad74115_dac_rate_tbl[] = { + 0, + 4 * 8, + 4 * 15, + 4 * 61, + 4 * 222, + 64 * 8, + 64 * 15, + 64 * 61, + 64 * 222, + 150 * 8, + 150 * 15, + 150 * 61, + 150 * 222, + 240 * 8, + 240 * 15, + 240 * 61, + 240 * 222, +}; + +static const unsigned int ad74115_dac_rate_step_tbl[][3] = { + { AD74115_SLEW_MODE_DISABLED }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_240KHZ }, +}; + +static const unsigned int ad74115_dac_slew_rate_hz_tbl[] = { + 4000, 64000, 150000, 240000 +}; + +static const unsigned int ad74115_rtd_excitation_current_ua_tbl[] = { + 250, 500, 750, 1000 +}; + +static const unsigned int ad74115_burnout_current_na_tbl[] = { + 0, 50, 0, 500, 1000, 0, 10000, 0 +}; + +static const unsigned int ad74115_viout_burnout_current_na_tbl[] = { + 0, 0, 0, 0, 1000, 0, 10000, 0 +}; + +static const unsigned int ad74115_gpio_mode_tbl[] = { + 0, 0, 0, 1, 2, 3, 4, 5 +}; + +static const unsigned int ad74115_adc_conv_rate_tbl[] = { + 10, 20, 1200, 4800, 9600 +}; + +static const unsigned int ad74115_debounce_tbl[] = { + 0, 13, 18, 24, 32, 42, 56, 75, + 100, 130, 180, 240, 320, 420, 560, 750, + 1000, 1300, 1800, 2400, 3200, 4200, 5600, 7500, + 10000, 13000, 18000, 24000, 32000, 42000, 56000, 75000, +}; + +static const unsigned int ad74115_adc_ch_data_regs_tbl[] = { + [AD74115_ADC_CH_CONV1] = 0x44, + [AD74115_ADC_CH_CONV2] = 0x46, +}; + +static const unsigned int ad74115_adc_ch_en_bit_tbl[] = { + [AD74115_ADC_CH_CONV1] = BIT(0), + [AD74115_ADC_CH_CONV2] = BIT(1), +}; + +static const bool ad74115_adc_bipolar_tbl[AD74115_ADC_RANGE_NUM] = { + [AD74115_ADC_RANGE_12V_BIPOLAR] = true, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = true, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = true, +}; + +static const unsigned int ad74115_adc_conv_mul_tbl[AD74115_ADC_RANGE_NUM] = { + [AD74115_ADC_RANGE_12V] = 12000, + [AD74115_ADC_RANGE_12V_BIPOLAR] = 24000, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = 5000, + [AD74115_ADC_RANGE_2_5V_NEG] = 2500, + [AD74115_ADC_RANGE_2_5V] = 2500, + [AD74115_ADC_RANGE_0_625V] = 625, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = 208, + [AD74115_ADC_RANGE_12V_OTHER] = 12000, +}; + +static const unsigned int ad74115_adc_gain_tbl[AD74115_ADC_RANGE_NUM][2] = { + [AD74115_ADC_RANGE_12V] = { 5, 24 }, + [AD74115_ADC_RANGE_12V_BIPOLAR] = { 5, 24 }, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = { 1, 1 }, + [AD74115_ADC_RANGE_2_5V_NEG] = { 1, 1 }, + [AD74115_ADC_RANGE_2_5V] = { 1, 1 }, + [AD74115_ADC_RANGE_0_625V] = { 4, 1 }, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = { 24, 1 }, + [AD74115_ADC_RANGE_12V_OTHER] = { 5, 24 }, +}; + +static const int ad74115_adc_range_tbl[AD74115_ADC_RANGE_NUM][2] = { + [AD74115_ADC_RANGE_12V] = { 0, 12000000 }, + [AD74115_ADC_RANGE_12V_BIPOLAR] = { -12000000, 12000000 }, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = { -2500000, 2500000 }, + [AD74115_ADC_RANGE_2_5V_NEG] = { -2500000, 0 }, + [AD74115_ADC_RANGE_2_5V] = { 0, 2500000 }, + [AD74115_ADC_RANGE_0_625V] = { 0, 625000 }, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = { -104000, 104000 }, + [AD74115_ADC_RANGE_12V_OTHER] = { 0, 12000000 }, +}; + +static int _ad74115_find_tbl_index(const unsigned int *tbl, unsigned int tbl_len, + unsigned int val, unsigned int *index) +{ + unsigned int i; + + for (i = 0; i < tbl_len; i++) + if (val == tbl[i]) { + *index = i; + return 0; + } + + return -EINVAL; +} + +#define ad74115_find_tbl_index(tbl, val, index) \ + _ad74115_find_tbl_index(tbl, ARRAY_SIZE(tbl), val, index) + +static int ad74115_crc(u8 *buf) +{ + return crc8(ad74115_crc8_table, buf, 3, 0); +} + +static void ad74115_format_reg_write(u8 reg, u16 val, u8 *buf) +{ + buf[0] = reg; + put_unaligned_be16(val, &buf[1]); + buf[3] = ad74115_crc(buf); +} + +static int ad74115_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct ad74115_state *st = context; + + ad74115_format_reg_write(reg, val, st->reg_tx_buf); + + return spi_write(st->spi, st->reg_tx_buf, AD74115_FRAME_SIZE); +} + +static int ad74115_crc_check(struct ad74115_state *st, u8 *buf) +{ + struct device *dev = &st->spi->dev; + u8 expected_crc = ad74115_crc(buf); + + if (buf[3] != expected_crc) { + dev_err(dev, "Bad CRC %02x for %02x%02x%02x, expected %02x\n", + buf[3], buf[0], buf[1], buf[2], expected_crc); + return -EINVAL; + } + + return 0; +} + +static int ad74115_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct ad74115_state *st = context; + struct spi_transfer reg_read_xfer[] = { + { + .tx_buf = st->reg_tx_buf, + .len = sizeof(st->reg_tx_buf), + .cs_change = 1, + }, + { + .rx_buf = st->reg_rx_buf, + .len = sizeof(st->reg_rx_buf), + }, + }; + int ret; + + ad74115_format_reg_write(AD74115_READ_SELECT_REG, reg, st->reg_tx_buf); + + ret = spi_sync_transfer(st->spi, reg_read_xfer, ARRAY_SIZE(reg_read_xfer)); + if (ret) + return ret; + + ret = ad74115_crc_check(st, st->reg_rx_buf); + if (ret) + return ret; + + *val = get_unaligned_be16(&st->reg_rx_buf[1]); + + return 0; +} + +static const struct regmap_config ad74115_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_read = ad74115_reg_read, + .reg_write = ad74115_reg_write, +}; + +static int ad74115_gpio_config_set(struct ad74115_state *st, unsigned int offset, + enum ad74115_gpio_config cfg) +{ + return regmap_update_bits(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), + AD74115_GPIO_CONFIG_SELECT_MASK, + FIELD_PREP(AD74115_GPIO_CONFIG_SELECT_MASK, cfg)); +} + +static int ad74115_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + *valid_mask = st->gpio_valid_mask; + + return 0; +} + +static int ad74115_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), &val); + if (ret) + return ret; + + return FIELD_GET(AD74115_GPIO_CONFIG_SELECT_MASK, val) == AD74115_GPIO_CONFIG_INPUT; +} + +static int ad74115_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + return ad74115_gpio_config_set(st, offset, AD74115_GPIO_CONFIG_INPUT); +} + +static int ad74115_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + return ad74115_gpio_config_set(st, offset, AD74115_GPIO_CONFIG_OUTPUT_BUFFERED); +} + +static int ad74115_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), &val); + if (ret) + return ret; + + return FIELD_GET(AD74115_GPIO_CONFIG_GPI_DATA, val); +} + +static void ad74115_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + struct device *dev = &st->spi->dev; + int ret; + + ret = regmap_update_bits(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), + AD74115_GPIO_CONFIG_GPO_DATA, + FIELD_PREP(AD74115_GPIO_CONFIG_GPO_DATA, value)); + if (ret) + dev_err(dev, "Failed to set GPIO %u output value, err: %d\n", + offset, ret); +} + +static int ad74115_set_comp_debounce(struct ad74115_state *st, unsigned int val) +{ + unsigned int len = ARRAY_SIZE(ad74115_debounce_tbl); + unsigned int i; + + for (i = 0; i < len; i++) + if (val <= ad74115_debounce_tbl[i]) + break; + + if (i == len) + i = len - 1; + + return regmap_update_bits(st->regmap, AD74115_DIN_CONFIG1_REG, + AD74115_DIN_DEBOUNCE_MASK, + FIELD_PREP(AD74115_DIN_DEBOUNCE_MASK, val)); +} + +static int ad74115_comp_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + return GPIO_LINE_DIRECTION_IN; +} + +static int ad74115_comp_gpio_set_config(struct gpio_chip *chip, + unsigned int offset, + unsigned long config) +{ + struct ad74115_state *st = gpiochip_get_data(chip); + u32 param = pinconf_to_config_param(config); + u32 arg = pinconf_to_config_argument(config); + + switch (param) { + case PIN_CONFIG_INPUT_DEBOUNCE: + return ad74115_set_comp_debounce(st, arg); + default: + return -ENOTSUPP; + } +} + +static int ad74115_comp_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(chip); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_DIN_COMP_OUT_REG, &val); + if (ret) + return ret; + + return !!val; +} + +static irqreturn_t ad74115_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + ret = spi_sync(st->spi, &st->adc_samples_msg); + if (ret) + goto out; + + iio_push_to_buffers(indio_dev, st->adc_samples_rx_buf); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static irqreturn_t ad74115_adc_data_interrupt(int irq, void *data) +{ + struct iio_dev *indio_dev = data; + struct ad74115_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll(st->trig); + else + complete(&st->adc_data_completion); + + return IRQ_HANDLED; +} + +static int ad74115_set_adc_ch_en(struct ad74115_state *st, + enum ad74115_adc_ch channel, bool status) +{ + unsigned int mask = ad74115_adc_ch_en_bit_tbl[channel]; + + return regmap_update_bits(st->regmap, AD74115_ADC_CONV_CTRL_REG, mask, + status ? mask : 0); +} + +static int ad74115_set_adc_conv_seq(struct ad74115_state *st, + enum ad74115_adc_conv_seq conv_seq) +{ + return regmap_update_bits(st->regmap, AD74115_ADC_CONV_CTRL_REG, + AD74115_ADC_CONV_SEQ_MASK, + FIELD_PREP(AD74115_ADC_CONV_SEQ_MASK, conv_seq)); +} + +static int ad74115_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct spi_transfer *xfer = st->adc_samples_xfer; + u8 *rx_buf = st->adc_samples_rx_buf; + u8 *tx_buf = st->adc_samples_tx_buf; + unsigned int i; + int ret = 0; + + mutex_lock(&st->lock); + + spi_message_init(&st->adc_samples_msg); + + for_each_clear_bit(i, active_scan_mask, AD74115_ADC_CH_NUM) { + ret = ad74115_set_adc_ch_en(st, i, false); + if (ret) + goto out; + } + + /* + * The read select register is used to select which register's value + * will be sent by the slave on the next SPI frame. + * + * Create an SPI message that, on each step, writes to the read select + * register to select the ADC result of the next enabled channel, and + * reads the ADC result of the previous enabled channel. + * + * Example: + * W: [WCH1] [WCH2] [WCH2] [WCH3] [ ] + * R: [ ] [RCH1] [RCH2] [RCH3] [RCH4] + */ + for_each_set_bit(i, active_scan_mask, AD74115_ADC_CH_NUM) { + ret = ad74115_set_adc_ch_en(st, i, true); + if (ret) + goto out; + + if (xfer == st->adc_samples_xfer) + xfer->rx_buf = NULL; + else + xfer->rx_buf = rx_buf; + + xfer->tx_buf = tx_buf; + xfer->len = AD74115_FRAME_SIZE; + xfer->cs_change = 1; + + ad74115_format_reg_write(AD74115_READ_SELECT_REG, + ad74115_adc_ch_data_regs_tbl[i], tx_buf); + + spi_message_add_tail(xfer, &st->adc_samples_msg); + + tx_buf += AD74115_FRAME_SIZE; + if (xfer != st->adc_samples_xfer) + rx_buf += AD74115_FRAME_SIZE; + xfer++; + } + + xfer->rx_buf = rx_buf; + xfer->tx_buf = NULL; + xfer->len = AD74115_FRAME_SIZE; + xfer->cs_change = 0; + + spi_message_add_tail(xfer, &st->adc_samples_msg); + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad74115_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + return ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_CONTINUOUS); +} + +static int ad74115_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + unsigned int i; + int ret; + + mutex_lock(&st->lock); + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_STANDBY); + if (ret) + goto out; + + /* + * update_scan_mode() is not called in the disable path, disable all + * channels here. + */ + for (i = 0; i < AD74115_ADC_CH_NUM; i++) { + ret = ad74115_set_adc_ch_en(st, i, false); + if (ret) + goto out; + } + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_buffer_setup_ops ad74115_buffer_ops = { + .postenable = &ad74115_buffer_postenable, + .predisable = &ad74115_buffer_predisable, +}; + +static const struct iio_trigger_ops ad74115_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static int ad74115_get_adc_rate(struct ad74115_state *st, + enum ad74115_adc_ch channel, int *val) +{ + unsigned int i; + int ret; + + ret = regmap_read(st->regmap, AD74115_ADC_CONFIG_REG, &i); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + i = FIELD_GET(AD74115_ADC_CONFIG_CONV1_RATE_MASK, i); + else + i = FIELD_GET(AD74115_ADC_CONFIG_CONV2_RATE_MASK, i); + + *val = ad74115_adc_conv_rate_tbl[i]; + + return IIO_VAL_INT; +} + +static int _ad74115_get_adc_code(struct ad74115_state *st, + enum ad74115_adc_ch channel, int *val) +{ + unsigned int uval; + int ret; + + reinit_completion(&st->adc_data_completion); + + ret = ad74115_set_adc_ch_en(st, channel, true); + if (ret) + return ret; + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_SINGLE); + if (ret) + return ret; + + if (st->irq) { + ret = wait_for_completion_timeout(&st->adc_data_completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + } else { + unsigned int regval, wait_time; + int rate; + + ret = ad74115_get_adc_rate(st, channel, &rate); + if (ret < 0) + return ret; + + wait_time = DIV_ROUND_CLOSEST(AD74115_CONV_TIME_US, rate); + + ret = regmap_read_poll_timeout(st->regmap, AD74115_LIVE_STATUS_REG, + regval, regval & AD74115_ADC_DATA_RDY_MASK, + wait_time, 5 * wait_time); + if (ret) + return ret; + + /* + * The ADC_DATA_RDY bit is W1C. + * See datasheet page 98, Table 62. Bit Descriptions for + * LIVE_STATUS. + * Although the datasheet mentions that the bit will auto-clear + * when writing to the ADC_CONV_CTRL register, this does not + * seem to happen. + */ + ret = regmap_write_bits(st->regmap, AD74115_LIVE_STATUS_REG, + AD74115_ADC_DATA_RDY_MASK, + FIELD_PREP(AD74115_ADC_DATA_RDY_MASK, 1)); + if (ret) + return ret; + } + + ret = regmap_read(st->regmap, ad74115_adc_ch_data_regs_tbl[channel], &uval); + if (ret) + return ret; + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_STANDBY); + if (ret) + return ret; + + ret = ad74115_set_adc_ch_en(st, channel, false); + if (ret) + return ret; + + *val = uval; + + return IIO_VAL_INT; +} + +static int ad74115_get_adc_code(struct iio_dev *indio_dev, + enum ad74115_adc_ch channel, int *val) +{ + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + ret = _ad74115_get_adc_code(st, channel, val); + mutex_unlock(&st->lock); + + iio_device_release_direct_mode(indio_dev); + + return ret; +} + +static int ad74115_adc_code_to_resistance(int code, int *val, int *val2) +{ + if (code == AD74115_ADC_CODE_MAX) + code--; + + *val = code * AD74115_REF_RESISTOR_OHMS; + *val2 = AD74115_ADC_CODE_MAX - code; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_set_dac_code(struct ad74115_state *st, + enum ad74115_dac_ch channel, int val) +{ + if (val < 0) + return -EINVAL; + + if (channel == AD74115_DAC_CH_COMPARATOR) { + if (val > AD74115_COMP_THRESH_MAX) + return -EINVAL; + + return regmap_update_bits(st->regmap, AD74115_DIN_CONFIG2_REG, + AD74115_COMP_THRESH_MASK, + FIELD_PREP(AD74115_COMP_THRESH_MASK, val)); + } + + if (val > AD74115_DAC_CODE_MAX) + return -EINVAL; + + return regmap_write(st->regmap, AD74115_DAC_CODE_REG, val); +} + +static int ad74115_get_dac_code(struct ad74115_state *st, + enum ad74115_dac_ch channel, int *val) +{ + unsigned int uval; + int ret; + + if (channel == AD74115_DAC_CH_COMPARATOR) + return -EINVAL; + + ret = regmap_read(st->regmap, AD74115_DAC_ACTIVE_REG, &uval); + if (ret) + return ret; + + *val = uval; + + return IIO_VAL_INT; +} + +static int ad74115_set_adc_rate(struct ad74115_state *st, + enum ad74115_adc_ch channel, int val) +{ + unsigned int i; + int ret; + + ret = ad74115_find_tbl_index(ad74115_adc_conv_rate_tbl, val, &i); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV1_RATE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV1_RATE_MASK, i)); + + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV2_RATE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV2_RATE_MASK, i)); +} + +static int ad74115_get_dac_rate(struct ad74115_state *st, int *val) +{ + unsigned int i, en_val, step_val, rate_val, tmp; + int ret; + + ret = regmap_read(st->regmap, AD74115_OUTPUT_CONFIG_REG, &tmp); + if (ret) + return ret; + + en_val = FIELD_GET(AD74115_OUTPUT_SLEW_EN_MASK, tmp); + step_val = FIELD_GET(AD74115_OUTPUT_SLEW_LIN_STEP_MASK, tmp); + rate_val = FIELD_GET(AD74115_OUTPUT_SLEW_LIN_RATE_MASK, tmp); + + for (i = 0; i < ARRAY_SIZE(ad74115_dac_rate_step_tbl); i++) + if (en_val == ad74115_dac_rate_step_tbl[i][0] && + step_val == ad74115_dac_rate_step_tbl[i][1] && + rate_val == ad74115_dac_rate_step_tbl[i][2]) + break; + + if (i == ARRAY_SIZE(ad74115_dac_rate_step_tbl)) + return -EINVAL; + + *val = ad74115_dac_rate_tbl[i]; + + return IIO_VAL_INT; +} + +static int ad74115_set_dac_rate(struct ad74115_state *st, int val) +{ + unsigned int i, en_val, step_val, rate_val, mask, tmp; + int ret; + + ret = ad74115_find_tbl_index(ad74115_dac_rate_tbl, val, &i); + if (ret) + return ret; + + en_val = ad74115_dac_rate_step_tbl[i][0]; + step_val = ad74115_dac_rate_step_tbl[i][1]; + rate_val = ad74115_dac_rate_step_tbl[i][2]; + + mask = AD74115_OUTPUT_SLEW_EN_MASK; + mask |= AD74115_OUTPUT_SLEW_LIN_STEP_MASK; + mask |= AD74115_OUTPUT_SLEW_LIN_RATE_MASK; + + tmp = FIELD_PREP(AD74115_OUTPUT_SLEW_EN_MASK, en_val); + tmp |= FIELD_PREP(AD74115_OUTPUT_SLEW_LIN_STEP_MASK, step_val); + tmp |= FIELD_PREP(AD74115_OUTPUT_SLEW_LIN_RATE_MASK, rate_val); + + return regmap_update_bits(st->regmap, AD74115_OUTPUT_CONFIG_REG, mask, tmp); +} + +static int ad74115_get_dac_scale(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + if (chan->channel == AD74115_DAC_CH_MAIN) { + if (chan->type == IIO_VOLTAGE) { + *val = AD74115_DAC_VOLTAGE_MAX; + + if (st->dac_bipolar) + *val *= 2; + + } else { + *val = AD74115_DAC_CURRENT_MAX; + } + + *val2 = AD74115_DAC_CODE_MAX; + } else { + if (st->din_threshold_mode == AD74115_DIN_THRESHOLD_MODE_AVDD) { + *val = 196 * st->avdd_mv; + *val2 = 10 * AD74115_COMP_THRESH_MAX; + } else { + *val = 49000; + *val2 = AD74115_COMP_THRESH_MAX; + } + } + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_dac_offset(struct ad74115_state *st, + struct iio_chan_spec const *chan, int *val) +{ + if (chan->channel == AD74115_DAC_CH_MAIN) { + if (chan->type == IIO_VOLTAGE && st->dac_bipolar) + *val = -AD74115_DAC_CODE_HALF; + else + *val = 0; + } else { + if (st->din_threshold_mode == AD74115_DIN_THRESHOLD_MODE_AVDD) + *val = -48; + else + *val = -38; + } + + return IIO_VAL_INT; +} + +static int ad74115_get_adc_range(struct ad74115_state *st, + enum ad74115_adc_ch channel, unsigned int *val) +{ + int ret; + + ret = regmap_read(st->regmap, AD74115_ADC_CONFIG_REG, val); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + *val = FIELD_GET(AD74115_ADC_CONFIG_CONV1_RANGE_MASK, *val); + else + *val = FIELD_GET(AD74115_ADC_CONFIG_CONV2_RANGE_MASK, *val); + + return 0; +} + +static int ad74115_get_adc_resistance_scale(struct ad74115_state *st, + unsigned int range, + int *val, int *val2) +{ + *val = ad74115_adc_gain_tbl[range][1] * AD74115_REF_RESISTOR_OHMS; + *val2 = ad74115_adc_gain_tbl[range][0]; + + if (ad74115_adc_bipolar_tbl[range]) + *val2 *= AD74115_ADC_CODE_HALF; + else + *val2 *= AD74115_ADC_CODE_MAX; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_scale(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + unsigned int range; + int ret; + + ret = ad74115_get_adc_range(st, chan->channel, &range); + if (ret) + return ret; + + if (chan->type == IIO_RESISTANCE) + return ad74115_get_adc_resistance_scale(st, range, val, val2); + + *val = ad74115_adc_conv_mul_tbl[range]; + *val2 = AD74115_ADC_CODE_MAX; + + if (chan->type == IIO_CURRENT) + *val2 *= AD74115_SENSE_RESISTOR_OHMS; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_resistance_offset(struct ad74115_state *st, + unsigned int range, + int *val, int *val2) +{ + unsigned int d = 10 * AD74115_REF_RESISTOR_OHMS + * ad74115_adc_gain_tbl[range][1]; + + *val = 5; + + if (ad74115_adc_bipolar_tbl[range]) + *val -= AD74115_ADC_CODE_HALF; + + *val *= d; + + if (!st->rtd_mode_4_wire) { + /* Add 0.2 Ohm to the final result for 3-wire RTD. */ + unsigned int v = 2 * ad74115_adc_gain_tbl[range][0]; + + if (ad74115_adc_bipolar_tbl[range]) + v *= AD74115_ADC_CODE_HALF; + else + v *= AD74115_ADC_CODE_MAX; + + *val += v; + } + + *val2 = d; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_offset(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + unsigned int range; + int ret; + + ret = ad74115_get_adc_range(st, chan->channel, &range); + if (ret) + return ret; + + if (chan->type == IIO_RESISTANCE) + return ad74115_get_adc_resistance_offset(st, range, val, val2); + + if (ad74115_adc_bipolar_tbl[range]) + *val = -AD74115_ADC_CODE_HALF; + else if (range == AD74115_ADC_RANGE_2_5V_NEG) + *val = -AD74115_ADC_CODE_MAX; + else + *val = 0; + + return IIO_VAL_INT; +} + +static int ad74115_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (chan->output) + return ad74115_get_dac_code(st, chan->channel, val); + + return ad74115_get_adc_code(indio_dev, chan->channel, val); + case IIO_CHAN_INFO_PROCESSED: + ret = ad74115_get_adc_code(indio_dev, chan->channel, val); + if (ret) + return ret; + + return ad74115_adc_code_to_resistance(*val, val, val2); + case IIO_CHAN_INFO_SCALE: + if (chan->output) + return ad74115_get_dac_scale(st, chan, val, val2); + + return ad74115_get_adc_scale(st, chan, val, val2); + case IIO_CHAN_INFO_OFFSET: + if (chan->output) + return ad74115_get_dac_offset(st, chan, val); + + return ad74115_get_adc_offset(st, chan, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) + return ad74115_get_dac_rate(st, val); + + return ad74115_get_adc_rate(st, chan->channel, val); + default: + return -EINVAL; + } +} + +static int ad74115_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long info) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (!chan->output) + return -EINVAL; + + return ad74115_set_dac_code(st, chan->channel, val); + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) + return ad74115_set_dac_rate(st, val); + + return ad74115_set_adc_rate(st, chan->channel, val); + default: + return -EINVAL; + } +} + +static int ad74115_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, long info) +{ + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) { + *vals = ad74115_dac_rate_tbl; + *length = ARRAY_SIZE(ad74115_dac_rate_tbl); + } else { + *vals = ad74115_adc_conv_rate_tbl; + *length = ARRAY_SIZE(ad74115_adc_conv_rate_tbl); + } + + *type = IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad74115_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static const struct iio_info ad74115_info = { + .read_raw = ad74115_read_raw, + .write_raw = ad74115_write_raw, + .read_avail = ad74115_read_avail, + .update_scan_mode = ad74115_update_scan_mode, + .debugfs_reg_access = ad74115_reg_access, +}; + +#define AD74115_DAC_CHANNEL(_type, index) \ + { \ + .type = (_type), \ + .channel = (index), \ + .indexed = 1, \ + .output = 1, \ + .scan_index = -1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET), \ + } + +#define _AD74115_ADC_CHANNEL(_type, index, extra_mask_separate) \ + { \ + .type = (_type), \ + .channel = (index), \ + .indexed = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SAMP_FREQ) \ + | (extra_mask_separate), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 32, \ + .shift = 8, \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD74115_ADC_CHANNEL(_type, index) \ + _AD74115_ADC_CHANNEL(_type, index, BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET)) + +static struct iio_chan_spec ad74115_voltage_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_voltage_output_channels[] = { + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_MAIN), + AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_current_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_current_output_channels[] = { + AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_2_wire_resistance_input_channels[] = { + _AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1, + BIT(IIO_CHAN_INFO_PROCESSED)), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_3_4_wire_resistance_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_digital_input_logic_channels[] = { + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_digital_input_loop_channels[] = { + AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +#define _AD74115_CHANNELS(_channels) \ + { \ + .channels = _channels, \ + .num_channels = ARRAY_SIZE(_channels), \ + } + +#define AD74115_CHANNELS(name) \ + _AD74115_CHANNELS(ad74115_ ## name ## _channels) + +static const struct ad74115_channels ad74115_channels_map[AD74115_CH_FUNC_NUM] = { + [AD74115_CH_FUNC_HIGH_IMPEDANCE] = AD74115_CHANNELS(voltage_input), + [AD74115_CH_FUNC_VOLTAGE_INPUT] = AD74115_CHANNELS(voltage_input), + + [AD74115_CH_FUNC_VOLTAGE_OUTPUT] = AD74115_CHANNELS(voltage_output), + + [AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER_HART] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART] = AD74115_CHANNELS(current_input), + + [AD74115_CH_FUNC_CURRENT_OUTPUT] = AD74115_CHANNELS(current_output), + [AD74115_CH_FUNC_CURRENT_OUTPUT_HART] = AD74115_CHANNELS(current_output), + + [AD74115_CH_FUNC_2_WIRE_RESISTANCE_INPUT] = AD74115_CHANNELS(2_wire_resistance_input), + [AD74115_CH_FUNC_3_4_WIRE_RESISTANCE_INPUT] = AD74115_CHANNELS(3_4_wire_resistance_input), + + [AD74115_CH_FUNC_DIGITAL_INPUT_LOGIC] = AD74115_CHANNELS(digital_input_logic), + + [AD74115_CH_FUNC_DIGITAL_INPUT_LOOP_POWER] = AD74115_CHANNELS(digital_input_loop), +}; + +#define AD74115_GPIO_MODE_FW_PROP(i) \ +{ \ + .name = "adi,gpio" __stringify(i) "-mode", \ + .reg = AD74115_GPIO_CONFIG_X_REG(i), \ + .mask = AD74115_GPIO_CONFIG_SELECT_MASK, \ + .lookup_tbl = ad74115_gpio_mode_tbl, \ + .lookup_tbl_len = ARRAY_SIZE(ad74115_gpio_mode_tbl), \ +} + +static const struct ad74115_fw_prop ad74115_gpio_mode_fw_props[] = { + AD74115_GPIO_MODE_FW_PROP(0), + AD74115_GPIO_MODE_FW_PROP(1), + AD74115_GPIO_MODE_FW_PROP(2), + AD74115_GPIO_MODE_FW_PROP(3), +}; + +static const struct ad74115_fw_prop ad74115_din_threshold_mode_fw_prop = + AD74115_FW_PROP_BOOL("adi,digital-input-threshold-mode-fixed", + AD74115_DIN_CONFIG2_REG, BIT(7)); + +static const struct ad74115_fw_prop ad74115_dac_bipolar_fw_prop = + AD74115_FW_PROP_BOOL("adi,dac-bipolar", AD74115_OUTPUT_CONFIG_REG, BIT(7)); + +static const struct ad74115_fw_prop ad74115_ch_func_fw_prop = + AD74115_FW_PROP("adi,ch-func", AD74115_CH_FUNC_MAX, + AD74115_CH_FUNC_SETUP_REG, GENMASK(3, 0)); + +static const struct ad74115_fw_prop ad74115_rtd_mode_fw_prop = + AD74115_FW_PROP_BOOL("adi,4-wire-rtd", AD74115_RTD3W4W_CONFIG_REG, BIT(3)); + +static const struct ad74115_fw_prop ad74115_din_range_fw_prop = + AD74115_FW_PROP_BOOL("adi,digital-input-sink-range-high", + AD74115_DIN_CONFIG1_REG, BIT(12)); + +static const struct ad74115_fw_prop ad74115_ext2_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,ext2-burnout-current-nanoamp", + ad74115_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(14, 12)); + +static const struct ad74115_fw_prop ad74115_ext1_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,ext1-burnout-current-nanoamp", + ad74115_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(9, 7)); + +static const struct ad74115_fw_prop ad74115_viout_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,viout-burnout-current-nanoamp", + ad74115_viout_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(4, 2)); + +static const struct ad74115_fw_prop ad74115_fw_props[] = { + AD74115_FW_PROP("adi,conv2-mux", 3, + AD74115_ADC_CONFIG_REG, GENMASK(3, 2)), + + AD74115_FW_PROP_BOOL_NEG("adi,sense-agnd-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(4)), + AD74115_FW_PROP_BOOL_NEG("adi,lf-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(3)), + AD74115_FW_PROP_BOOL_NEG("adi,hf-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(2)), + AD74115_FW_PROP_BOOL_NEG("adi,ext2-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(1)), + AD74115_FW_PROP_BOOL_NEG("adi,ext1-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(0)), + + AD74115_FW_PROP_BOOL("adi,comparator-invert", + AD74115_DIN_CONFIG1_REG, BIT(14)), + AD74115_FW_PROP_BOOL("adi,digital-input-debounce-mode-counter-reset", + AD74115_DIN_CONFIG1_REG, BIT(6)), + + AD74115_FW_PROP_BOOL("adi,digital-input-unbuffered", + AD74115_DIN_CONFIG2_REG, BIT(10)), + AD74115_FW_PROP_BOOL("adi,digital-input-short-circuit-detection", + AD74115_DIN_CONFIG2_REG, BIT(9)), + AD74115_FW_PROP_BOOL("adi,digital-input-open-circuit-detection", + AD74115_DIN_CONFIG2_REG, BIT(8)), + + AD74115_FW_PROP_BOOL("adi,dac-current-limit-low", + AD74115_OUTPUT_CONFIG_REG, BIT(0)), + + AD74115_FW_PROP_BOOL("adi,3-wire-rtd-excitation-swap", + AD74115_RTD3W4W_CONFIG_REG, BIT(2)), + AD74115_FW_PROP_TBL("adi,rtd-excitation-current-microamp", + ad74115_rtd_excitation_current_ua_tbl, + AD74115_RTD3W4W_CONFIG_REG, GENMASK(1, 0)), + + AD74115_FW_PROP_BOOL("adi,ext2-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(11)), + AD74115_FW_PROP_BOOL("adi,ext1-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(6)), + AD74115_FW_PROP_BOOL("adi,viout-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(1)), + + AD74115_FW_PROP_BOOL("adi,charge-pump", + AD74115_CHARGE_PUMP_REG, BIT(0)), +}; + +static int ad74115_apply_fw_prop(struct ad74115_state *st, + const struct ad74115_fw_prop *prop, u32 *retval) +{ + struct device *dev = &st->spi->dev; + u32 val = 0; + int ret; + + if (prop->is_boolean) { + val = device_property_read_bool(dev, prop->name); + } else { + ret = device_property_read_u32(dev, prop->name, &val); + if (ret && prop->lookup_tbl) + val = prop->lookup_tbl[0]; + } + + *retval = val; + + if (prop->negate) + val = !val; + + if (prop->lookup_tbl) + ret = _ad74115_find_tbl_index(prop->lookup_tbl, + prop->lookup_tbl_len, val, &val); + else if (prop->max && val > prop->max) + ret = -EINVAL; + else + ret = 0; + + if (ret) + return dev_err_probe(dev, -EINVAL, + "Invalid value %u for prop %s\n", + val, prop->name); + + WARN(!prop->mask, "Prop %s mask is empty\n", prop->name); + + val = (val << __ffs(prop->mask)) & prop->mask; + + return regmap_update_bits(st->regmap, prop->reg, prop->mask, val); +} + +static int ad74115_setup_adc_conv2_range(struct ad74115_state *st) +{ + unsigned int tbl_len = ARRAY_SIZE(ad74115_adc_range_tbl); + const char *prop_name = "adi,conv2-range-microvolt"; + s32 vals[2] = { + ad74115_adc_range_tbl[0][0], + ad74115_adc_range_tbl[0][1], + }; + struct device *dev = &st->spi->dev; + unsigned int i; + + device_property_read_u32_array(dev, prop_name, vals, 2); + + for (i = 0; i < tbl_len; i++) + if (vals[0] == ad74115_adc_range_tbl[i][0] && + vals[1] == ad74115_adc_range_tbl[i][1]) + break; + + if (i == tbl_len) + return dev_err_probe(dev, -EINVAL, + "Invalid value %d, %d for prop %s\n", + vals[0], vals[1], prop_name); + + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV2_RANGE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV2_RANGE_MASK, i)); +} + +static int ad74115_setup_iio_channels(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + struct iio_chan_spec *channels; + + channels = devm_kcalloc(dev, sizeof(*channels), + indio_dev->num_channels, GFP_KERNEL); + if (!channels) + return -ENOMEM; + + indio_dev->channels = channels; + + memcpy(channels, ad74115_channels_map[st->ch_func].channels, + sizeof(*channels) * ad74115_channels_map[st->ch_func].num_channels); + + if (channels[0].output && channels[0].channel == AD74115_DAC_CH_MAIN && + channels[0].type == IIO_VOLTAGE && !st->dac_hart_slew) { + channels[0].info_mask_separate |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + channels[0].info_mask_separate_available |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + } + + return 0; +} + +static int ad74115_setup_gpio_chip(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + + if (!st->gpio_valid_mask) + return 0; + + st->gc = (struct gpio_chip) { + .owner = THIS_MODULE, + .label = AD74115_NAME, + .base = -1, + .ngpio = AD74115_GPIO_NUM, + .parent = dev, + .can_sleep = true, + .init_valid_mask = ad74115_gpio_init_valid_mask, + .get_direction = ad74115_gpio_get_direction, + .direction_input = ad74115_gpio_direction_input, + .direction_output = ad74115_gpio_direction_output, + .get = ad74115_gpio_get, + .set = ad74115_gpio_set, + }; + + return devm_gpiochip_add_data(dev, &st->gc, st); +} + +static int ad74115_setup_comp_gpio_chip(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + u32 val; + int ret; + + ret = regmap_read(st->regmap, AD74115_DIN_CONFIG1_REG, &val); + if (ret) + return ret; + + if (!(val & AD74115_DIN_COMPARATOR_EN_MASK)) + return 0; + + st->comp_gc = (struct gpio_chip) { + .owner = THIS_MODULE, + .label = AD74115_NAME, + .base = -1, + .ngpio = 1, + .parent = dev, + .can_sleep = true, + .get_direction = ad74115_comp_gpio_get_direction, + .get = ad74115_comp_gpio_get, + .set_config = ad74115_comp_gpio_set_config, + }; + + return devm_gpiochip_add_data(dev, &st->comp_gc, st); +} + +static int ad74115_setup(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + u32 val, din_range_high; + unsigned int i; + int ret; + + ret = ad74115_apply_fw_prop(st, &ad74115_ch_func_fw_prop, &val); + if (ret) + return ret; + + indio_dev->num_channels += ad74115_channels_map[val].num_channels; + st->ch_func = val; + + ret = ad74115_setup_adc_conv2_range(st); + if (ret) + return ret; + + val = device_property_read_bool(dev, "adi,dac-hart-slew"); + if (val) { + st->dac_hart_slew = val; + + ret = regmap_update_bits(st->regmap, AD74115_OUTPUT_CONFIG_REG, + AD74115_OUTPUT_SLEW_EN_MASK, + FIELD_PREP(AD74115_OUTPUT_SLEW_EN_MASK, + AD74115_SLEW_MODE_HART)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_din_range_fw_prop, + &din_range_high); + if (ret) + return ret; + + ret = device_property_read_u32(dev, "adi,digital-input-sink-microamp", &val); + if (!ret) { + if (din_range_high) + val = DIV_ROUND_CLOSEST(val, AD74115_DIN_SINK_LOW_STEP); + else + val = DIV_ROUND_CLOSEST(val, AD74115_DIN_SINK_HIGH_STEP); + + if (val > AD74115_DIN_SINK_MAX) + val = AD74115_DIN_SINK_MAX; + + ret = regmap_update_bits(st->regmap, AD74115_DIN_CONFIG1_REG, + AD74115_DIN_SINK_MASK, + FIELD_PREP(AD74115_DIN_SINK_MASK, val)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_din_threshold_mode_fw_prop, &val); + if (ret) + return ret; + + if (val == AD74115_DIN_THRESHOLD_MODE_AVDD) { + ret = regulator_get_voltage(st->avdd); + if (ret < 0) + return ret; + + st->avdd_mv = ret / 1000; + } + + st->din_threshold_mode = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_dac_bipolar_fw_prop, &val); + if (ret) + return ret; + + st->dac_bipolar = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_rtd_mode_fw_prop, &val); + if (ret) + return ret; + + st->rtd_mode_4_wire = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_ext2_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_EXT2_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_EXT2_EN_MASK, 1)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_ext1_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_EXT1_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_EXT1_EN_MASK, 1)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_viout_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_VIOUT_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_VIOUT_EN_MASK, 1)); + if (ret) + return ret; + } + + for (i = 0; i < AD74115_GPIO_NUM; i++) { + ret = ad74115_apply_fw_prop(st, &ad74115_gpio_mode_fw_props[i], &val); + if (ret) + return ret; + + if (val == AD74115_GPIO_MODE_LOGIC) + st->gpio_valid_mask |= BIT(i); + } + + for (i = 0; i < ARRAY_SIZE(ad74115_fw_props); i++) { + ret = ad74115_apply_fw_prop(st, &ad74115_fw_props[i], &val); + if (ret) + return ret; + } + + ret = ad74115_setup_gpio_chip(st); + if (ret) + return ret; + + ret = ad74115_setup_comp_gpio_chip(st); + if (ret) + return ret; + + return ad74115_setup_iio_channels(indio_dev); +} + +static int ad74115_reset(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + struct gpio_desc *reset_gpio; + int ret; + + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(reset_gpio)) + return dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to find reset GPIO\n"); + + if (reset_gpio) { + fsleep(100); + + gpiod_set_value_cansleep(reset_gpio, 0); + } else { + ret = regmap_write(st->regmap, AD74115_CMD_KEY_REG, + AD74115_CMD_KEY_RESET1); + if (ret) + return ret; + + ret = regmap_write(st->regmap, AD74115_CMD_KEY_REG, + AD74115_CMD_KEY_RESET2); + if (ret) + return ret; + } + + fsleep(1000); + + return 0; +} + +static void ad74115_regulator_disable(void *data) +{ + regulator_disable(data); +} + +static int ad74115_setup_trigger(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + int ret; + + st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "adc_rdy"); + + if (st->irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (st->irq < 0) { + st->irq = 0; + return 0; + } + + ret = devm_request_irq(dev, st->irq, ad74115_adc_data_interrupt, + 0, AD74115_NAME, indio_dev); + if (ret) + return ret; + + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", AD74115_NAME, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &ad74115_trigger_ops; + iio_trigger_set_drvdata(st->trig, st); + + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trig); + + return 0; +} + +static int ad74115_probe(struct spi_device *spi) +{ + static const char * const regulator_names[] = { + "avcc", "dvcc", "dovdd", "refin", + }; + struct device *dev = &spi->dev; + struct ad74115_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->spi = spi; + mutex_init(&st->lock); + init_completion(&st->adc_data_completion); + + indio_dev->name = AD74115_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad74115_info; + + st->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(st->avdd)) + return PTR_ERR(st->avdd); + + ret = regulator_enable(st->avdd); + if (ret) { + dev_err(dev, "Failed to enable avdd regulator\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, ad74115_regulator_disable, st->avdd); + if (ret) + return ret; + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); + if (ret) + return ret; + + st->regmap = devm_regmap_init(dev, NULL, st, &ad74115_regmap_config); + if (IS_ERR(st->regmap)) + return PTR_ERR(st->regmap); + + ret = ad74115_reset(st); + if (ret) + return ret; + + ret = ad74115_setup(indio_dev); + if (ret) + return ret; + + ret = ad74115_setup_trigger(indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + ad74115_trigger_handler, + &ad74115_buffer_ops); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad74115_unregister_driver(struct spi_driver *spi) +{ + spi_unregister_driver(spi); + + return 0; +} + +static int __init ad74115_register_driver(struct spi_driver *spi) +{ + crc8_populate_msb(ad74115_crc8_table, AD74115_CRC_POLYNOMIAL); + + return spi_register_driver(spi); +} + +static const struct spi_device_id ad74115_spi_id[] = { + { "ad74115h" }, + { } +}; + +MODULE_DEVICE_TABLE(spi, ad74115_spi_id); + +static const struct of_device_id ad74115_dt_id[] = { + { .compatible = "adi,ad74115h" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad74115_dt_id); + +static struct spi_driver ad74115_driver = { + .driver = { + .name = "ad74115", + .of_match_table = ad74115_dt_id, + }, + .probe = ad74115_probe, + .id_table = ad74115_spi_id, +}; + +module_driver(ad74115_driver, + ad74115_register_driver, ad74115_unregister_driver); + +MODULE_AUTHOR("Cosmin Tanislav "); +MODULE_DESCRIPTION("Analog Devices AD74115 ADDAC"); +MODULE_LICENSE("GPL"); -- GitLab From f35e1ee9cb5d617efeb0f3695ff65169eb2b9cdd Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 16 Nov 2022 14:40:03 +0100 Subject: [PATCH 1141/1480] iio: imu: st_lsm6dsx: add support to LSM6DSO16IS Add support to STM LSM6DSO16IS (accelerometer and gyroscope) Mems sensor. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dso16is.pdf Tested-by: Mario Tesi Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/df6a9d4653cd69f7204190f8b6a9b618fd48bd23.1668605631.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 4 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 128 ++++++++++++++++++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 + 5 files changed, 141 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 37d02e0fc227a..0096035728cd4 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,8 +13,8 @@ config IIO_ST_LSM6DSX sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx, - lsm6dsv, lsm6dsv16x, the accelerometer/gyroscope of lsm9ds1 - and lsm6dst. + lsm6dsv, lsm6dsv16x, lsm6dso16is, the accelerometer/gyroscope + of lsm9ds1 and lsm6dst. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 683cfadcf62ef..abf14a2ce0e95 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -35,6 +35,7 @@ #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" #define ST_LSM6DSV_DEV_NAME "lsm6dsv" #define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" +#define ST_LSM6DSO16IS_DEV_NAME "lsm6dso16is" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -57,6 +58,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSTX_ID, ST_LSM6DSV_ID, ST_LSM6DSV16X_ID, + ST_LSM6DSO16IS_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b680682f98330..57a79bf35bbaa 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX: + * LSM6DSTX/LSM6DSO16IS: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -1375,6 +1375,132 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .wakeup_src_x_mask = BIT(2), }, }, + { + .reset = { + .addr = 0x12, + .mask = BIT(0), + }, + .boot = { + .addr = 0x12, + .mask = BIT(7), + }, + .bdu = { + .addr = 0x12, + .mask = BIT(6), + }, + .id = { + { + .hw_id = ST_LSM6DSO16IS_ID, + .name = ST_LSM6DSO16IS_DEV_NAME, + .wai = 0x22, + }, + }, + .channels = { + [ST_LSM6DSX_ID_ACC] = { + .chan = st_lsm6dsx_acc_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + }, + [ST_LSM6DSX_ID_GYRO] = { + .chan = st_lsm6dsx_gyro_channels, + .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), + }, + }, + .odr_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(7, 4), + }, + .odr_avl[0] = { 12500, 0x01 }, + .odr_avl[1] = { 26000, 0x02 }, + .odr_avl[2] = { 52000, 0x03 }, + .odr_avl[3] = { 104000, 0x04 }, + .odr_avl[4] = { 208000, 0x05 }, + .odr_avl[5] = { 416000, 0x06 }, + .odr_avl[6] = { 833000, 0x07 }, + .odr_len = 7, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(7, 4), + }, + .odr_avl[0] = { 12500, 0x01 }, + .odr_avl[1] = { 26000, 0x02 }, + .odr_avl[2] = { 52000, 0x03 }, + .odr_avl[3] = { 104000, 0x04 }, + .odr_avl[4] = { 208000, 0x05 }, + .odr_avl[5] = { 416000, 0x06 }, + .odr_avl[6] = { 833000, 0x07 }, + .odr_len = 7, + }, + }, + .fs_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(3, 2), + }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, + .fs_len = 4, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(3, 2), + }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, + .fs_len = 4, + }, + }, + .irq_config = { + .hla = { + .addr = 0x12, + .mask = BIT(5), + }, + .od = { + .addr = 0x12, + .mask = BIT(4), + }, + }, + .shub_settings = { + .page_mux = { + .addr = 0x01, + .mask = BIT(6), + }, + .master_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(2), + }, + .pullup_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(3), + }, + .aux_sens = { + .addr = 0x14, + .mask = GENMASK(1, 0), + }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, + .slv0_addr = 0x15, + .dw_slv0_addr = 0x21, + }, + }, }; int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 3570fac1b6125..c34ccc85e4c71 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -117,6 +117,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dsv16x", .data = (void *)ST_LSM6DSV16X_ID, }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -142,6 +146,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, + { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 57597aaa2a92a..24d5e51a8662e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -117,6 +117,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dsv16x", .data = (void *)ST_LSM6DSV16X_ID, }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -142,6 +146,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, + { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- GitLab From 1842fff0f7b603e587e0fe45804d9ebfba329e38 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 16 Nov 2022 14:40:04 +0100 Subject: [PATCH 1142/1480] dt-bindings: iio: imu: st_lsm6dsx: add lsm6dso16is Add device bindings for lsm6dso16is IMU sensor. Signed-off-by: Lorenzo Bianconi Acked-by: Rob Herring Link: https://lore.kernel.org/r/55b15b3e8453a12edcf8195ef9c9243a76f87096.1668605631.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index 5933270799f55..07d5aee7e4421 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -33,6 +33,7 @@ properties: - st,lsm6dst - st,lsm6dsop - st,lsm6dsv + - st,lsm6dso16is - items: - const: st,asm330lhhx - const: st,lsm6dsr -- GitLab From 58ae95f9671ddf98082e021ee42643d126912e71 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 31 Oct 2022 19:24:54 +0100 Subject: [PATCH 1143/1480] dt-bindings: iio/adc: qcom,spmi-iadc: use double compatibles As in other bindings, let's use specific compatibles together with the fallback compatible. Adjust the bindings for it. Signed-off-by: Luca Weiss Acked-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221031182456.952648-1-luca@z3ntu.xyz Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/qcom,spmi-iadc.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.yaml index 2a94db6888308..fa855baa368c3 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.yaml @@ -18,7 +18,10 @@ description: | properties: compatible: - const: qcom,spmi-iadc + items: + - enum: + - qcom,pm8941-iadc + - const: qcom,spmi-iadc reg: description: IADC base address and length in the SPMI PMIC register map @@ -50,7 +53,7 @@ examples: #address-cells = <1>; #size-cells = <0>; pmic_iadc: adc@3600 { - compatible = "qcom,spmi-iadc"; + compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc"; reg = <0x3600>; interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; qcom,external-resistor-micro-ohms = <10000>; -- GitLab From 7b2366008125b0849dcbd18afbcb33cbc30c3477 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 10:55:15 +0100 Subject: [PATCH 1144/1480] iio: addac: ad74413r: add spi_device_id table Silence the run-time warning SPI driver ad74413r has no spi_device_id for adi,ad74412r Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20221115095517.1008632-2-linux@rasmusvillemoes.dk Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index e0e130ba9d3ec..29b3a5775f236 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -1305,6 +1305,15 @@ static int ad74413r_probe(struct spi_device *spi) st->spi = spi; st->dev = &spi->dev; st->chip_info = device_get_match_data(&spi->dev); + if (!st->chip_info) { + const struct spi_device_id *id = spi_get_device_id(spi); + if (id) + st->chip_info = + (struct ad74413r_chip_info *)id->driver_data; + if (!st->chip_info) + return -EINVAL; + } + mutex_init(&st->lock); init_completion(&st->adc_data_completion); @@ -1457,12 +1466,20 @@ static const struct of_device_id ad74413r_dt_id[] = { }; MODULE_DEVICE_TABLE(of, ad74413r_dt_id); +static const struct spi_device_id ad74413r_spi_id[] = { + { .name = "ad74412r", .driver_data = (kernel_ulong_t)&ad74412r_chip_info_data }, + { .name = "ad74413r", .driver_data = (kernel_ulong_t)&ad74413r_chip_info_data }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad74413r_spi_id); + static struct spi_driver ad74413r_driver = { .driver = { .name = "ad74413r", .of_match_table = ad74413r_dt_id, }, .probe = ad74413r_probe, + .id_table = ad74413r_spi_id, }; module_driver(ad74413r_driver, -- GitLab From 6aaf7045697aa93589bea1b33e751814b0776991 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 10:55:16 +0100 Subject: [PATCH 1145/1480] dt-bindings: iio: ad74413r: add optional reset-gpios The ad74412 and ad74413 devices have an active-low reset pin. Add a binding allowing one to specify a gpio tied to that. Signed-off-by: Rasmus Villemoes Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221115095517.1008632-3-linux@rasmusvillemoes.dk Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml index 58b3ae14ccaa6..9eb3ecc8bbc87 100644 --- a/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml +++ b/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml @@ -51,6 +51,9 @@ properties: Shunt (sense) resistor value in micro-Ohms. default: 100000000 + reset-gpios: + maxItems: 1 + required: - compatible - reg @@ -129,6 +132,7 @@ examples: interrupts = <26 IRQ_TYPE_EDGE_FALLING>; refin-supply = <&ad74413r_refin>; + reset-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>; channel@0 { reg = <0>; -- GitLab From f237cf1914e24ebba88670ecc36e8209c888c9a2 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 10:55:17 +0100 Subject: [PATCH 1146/1480] iio: addac: ad74413r: add support for reset-gpio We have a board where the reset pin of the ad74412 is connected to a gpio, but also pulled low (i.e., asserted) by default. Hence to get the chip out of reset, the driver needs to know about that gpio and deassert the reset signal before attempting to communicate with the chip. When a reset-gpio is given in device tree, use that instead of the software reset. According to the data sheet, the two methods are functionally equivalent. Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20221115095517.1008632-4-linux@rasmusvillemoes.dk Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 29b3a5775f236..61030053cbeaa 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -71,6 +71,7 @@ struct ad74413r_state { struct regmap *regmap; struct device *dev; struct iio_trigger *trig; + struct gpio_desc *reset_gpio; size_t adc_active_channels; struct spi_message adc_samples_msg; @@ -393,6 +394,13 @@ static int ad74413r_reset(struct ad74413r_state *st) { int ret; + if (st->reset_gpio) { + gpiod_set_value_cansleep(st->reset_gpio, 1); + fsleep(50); + gpiod_set_value_cansleep(st->reset_gpio, 0); + return 0; + } + ret = regmap_write(st->regmap, AD74413R_REG_CMD_KEY, AD74413R_CMD_KEY_RESET1); if (ret) @@ -1322,6 +1330,10 @@ static int ad74413r_probe(struct spi_device *spi) if (IS_ERR(st->regmap)) return PTR_ERR(st->regmap); + st->reset_gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); + st->refin_reg = devm_regulator_get(st->dev, "refin"); if (IS_ERR(st->refin_reg)) return dev_err_probe(st->dev, PTR_ERR(st->refin_reg), -- GitLab From 9d901e356c8d3640940cb72ff7969f03e85c2e95 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:21 +0100 Subject: [PATCH 1147/1480] iio: adc: stm32-adc: smart calibration support Add smart calibration support for STM32MP1. - STM32MP15x: both linear & offset calibration are supported - STM32MP13x: Only offset calibration is supported Linear calibration: Linear calibration is SoC dependent and does not change over time so it can be done only once. Linear calibration may have already been done in u-boot. Skip calibration execution if calibration data are already available. Save calibration factors in private data and restore them from private data on next ADC start. Offset calibration: This calibration may vary over time, depending on temperature or voltage. Run offset single-ended and differential calibration on each ADC start, as it is not time consuming. This calibration do not need to be saved. So, remove calfact_s and calfact_d value and bitfields that are no longer used. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-2-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc-core.h | 1 + drivers/iio/adc/stm32-adc.c | 108 +++++++++++++++---------------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h index 9d6dfa1c03faf..73b2c2e91c088 100644 --- a/drivers/iio/adc/stm32-adc-core.h +++ b/drivers/iio/adc/stm32-adc-core.h @@ -142,6 +142,7 @@ #define STM32H7_LINCALRDYW3 BIT(24) #define STM32H7_LINCALRDYW2 BIT(23) #define STM32H7_LINCALRDYW1 BIT(22) +#define STM32H7_LINCALRDYW_MASK GENMASK(27, 22) #define STM32H7_ADCALLIN BIT(16) #define STM32H7_BOOST BIT(8) #define STM32H7_ADSTP BIT(4) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 8d03d21a33d60..2b2b55eb130ed 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -119,16 +119,12 @@ struct stm32_adc_trig_info { /** * struct stm32_adc_calib - optional adc calibration data - * @calfact_s: Calibration offset for single ended channels - * @calfact_d: Calibration offset in differential * @lincalfact: Linearity calibration factor - * @calibrated: Indicates calibration status + * @lincal_saved: Indicates that linear calibration factors are saved */ struct stm32_adc_calib { - u32 calfact_s; - u32 calfact_d; u32 lincalfact[STM32H7_LINCALFACT_NUM]; - bool calibrated; + bool lincal_saved; }; /** @@ -165,8 +161,6 @@ struct stm32_adc_vrefint { * @extsel: trigger selection register & bitfield * @res: resolution selection register & bitfield * @difsel: differential mode selection register & bitfield - * @calfact_s: single-ended calibration factors register & bitfield - * @calfact_d: differential calibration factors register & bitfield * @smpr: smpr1 & smpr2 registers offset array * @smp_bits: smpr1 & smpr2 index and bitfields * @or_vddcore: option register & vddcore bitfield @@ -186,8 +180,6 @@ struct stm32_adc_regspec { const struct stm32_adc_regs extsel; const struct stm32_adc_regs res; const struct stm32_adc_regs difsel; - const struct stm32_adc_regs calfact_s; - const struct stm32_adc_regs calfact_d; const u32 smpr[2]; const struct stm32_adc_regs *smp_bits; const struct stm32_adc_regs or_vddcore; @@ -525,10 +517,6 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, - .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, - STM32H7_CALFACT_S_SHIFT }, - .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, - STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, }; @@ -550,10 +538,6 @@ static const struct stm32_adc_regspec stm32mp13_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32MP13_RES_MASK, STM32MP13_RES_SHIFT }, .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK}, - .calfact_s = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_S_MASK, - STM32MP13_CALFACT_S_SHIFT }, - .calfact_d = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_D_MASK, - STM32MP13_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, .or_vddcore = { STM32MP13_ADC2_OR, STM32MP13_OP0 }, @@ -575,10 +559,6 @@ static const struct stm32_adc_regspec stm32mp1_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, - .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, - STM32H7_CALFACT_S_SHIFT }, - .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, - STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, .or_vddcore = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, @@ -1000,9 +980,6 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - if (!adc->cfg->has_linearcal) - goto skip_linearcal; - /* Read linearity calibration */ lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -1024,15 +1001,7 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) lincalrdyw_mask >>= 1; } - -skip_linearcal: - /* Read offset calibration */ - val = stm32_adc_readl(adc, adc->cfg->regs->calfact_s.reg); - adc->cal.calfact_s = (val & adc->cfg->regs->calfact_s.mask); - adc->cal.calfact_s >>= adc->cfg->regs->calfact_s.shift; - adc->cal.calfact_d = (val & adc->cfg->regs->calfact_d.mask); - adc->cal.calfact_d >>= adc->cfg->regs->calfact_d.shift; - adc->cal.calibrated = true; + adc->cal.lincal_saved = true; return 0; } @@ -1048,13 +1017,6 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - val = (adc->cal.calfact_s << adc->cfg->regs->calfact_s.shift) | - (adc->cal.calfact_d << adc->cfg->regs->calfact_d.shift); - stm32_adc_writel(adc, adc->cfg->regs->calfact_s.reg, val); - - if (!adc->cfg->has_linearcal) - return 0; - lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { /* @@ -1116,19 +1078,20 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) /** * stm32h7_adc_selfcalib() - Procedure to calibrate ADC * @indio_dev: IIO device instance + * @do_lincal: linear calibration request flag * Note: Must be called once ADC is out of power down. + * + * Run offset calibration unconditionally. + * Run linear calibration if requested & supported. */ -static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) +static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) { struct stm32_adc *adc = iio_priv(indio_dev); int ret; u32 msk = STM32H7_ADCALDIF; u32 val; - if (adc->cal.calibrated) - return true; - - if (adc->cfg->has_linearcal) + if (adc->cfg->has_linearcal && do_lincal) msk |= STM32H7_ADCALLIN; /* ADC must be disabled for calibration */ stm32h7_adc_disable(indio_dev); @@ -1172,6 +1135,33 @@ out: return ret; } +/** + * stm32h7_adc_check_selfcalib() - Check linear calibration status + * @indio_dev: IIO device instance + * + * Used to check if linear calibration has been done. + * Return true if linear calibration factors are already saved in private data + * or if a linear calibration has been done at boot stage. + */ +static int stm32h7_adc_check_selfcalib(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + u32 val; + + if (adc->cal.lincal_saved) + return true; + + /* + * Check if linear calibration factors are available in ADC registers, + * by checking that all LINCALRDYWx bits are set. + */ + val = stm32_adc_readl(adc, STM32H7_ADC_CR) & STM32H7_LINCALRDYW_MASK; + if (val == STM32H7_LINCALRDYW_MASK) + return true; + + return false; +} + /** * stm32h7_adc_prepare() - Leave power down mode to enable ADC. * @indio_dev: IIO device instance @@ -1186,16 +1176,20 @@ out: static int stm32h7_adc_prepare(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); - int calib, ret; + int lincal_done = false; + int ret; ret = stm32h7_adc_exit_pwr_down(indio_dev); if (ret) return ret; - ret = stm32h7_adc_selfcalib(indio_dev); + if (adc->cfg->has_linearcal) + lincal_done = stm32h7_adc_check_selfcalib(indio_dev); + + /* Always run offset calibration. Run linear calibration only once */ + ret = stm32h7_adc_selfcalib(indio_dev, !lincal_done); if (ret < 0) goto pwr_dwn; - calib = ret; stm32_adc_int_ch_enable(indio_dev); @@ -1205,13 +1199,15 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) if (ret) goto ch_disable; - /* Either restore or read calibration result for future reference */ - if (calib) - ret = stm32h7_adc_restore_selfcalib(indio_dev); - else - ret = stm32h7_adc_read_selfcalib(indio_dev); - if (ret) - goto disable; + if (adc->cfg->has_linearcal) { + if (!adc->cal.lincal_saved) + ret = stm32h7_adc_read_selfcalib(indio_dev); + else + ret = stm32h7_adc_restore_selfcalib(indio_dev); + + if (ret) + goto disable; + } if (adc->cfg->has_presel) stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); -- GitLab From 2206732b9ad1be8c59f714f2912539bf95cf2961 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:22 +0100 Subject: [PATCH 1148/1480] iio: adc: stm32-adc: improve calibration error log Add more information in calibration error log to differentiate single-ended and differential calibration. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-3-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 2b2b55eb130ed..65dd455375050 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -1109,7 +1109,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) !(val & STM32H7_ADCAL), 100, STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { - dev_err(&indio_dev->dev, "calibration failed\n"); + dev_err(&indio_dev->dev, "calibration (single-ended) error %d\n", ret); goto out; } @@ -1125,7 +1125,8 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) !(val & STM32H7_ADCAL), 100, STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { - dev_err(&indio_dev->dev, "calibration failed\n"); + dev_err(&indio_dev->dev, "calibration (diff%s) error %d\n", + (msk & STM32H7_ADCALLIN) ? "+linear" : "", ret); goto out; } -- GitLab From 51bcacc6fce8db7085c8652069b68123c6c1897c Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:23 +0100 Subject: [PATCH 1149/1480] iio: adc: stm32-adc: add debugfs to read raw calibration result Add debugfs to read linear ADC STM32 self calibration results. Signed-off-by: Fabrice Gasnier Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-4-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 65dd455375050..45d4e79f8e55e 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -1879,6 +1880,23 @@ static const struct iio_chan_spec_ext_info stm32_adc_ext_info[] = { {}, }; +static void stm32_adc_debugfs_init(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + struct dentry *d = iio_get_debugfs_dentry(indio_dev); + struct stm32_adc_calib *cal = &adc->cal; + char buf[16]; + unsigned int i; + + if (!adc->cfg->has_linearcal) + return; + + for (i = 0; i < STM32H7_LINCALFACT_NUM; i++) { + snprintf(buf, sizeof(buf), "lincalfact%d", i + 1); + debugfs_create_u32(buf, 0444, d, &cal->lincalfact[i]); + } +} + static int stm32_adc_fw_get_resolution(struct iio_dev *indio_dev) { struct device *dev = &indio_dev->dev; @@ -2465,6 +2483,9 @@ static int stm32_adc_probe(struct platform_device *pdev) pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); + if (IS_ENABLED(CONFIG_DEBUG_FS)) + stm32_adc_debugfs_init(indio_dev); + return 0; err_hw_stop: @@ -2493,6 +2514,7 @@ static int stm32_adc_remove(struct platform_device *pdev) struct stm32_adc *adc = iio_priv(indio_dev); pm_runtime_get_sync(&pdev->dev); + /* iio_device_unregister() also removes debugfs entries */ iio_device_unregister(indio_dev); stm32_adc_hw_stop(&pdev->dev); pm_runtime_disable(&pdev->dev); -- GitLab From e2af60f5900c6ade53477b494ffb54690eee11f5 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 14:23:23 +0100 Subject: [PATCH 1150/1480] iio: adc128s052: add proper .data members in adc128_of_match table Prior to commit bd5d54e4d49d ("iio: adc128s052: add ACPI _HID AANT1280"), the driver unconditionally used spi_get_device_id() to get the index into the adc128_config array. However, with that commit, OF-based boards now incorrectly treat all supported sensors as if they are an adc128s052, because all the .data members of the adc128_of_match table are implicitly 0. Our board, which has an adc122s021, thus exposes 8 channels whereas it really only has two. Fixes: bd5d54e4d49d ("iio: adc128s052: add ACPI _HID AANT1280") Signed-off-by: Rasmus Villemoes Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221115132324.1078169-1-linux@rasmusvillemoes.dk Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-adc128s052.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 622fd384983c7..b3d5b9b7255bc 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -181,13 +181,13 @@ static int adc128_probe(struct spi_device *spi) } static const struct of_device_id adc128_of_match[] = { - { .compatible = "ti,adc128s052", }, - { .compatible = "ti,adc122s021", }, - { .compatible = "ti,adc122s051", }, - { .compatible = "ti,adc122s101", }, - { .compatible = "ti,adc124s021", }, - { .compatible = "ti,adc124s051", }, - { .compatible = "ti,adc124s101", }, + { .compatible = "ti,adc128s052", .data = (void*)0L, }, + { .compatible = "ti,adc122s021", .data = (void*)1L, }, + { .compatible = "ti,adc122s051", .data = (void*)1L, }, + { .compatible = "ti,adc122s101", .data = (void*)1L, }, + { .compatible = "ti,adc124s021", .data = (void*)2L, }, + { .compatible = "ti,adc124s051", .data = (void*)2L, }, + { .compatible = "ti,adc124s101", .data = (void*)2L, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, adc128_of_match); -- GitLab From 32abe97b48fb1532c752495dab3f8255db8f5c2a Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 15 Nov 2022 12:41:28 +0000 Subject: [PATCH 1151/1480] dt-bindings: iio: adc: renesas,rzg2l-adc: Document RZ/Five SoC The ADC block on the RZ/Five SoC is identical to one found on the RZ/G2UL SoC. "renesas,r9a07g043-adc" compatible string will be used on the RZ/Five SoC so to make this clear, update the comment to include RZ/Five SoC. No driver changes are required as generic compatible string "renesas,rzg2l-adc" will be used as a fallback on RZ/Five SoC. Signed-off-by: Lad Prabhakar Acked-by: Rob Herring Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20221115124128.1183144-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml b/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml index 61c6157cf5a96..8b743742a5f9f 100644 --- a/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml @@ -19,7 +19,7 @@ properties: compatible: items: - enum: - - renesas,r9a07g043-adc # RZ/G2UL + - renesas,r9a07g043-adc # RZ/G2UL and RZ/Five - renesas,r9a07g044-adc # RZ/G2L - renesas,r9a07g054-adc # RZ/V2L - const: renesas,rzg2l-adc -- GitLab From a0666f7f0f9470bfe64ab60324bc0a7830ce9035 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Tue, 15 Nov 2022 17:16:53 +0200 Subject: [PATCH 1152/1480] dt-bindings: iio: temperature: ltc2983: drop $ref for -nanoamp properties Currently there are -nanoamp properties both with and without a $ref. dt-schema has been modified to handle it as a standard unit, but the change has been reverted since there were still occurrences of -nanoamp properties with a $ref. Remove this since it's the only occurrence left. Signed-off-by: Cosmin Tanislav Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221115151653.393559-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/temperature/adi,ltc2983.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 44f8b0672f533..b69813f281dad 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -325,7 +325,6 @@ patternProperties: description: Excitation current applied to the thermistor. 0 sets the sensor in auto-range mode. - $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000] default: 0 -- GitLab From e0736b1bb71b21faeebf85efc725d01c7ecf2ebe Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Tue, 15 Nov 2022 17:19:55 +0200 Subject: [PATCH 1153/1480] dt-bindings: iio: adc: ad4130: use spi-peripheral-props.yaml Reference the "spi-peripheral-props.yaml" schema to allow using all SPI device properties. Signed-off-by: Cosmin Tanislav Acked-by: Rob Herring Link: https://lore.kernel.org/r/20221115151955.394030-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml index 28ebd38b9db44..d00690a8d3fbd 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml @@ -190,7 +190,10 @@ patternProperties: - reg - diff-channels -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- GitLab From 1407438a7ad513a9dd5c70bc996200f97960584c Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 15 Nov 2022 13:00:40 +0200 Subject: [PATCH 1154/1480] dt-bindings: iio: frequency: add adf4377 doc Add device tree bindings for the ADF4377 driver. Signed-off-by: Antoniu Miclaus Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221115110041.71495-1-antoniu.miclaus@analog.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/frequency/adi,adf4377.yaml | 92 +++++++++++++++++++ MAINTAINERS | 8 ++ 2 files changed, 100 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml new file mode 100644 index 0000000000000..aa6a3193b4e03 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/frequency/adi,adf4377.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADF4377 Microwave Wideband Synthesizer with Integrated VCO + +maintainers: + - Antoniu Miclaus + - Dragos Bogdan + +description: | + The ADF4377 is a high performance, ultralow jitter, dual output integer-N + phased locked loop (PLL) with integrated voltage controlled oscillator (VCO) + ideally suited for data converter and mixed signal front end (MxFE) clock + applications. + + https://www.analog.com/en/products/adf4377.html + +properties: + compatible: + enum: + - adi,adf4377 + - adi,adf4378 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 10000000 + + clocks: + maxItems: 1 + + clock-names: + description: + External clock that provides reference input frequency. + items: + - const: ref_in + + chip-enable-gpios: + description: + GPIO that controls the Chip Enable Pin. + maxItems: 1 + + clk1-enable-gpios: + description: + GPIO that controls the Enable Clock 1 Output Buffer Pin. + maxItems: 1 + + clk2-enable-gpios: + description: + GPIO that controls the Enable Clock 2 Output Buffer Pin. + maxItems: 1 + + adi,muxout-select: + description: + On chip multiplexer output selection. + high_z - MUXOUT Pin set to high-Z. + lock_detect - MUXOUT Pin set to lock detector output. + muxout_low - MUXOUT Pin set to low. + f_div_rclk_2 - MUXOUT Pin set to fDIV_RCLK/2. + f_div_nclk_2 - MUXOUT Pin set to fDIV_NCLK/2. + muxout_high - MUXOUT Pin set to high. + enum: [high_z, lock_detect, muxout_low, f_div_rclk_2, f_div_nclk_2, muxout_high] + +required: + - compatible + - reg + - clocks + - clock-names + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + frequency@0 { + compatible = "adi,adf4377"; + reg = <0>; + spi-max-frequency = <10000000>; + clocks = <&adf4377_ref_in>; + clock-names = "ref_in"; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 860075c493dd2..82e23ae055e11 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1206,6 +1206,14 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/amplifiers/adi,ada4250.yaml F: drivers/iio/amplifiers/ada4250.c +ANALOG DEVICES INC ADF4377 DRIVER +M: Antoniu Miclaus +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml +F: drivers/iio/frequency/adf4377.c + ANALOG DEVICES INC ADGS1408 DRIVER M: Mircea Caprioru S: Supported -- GitLab From eda549e2e52496d0d374ce457f514a4f14172aa5 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 15 Nov 2022 13:00:41 +0200 Subject: [PATCH 1155/1480] iio: frequency: adf4377: add support for ADF4377 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ADF4377 is a high performance, ultralow jitter, dual output integer-N phased locked loop (PLL) with integrated voltage controlled oscillator (VCO) ideally suited for data converter and mixed signal front end (MxFE) clock applications. Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adf4377.pdf Signed-off-by: Antoniu Miclaus Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221115110041.71495-2-antoniu.miclaus@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/frequency/Kconfig | 10 + drivers/iio/frequency/Makefile | 1 + drivers/iio/frequency/adf4377.c | 994 ++++++++++++++++++++++++++++++++ 3 files changed, 1005 insertions(+) create mode 100644 drivers/iio/frequency/adf4377.c diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index f3702f36436cb..9e85dfa585081 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -50,6 +50,16 @@ config ADF4371 To compile this driver as a module, choose M here: the module will be called adf4371. +config ADF4377 + tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" + depends on SPI && COMMON_CLK + help + Say yes here to build support for Analog Devices ADF4377 Microwave + Wideband Synthesizer. + + To compile this driver as a module, choose M here: the + module will be called adf4377. + config ADMV1013 tristate "Analog Devices ADMV1013 Microwave Upconverter" depends on SPI && COMMON_CLK diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index 48add732f1d36..b616c29b4a087 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_AD9523) += ad9523.o obj-$(CONFIG_ADF4350) += adf4350.o obj-$(CONFIG_ADF4371) += adf4371.o +obj-$(CONFIG_ADF4377) += adf4377.o obj-$(CONFIG_ADMV1013) += admv1013.o obj-$(CONFIG_ADMV1014) += admv1014.o obj-$(CONFIG_ADMV4420) += admv4420.o diff --git a/drivers/iio/frequency/adf4377.c b/drivers/iio/frequency/adf4377.c new file mode 100644 index 0000000000000..26abecbd51e06 --- /dev/null +++ b/drivers/iio/frequency/adf4377.c @@ -0,0 +1,994 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ADF4377 driver + * + * Copyright 2022 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* ADF4377 REG0000 Map */ +#define ADF4377_0000_SOFT_RESET_R_MSK BIT(7) +#define ADF4377_0000_LSB_FIRST_R_MSK BIT(6) +#define ADF4377_0000_ADDRESS_ASC_R_MSK BIT(5) +#define ADF4377_0000_SDO_ACTIVE_R_MSK BIT(4) +#define ADF4377_0000_SDO_ACTIVE_MSK BIT(3) +#define ADF4377_0000_ADDRESS_ASC_MSK BIT(2) +#define ADF4377_0000_LSB_FIRST_MSK BIT(1) +#define ADF4377_0000_SOFT_RESET_MSK BIT(0) + +/* ADF4377 REG0000 Bit Definition */ +#define ADF4377_0000_SDO_ACTIVE_SPI_3W 0x0 +#define ADF4377_0000_SDO_ACTIVE_SPI_4W 0x1 + +#define ADF4377_0000_ADDR_ASC_AUTO_DECR 0x0 +#define ADF4377_0000_ADDR_ASC_AUTO_INCR 0x1 + +#define ADF4377_0000_LSB_FIRST_MSB 0x0 +#define ADF4377_0000_LSB_FIRST_LSB 0x1 + +#define ADF4377_0000_SOFT_RESET_N_OP 0x0 +#define ADF4377_0000_SOFT_RESET_EN 0x1 + +/* ADF4377 REG0001 Map */ +#define ADF4377_0001_SINGLE_INSTR_MSK BIT(7) +#define ADF4377_0001_MASTER_RB_CTRL_MSK BIT(5) + +/* ADF4377 REG0003 Bit Definition */ +#define ADF4377_0003_CHIP_TYPE 0x06 + +/* ADF4377 REG0004 Bit Definition */ +#define ADF4377_0004_PRODUCT_ID_LSB 0x0005 + +/* ADF4377 REG0005 Bit Definition */ +#define ADF4377_0005_PRODUCT_ID_MSB 0x0005 + +/* ADF4377 REG000A Map */ +#define ADF4377_000A_SCRATCHPAD_MSK GENMASK(7, 0) + +/* ADF4377 REG000C Bit Definition */ +#define ADF4377_000C_VENDOR_ID_LSB 0x56 + +/* ADF4377 REG000D Bit Definition */ +#define ADF4377_000D_VENDOR_ID_MSB 0x04 + +/* ADF4377 REG000F Bit Definition */ +#define ADF4377_000F_R00F_RSV1_MSK GENMASK(7, 0) + +/* ADF4377 REG0010 Map*/ +#define ADF4377_0010_N_INT_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0011 Map*/ +#define ADF4377_0011_EN_AUTOCAL_MSK BIT(7) +#define ADF4377_0011_EN_RDBLR_MSK BIT(6) +#define ADF4377_0011_DCLK_DIV2_MSK GENMASK(5, 4) +#define ADF4377_0011_N_INT_MSB_MSK GENMASK(3, 0) + +/* ADF4377 REG0011 Bit Definition */ +#define ADF4377_0011_DCLK_DIV2_1 0x0 +#define ADF4377_0011_DCLK_DIV2_2 0x1 +#define ADF4377_0011_DCLK_DIV2_4 0x2 +#define ADF4377_0011_DCLK_DIV2_8 0x3 + +/* ADF4377 REG0012 Map*/ +#define ADF4377_0012_CLKOUT_DIV_MSK GENMASK(7, 6) +#define ADF4377_0012_R_DIV_MSK GENMASK(5, 0) + +/* ADF4377 REG0012 Bit Definition */ +#define ADF4377_0012_CLKOUT_DIV_1 0x0 +#define ADF4377_0012_CLKOUT_DIV_2 0x1 +#define ADF4377_0012_CLKOUT_DIV_4 0x2 +#define ADF4377_0012_CLKOUT_DIV_8 0x3 + +/* ADF4377 REG0013 Map */ +#define ADF4377_0013_M_VCO_CORE_MSK GENMASK(5, 4) +#define ADF4377_0013_VCO_BIAS_MSK GENMASK(3, 0) + +/* ADF4377 REG0013 Bit Definition */ +#define ADF4377_0013_M_VCO_0 0x0 +#define ADF4377_0013_M_VCO_1 0x1 +#define ADF4377_0013_M_VCO_2 0x2 +#define ADF4377_0013_M_VCO_3 0x3 + +/* ADF4377 REG0014 Map */ +#define ADF4377_0014_M_VCO_BAND_MSK GENMASK(7, 0) + +/* ADF4377 REG0015 Map */ +#define ADF4377_0015_BLEED_I_LSB_MSK GENMASK(7, 6) +#define ADF4377_0015_BLEED_POL_MSK BIT(5) +#define ADF4377_0015_EN_BLEED_MSK BIT(4) +#define ADF4377_0015_CP_I_MSK GENMASK(3, 0) + +/* ADF4377 REG0015 Bit Definition */ +#define ADF4377_CURRENT_SINK 0x0 +#define ADF4377_CURRENT_SOURCE 0x1 + +#define ADF4377_0015_CP_0MA7 0x0 +#define ADF4377_0015_CP_0MA9 0x1 +#define ADF4377_0015_CP_1MA1 0x2 +#define ADF4377_0015_CP_1MA3 0x3 +#define ADF4377_0015_CP_1MA4 0x4 +#define ADF4377_0015_CP_1MA8 0x5 +#define ADF4377_0015_CP_2MA2 0x6 +#define ADF4377_0015_CP_2MA5 0x7 +#define ADF4377_0015_CP_2MA9 0x8 +#define ADF4377_0015_CP_3MA6 0x9 +#define ADF4377_0015_CP_4MA3 0xA +#define ADF4377_0015_CP_5MA0 0xB +#define ADF4377_0015_CP_5MA7 0xC +#define ADF4377_0015_CP_7MA2 0xD +#define ADF4377_0015_CP_8MA6 0xE +#define ADF4377_0015_CP_10MA1 0xF + +/* ADF4377 REG0016 Map */ +#define ADF4377_0016_BLEED_I_MSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0017 Map */ +#define ADF4377_0016_INV_CLKOUT_MSK BIT(7) +#define ADF4377_0016_N_DEL_MSK GENMASK(6, 0) + +/* ADF4377 REG0018 Map */ +#define ADF4377_0018_CMOS_OV_MSK BIT(7) +#define ADF4377_0018_R_DEL_MSK GENMASK(6, 0) + +/* ADF4377 REG0018 Bit Definition */ +#define ADF4377_0018_1V8_LOGIC 0x0 +#define ADF4377_0018_3V3_LOGIC 0x1 + +/* ADF4377 REG0019 Map */ +#define ADF4377_0019_CLKOUT2_OP_MSK GENMASK(7, 6) +#define ADF4377_0019_CLKOUT1_OP_MSK GENMASK(5, 4) +#define ADF4377_0019_PD_CLK_MSK BIT(3) +#define ADF4377_0019_PD_RDET_MSK BIT(2) +#define ADF4377_0019_PD_ADC_MSK BIT(1) +#define ADF4377_0019_PD_CALADC_MSK BIT(0) + +/* ADF4377 REG0019 Bit Definition */ +#define ADF4377_0019_CLKOUT_320MV 0x0 +#define ADF4377_0019_CLKOUT_420MV 0x1 +#define ADF4377_0019_CLKOUT_530MV 0x2 +#define ADF4377_0019_CLKOUT_640MV 0x3 + +/* ADF4377 REG001A Map */ +#define ADF4377_001A_PD_ALL_MSK BIT(7) +#define ADF4377_001A_PD_RDIV_MSK BIT(6) +#define ADF4377_001A_PD_NDIV_MSK BIT(5) +#define ADF4377_001A_PD_VCO_MSK BIT(4) +#define ADF4377_001A_PD_LD_MSK BIT(3) +#define ADF4377_001A_PD_PFDCP_MSK BIT(2) +#define ADF4377_001A_PD_CLKOUT1_MSK BIT(1) +#define ADF4377_001A_PD_CLKOUT2_MSK BIT(0) + +/* ADF4377 REG001B Map */ +#define ADF4377_001B_EN_LOL_MSK BIT(7) +#define ADF4377_001B_LDWIN_PW_MSK BIT(6) +#define ADF4377_001B_EN_LDWIN_MSK BIT(5) +#define ADF4377_001B_LD_COUNT_MSK GENMASK(4, 0) + +/* ADF4377 REG001B Bit Definition */ +#define ADF4377_001B_LDWIN_PW_NARROW 0x0 +#define ADF4377_001B_LDWIN_PW_WIDE 0x1 + +/* ADF4377 REG001C Map */ +#define ADF4377_001C_EN_DNCLK_MSK BIT(7) +#define ADF4377_001C_EN_DRCLK_MSK BIT(6) +#define ADF4377_001C_RST_LD_MSK BIT(2) +#define ADF4377_001C_R01C_RSV1_MSK BIT(0) + +/* ADF4377 REG001C Bit Definition */ +#define ADF4377_001C_RST_LD_INACTIVE 0x0 +#define ADF4377_001C_RST_LD_ACTIVE 0x1 + +#define ADF4377_001C_R01C_RSV1 0x1 + +/* ADF4377 REG001D Map */ +#define ADF4377_001D_MUXOUT_MSK GENMASK(7, 4) +#define ADF4377_001D_EN_CPTEST_MSK BIT(2) +#define ADF4377_001D_CP_DOWN_MSK BIT(1) +#define ADF4377_001D_CP_UP_MSK BIT(0) + +#define ADF4377_001D_EN_CPTEST_OFF 0x0 +#define ADF4377_001D_EN_CPTEST_ON 0x1 + +#define ADF4377_001D_CP_DOWN_OFF 0x0 +#define ADF4377_001D_CP_DOWN_ON 0x1 + +#define ADF4377_001D_CP_UP_OFF 0x0 +#define ADF4377_001D_CP_UP_ON 0x1 + +/* ADF4377 REG001F Map */ +#define ADF4377_001F_BST_REF_MSK BIT(7) +#define ADF4377_001F_FILT_REF_MSK BIT(6) +#define ADF4377_001F_REF_SEL_MSK BIT(5) +#define ADF4377_001F_R01F_RSV1_MSK GENMASK(4, 0) + +/* ADF4377 REG001F Bit Definition */ +#define ADF4377_001F_BST_LARGE_REF_IN 0x0 +#define ADF4377_001F_BST_SMALL_REF_IN 0x1 + +#define ADF4377_001F_FILT_REF_OFF 0x0 +#define ADF4377_001F_FILT_REF_ON 0x1 + +#define ADF4377_001F_REF_SEL_DMA 0x0 +#define ADF4377_001F_REF_SEL_LNA 0x1 + +#define ADF4377_001F_R01F_RSV1 0x7 + +/* ADF4377 REG0020 Map */ +#define ADF4377_0020_RST_SYS_MSK BIT(4) +#define ADF4377_0020_EN_ADC_CLK_MSK BIT(3) +#define ADF4377_0020_R020_RSV1_MSK BIT(0) + +/* ADF4377 REG0021 Bit Definition */ +#define ADF4377_0021_R021_RSV1 0xD3 + +/* ADF4377 REG0022 Bit Definition */ +#define ADF4377_0022_R022_RSV1 0x32 + +/* ADF4377 REG0023 Map */ +#define ADF4377_0023_CAT_CT_SEL BIT(7) +#define ADF4377_0023_R023_RSV1_MSK GENMASK(6, 0) + +/* ADF4377 REG0023 Bit Definition */ +#define ADF4377_0023_R023_RSV1 0x18 + +/* ADF4377 REG0024 Map */ +#define ADF4377_0024_DCLK_MODE_MSK BIT(2) + +/* ADF4377 REG0025 Map */ +#define ADF4377_0025_CLKODIV_DB_MSK BIT(7) +#define ADF4377_0025_DCLK_DB_MSK BIT(6) +#define ADF4377_0025_R025_RSV1_MSK GENMASK(5, 0) + +/* ADF4377 REG0025 Bit Definition */ +#define ADF4377_0025_R025_RSV1 0x16 + +/* ADF4377 REG0026 Map */ +#define ADF4377_0026_VCO_BAND_DIV_MSK GENMASK(7, 0) + +/* ADF4377 REG0027 Map */ +#define ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0028 Map */ +#define ADF4377_0028_O_VCO_DB_MSK BIT(7) +#define ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK GENMASK(6, 0) + +/* ADF4377 REG0029 Map */ +#define ADF4377_0029_VCO_ALC_TO_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG002A Map */ +#define ADF4377_002A_DEL_CTRL_DB_MSK BIT(7) +#define ADF4377_002A_VCO_ALC_TO_MSB_MSK GENMASK(6, 0) + +/* ADF4377 REG002C Map */ +#define ADF4377_002C_R02C_RSV1 0xC0 + +/* ADF4377 REG002D Map */ +#define ADF4377_002D_ADC_CLK_DIV_MSK GENMASK(7, 0) + +/* ADF4377 REG002E Map */ +#define ADF4377_002E_EN_ADC_CNV_MSK BIT(7) +#define ADF4377_002E_EN_ADC_MSK BIT(1) +#define ADF4377_002E_ADC_A_CONV_MSK BIT(0) + +/* ADF4377 REG002E Bit Definition */ +#define ADF4377_002E_ADC_A_CONV_ADC_ST_CNV 0x0 +#define ADF4377_002E_ADC_A_CONV_VCO_CALIB 0x1 + +/* ADF4377 REG002F Map */ +#define ADF4377_002F_DCLK_DIV1_MSK GENMASK(1, 0) + +/* ADF4377 REG002F Bit Definition */ +#define ADF4377_002F_DCLK_DIV1_1 0x0 +#define ADF4377_002F_DCLK_DIV1_2 0x1 +#define ADF4377_002F_DCLK_DIV1_8 0x2 +#define ADF4377_002F_DCLK_DIV1_32 0x3 + +/* ADF4377 REG0031 Bit Definition */ +#define ADF4377_0031_R031_RSV1 0x09 + +/* ADF4377 REG0032 Map */ +#define ADF4377_0032_ADC_CLK_SEL_MSK BIT(6) +#define ADF4377_0032_R032_RSV1_MSK GENMASK(5, 0) + +/* ADF4377 REG0032 Bit Definition */ +#define ADF4377_0032_ADC_CLK_SEL_N_OP 0x0 +#define ADF4377_0032_ADC_CLK_SEL_SPI_CLK 0x1 + +#define ADF4377_0032_R032_RSV1 0x9 + +/* ADF4377 REG0033 Bit Definition */ +#define ADF4377_0033_R033_RSV1 0x18 + +/* ADF4377 REG0034 Bit Definition */ +#define ADF4377_0034_R034_RSV1 0x08 + +/* ADF4377 REG003A Bit Definition */ +#define ADF4377_003A_R03A_RSV1 0x5D + +/* ADF4377 REG003B Bit Definition */ +#define ADF4377_003B_R03B_RSV1 0x2B + +/* ADF4377 REG003D Map */ +#define ADF4377_003D_O_VCO_BAND_MSK BIT(3) +#define ADF4377_003D_O_VCO_CORE_MSK BIT(2) +#define ADF4377_003D_O_VCO_BIAS_MSK BIT(1) + +/* ADF4377 REG003D Bit Definition */ +#define ADF4377_003D_O_VCO_BAND_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_BAND_M_VCO 0x1 + +#define ADF4377_003D_O_VCO_CORE_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_CORE_M_VCO 0x1 + +#define ADF4377_003D_O_VCO_BIAS_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_BIAS_M_VCO 0x1 + +/* ADF4377 REG0042 Map */ +#define ADF4377_0042_R042_RSV1 0x05 + +/* ADF4377 REG0045 Map */ +#define ADF4377_0045_ADC_ST_CNV_MSK BIT(0) + +/* ADF4377 REG0049 Map */ +#define ADF4377_0049_EN_CLK2_MSK BIT(7) +#define ADF4377_0049_EN_CLK1_MSK BIT(6) +#define ADF4377_0049_REF_OK_MSK BIT(3) +#define ADF4377_0049_ADC_BUSY_MSK BIT(2) +#define ADF4377_0049_FSM_BUSY_MSK BIT(1) +#define ADF4377_0049_LOCKED_MSK BIT(0) + +/* ADF4377 REG004B Map */ +#define ADF4377_004B_VCO_CORE_MSK GENMASK(1, 0) + +/* ADF4377 REG004C Map */ +#define ADF4377_004C_CHIP_TEMP_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG004D Map */ +#define ADF4377_004D_CHIP_TEMP_MSB_MSK BIT(0) + +/* ADF4377 REG004F Map */ +#define ADF4377_004F_VCO_BAND_MSK GENMASK(7, 0) + +/* ADF4377 REG0051 Map */ +#define ADF4377_0051_VCO_BIAS_MSK GENMASK(3, 0) + +/* ADF4377 REG0054 Map */ +#define ADF4377_0054_CHIP_VERSION_MSK GENMASK(7, 0) + +/* Specifications */ +#define ADF4377_SPI_READ_CMD BIT(7) +#define ADF4377_MAX_VCO_FREQ (12800ULL * HZ_PER_MHZ) +#define ADF4377_MIN_VCO_FREQ (6400ULL * HZ_PER_MHZ) +#define ADF4377_MAX_REFIN_FREQ (1000 * HZ_PER_MHZ) +#define ADF4377_MIN_REFIN_FREQ (10 * HZ_PER_MHZ) +#define ADF4377_MAX_FREQ_PFD (500 * HZ_PER_MHZ) +#define ADF4377_MIN_FREQ_PFD (3 * HZ_PER_MHZ) +#define ADF4377_MAX_CLKPN_FREQ ADF4377_MAX_VCO_FREQ +#define ADF4377_MIN_CLKPN_FREQ (ADF4377_MIN_VCO_FREQ / 8) +#define ADF4377_FREQ_PFD_80MHZ (80 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_125MHZ (125 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_160MHZ (160 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_250MHZ (250 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_320MHZ (320 * HZ_PER_MHZ) + +enum { + ADF4377_FREQ, +}; + +enum muxout_select_mode { + ADF4377_MUXOUT_HIGH_Z = 0x0, + ADF4377_MUXOUT_LKDET = 0x1, + ADF4377_MUXOUT_LOW = 0x2, + ADF4377_MUXOUT_DIV_RCLK_2 = 0x4, + ADF4377_MUXOUT_DIV_NCLK_2 = 0x5, + ADF4377_MUXOUT_HIGH = 0x8, +}; + +struct adf4377_state { + struct spi_device *spi; + struct regmap *regmap; + struct clk *clkin; + /* Protect against concurrent accesses to the device and data content */ + struct mutex lock; + struct notifier_block nb; + /* Reference Divider */ + unsigned int ref_div_factor; + /* PFD Frequency */ + unsigned int f_pfd; + /* Input Reference Clock */ + unsigned int clkin_freq; + /* CLKOUT Divider */ + u8 clkout_div_sel; + /* Feedback Divider (N) */ + u16 n_int; + u16 synth_lock_timeout; + u16 vco_alc_timeout; + u16 adc_clk_div; + u16 vco_band_div; + u8 dclk_div1; + u8 dclk_div2; + u8 dclk_mode; + unsigned int f_div_rclk; + enum muxout_select_mode muxout_select; + struct gpio_desc *gpio_ce; + struct gpio_desc *gpio_enclk1; + struct gpio_desc *gpio_enclk2; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); +}; + +static const char * const adf4377_muxout_modes[] = { + [ADF4377_MUXOUT_HIGH_Z] = "high_z", + [ADF4377_MUXOUT_LKDET] = "lock_detect", + [ADF4377_MUXOUT_LOW] = "muxout_low", + [ADF4377_MUXOUT_DIV_RCLK_2] = "f_div_rclk_2", + [ADF4377_MUXOUT_DIV_NCLK_2] = "f_div_nclk_2", + [ADF4377_MUXOUT_HIGH] = "muxout_high", +}; + +static const struct reg_sequence adf4377_reg_defaults[] = { + { 0x42, ADF4377_0042_R042_RSV1 }, + { 0x3B, ADF4377_003B_R03B_RSV1 }, + { 0x3A, ADF4377_003A_R03A_RSV1 }, + { 0x34, ADF4377_0034_R034_RSV1 }, + { 0x33, ADF4377_0033_R033_RSV1 }, + { 0x32, ADF4377_0032_R032_RSV1 }, + { 0x31, ADF4377_0031_R031_RSV1 }, + { 0x2C, ADF4377_002C_R02C_RSV1 }, + { 0x25, ADF4377_0025_R025_RSV1 }, + { 0x23, ADF4377_0023_R023_RSV1 }, + { 0x22, ADF4377_0022_R022_RSV1 }, + { 0x21, ADF4377_0021_R021_RSV1 }, + { 0x1f, ADF4377_001F_R01F_RSV1 }, + { 0x1c, ADF4377_001C_R01C_RSV1 }, +}; + +static const struct regmap_config adf4377_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .read_flag_mask = BIT(7), + .max_register = 0x54, +}; + +static int adf4377_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int write_val, + unsigned int *read_val) +{ + struct adf4377_state *st = iio_priv(indio_dev); + + if (read_val) + return regmap_read(st->regmap, reg, read_val); + + return regmap_write(st->regmap, reg, write_val); +} + +static const struct iio_info adf4377_info = { + .debugfs_reg_access = &adf4377_reg_access, +}; + +static int adf4377_soft_reset(struct adf4377_state *st) +{ + unsigned int read_val; + int ret; + + ret = regmap_update_bits(st->regmap, 0x0, ADF4377_0000_SOFT_RESET_MSK | + ADF4377_0000_SOFT_RESET_R_MSK, + FIELD_PREP(ADF4377_0000_SOFT_RESET_MSK, 1) | + FIELD_PREP(ADF4377_0000_SOFT_RESET_R_MSK, 1)); + if (ret) + return ret; + + return regmap_read_poll_timeout(st->regmap, 0x0, read_val, + !(read_val & (ADF4377_0000_SOFT_RESET_R_MSK | + ADF4377_0000_SOFT_RESET_R_MSK)), 200, 200 * 100); +} + +static int adf4377_get_freq(struct adf4377_state *st, u64 *freq) +{ + unsigned int ref_div_factor, n_int; + u64 clkin_freq; + int ret; + + mutex_lock(&st->lock); + ret = regmap_read(st->regmap, 0x12, &ref_div_factor); + if (ret) + goto exit; + + ret = regmap_bulk_read(st->regmap, 0x10, st->buf, sizeof(st->buf)); + if (ret) + goto exit; + + clkin_freq = clk_get_rate(st->clkin); + ref_div_factor = FIELD_GET(ADF4377_0012_R_DIV_MSK, ref_div_factor); + n_int = FIELD_GET(ADF4377_0010_N_INT_LSB_MSK | ADF4377_0011_N_INT_MSB_MSK, + get_unaligned_le16(&st->buf)); + + *freq = div_u64(clkin_freq, ref_div_factor) * n_int; +exit: + mutex_unlock(&st->lock); + + return ret; +} + +static int adf4377_set_freq(struct adf4377_state *st, u64 freq) +{ + unsigned int read_val; + u64 f_vco; + int ret; + + mutex_lock(&st->lock); + + if (freq > ADF4377_MAX_CLKPN_FREQ || freq < ADF4377_MIN_CLKPN_FREQ) { + ret = -EINVAL; + goto exit; + } + + ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | + ADF4377_001C_EN_DRCLK_MSK, + FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 1) | + FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_AUTOCAL_MSK | + ADF4377_0011_DCLK_DIV2_MSK, + FIELD_PREP(ADF4377_0011_EN_AUTOCAL_MSK, 1) | + FIELD_PREP(ADF4377_0011_DCLK_DIV2_MSK, st->dclk_div2)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2E, ADF4377_002E_EN_ADC_CNV_MSK | + ADF4377_002E_EN_ADC_MSK | + ADF4377_002E_ADC_A_CONV_MSK, + FIELD_PREP(ADF4377_002E_EN_ADC_CNV_MSK, 1) | + FIELD_PREP(ADF4377_002E_EN_ADC_MSK, 1) | + FIELD_PREP(ADF4377_002E_ADC_A_CONV_MSK, + ADF4377_002E_ADC_A_CONV_VCO_CALIB)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, + FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2F, ADF4377_002F_DCLK_DIV1_MSK, + FIELD_PREP(ADF4377_002F_DCLK_DIV1_MSK, st->dclk_div1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x24, ADF4377_0024_DCLK_MODE_MSK, + FIELD_PREP(ADF4377_0024_DCLK_MODE_MSK, st->dclk_mode)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x27, + FIELD_PREP(ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK, + st->synth_lock_timeout)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x28, ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, + FIELD_PREP(ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, + st->synth_lock_timeout >> 8)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x29, + FIELD_PREP(ADF4377_0029_VCO_ALC_TO_LSB_MSK, + st->vco_alc_timeout)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2A, ADF4377_002A_VCO_ALC_TO_MSB_MSK, + FIELD_PREP(ADF4377_002A_VCO_ALC_TO_MSB_MSK, + st->vco_alc_timeout >> 8)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x26, + FIELD_PREP(ADF4377_0026_VCO_BAND_DIV_MSK, st->vco_band_div)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x2D, + FIELD_PREP(ADF4377_002D_ADC_CLK_DIV_MSK, st->adc_clk_div)); + if (ret) + goto exit; + + st->clkout_div_sel = 0; + + f_vco = freq; + + while (f_vco < ADF4377_MIN_VCO_FREQ) { + f_vco <<= 1; + st->clkout_div_sel++; + } + + st->n_int = div_u64(freq, st->f_pfd); + + ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_RDBLR_MSK | + ADF4377_0011_N_INT_MSB_MSK, + FIELD_PREP(ADF4377_0011_EN_RDBLR_MSK, 0) | + FIELD_PREP(ADF4377_0011_N_INT_MSB_MSK, st->n_int >> 8)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x12, ADF4377_0012_R_DIV_MSK | + ADF4377_0012_CLKOUT_DIV_MSK, + FIELD_PREP(ADF4377_0012_CLKOUT_DIV_MSK, st->clkout_div_sel) | + FIELD_PREP(ADF4377_0012_R_DIV_MSK, st->ref_div_factor)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x10, + FIELD_PREP(ADF4377_0010_N_INT_LSB_MSK, st->n_int)); + if (ret) + goto exit; + + ret = regmap_read_poll_timeout(st->regmap, 0x49, read_val, + !(read_val & (ADF4377_0049_FSM_BUSY_MSK)), 200, 200 * 100); + if (ret) + goto exit; + + /* Disable EN_DNCLK, EN_DRCLK */ + ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | + ADF4377_001C_EN_DRCLK_MSK, + FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 0) | + FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 0)); + if (ret) + goto exit; + + /* Disable EN_ADC_CLK */ + ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, + FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 0)); + if (ret) + goto exit; + + /* Set output Amplitude */ + ret = regmap_update_bits(st->regmap, 0x19, ADF4377_0019_CLKOUT2_OP_MSK | + ADF4377_0019_CLKOUT1_OP_MSK, + FIELD_PREP(ADF4377_0019_CLKOUT1_OP_MSK, + ADF4377_0019_CLKOUT_420MV) | + FIELD_PREP(ADF4377_0019_CLKOUT2_OP_MSK, + ADF4377_0019_CLKOUT_420MV)); + +exit: + mutex_unlock(&st->lock); + + return ret; +} + +static void adf4377_gpio_init(struct adf4377_state *st) +{ + if (st->gpio_ce) { + gpiod_set_value(st->gpio_ce, 1); + + /* Delay for SPI register bits to settle to their power-on reset state */ + fsleep(200); + } + + if (st->gpio_enclk1) + gpiod_set_value(st->gpio_enclk1, 1); + + if (st->gpio_enclk2) + gpiod_set_value(st->gpio_enclk2, 1); +} + +static int adf4377_init(struct adf4377_state *st) +{ + struct spi_device *spi = st->spi; + int ret; + + adf4377_gpio_init(st); + + ret = adf4377_soft_reset(st); + if (ret) { + dev_err(&spi->dev, "Failed to soft reset.\n"); + return ret; + } + + ret = regmap_multi_reg_write(st->regmap, adf4377_reg_defaults, + ARRAY_SIZE(adf4377_reg_defaults)); + if (ret) { + dev_err(&spi->dev, "Failed to set default registers.\n"); + return ret; + } + + ret = regmap_update_bits(st->regmap, 0x00, + ADF4377_0000_SDO_ACTIVE_MSK | ADF4377_0000_SDO_ACTIVE_R_MSK, + FIELD_PREP(ADF4377_0000_SDO_ACTIVE_MSK, + ADF4377_0000_SDO_ACTIVE_SPI_4W) | + FIELD_PREP(ADF4377_0000_SDO_ACTIVE_R_MSK, + ADF4377_0000_SDO_ACTIVE_SPI_4W)); + if (ret) { + dev_err(&spi->dev, "Failed to set 4-Wire Operation.\n"); + return ret; + } + + st->clkin_freq = clk_get_rate(st->clkin); + + /* Power Up */ + ret = regmap_write(st->regmap, 0x1a, + FIELD_PREP(ADF4377_001A_PD_ALL_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_RDIV_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_NDIV_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_VCO_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_LD_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_PFDCP_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 0)); + if (ret) { + dev_err(&spi->dev, "Failed to set power down registers.\n"); + return ret; + } + + /* Set Mux Output */ + ret = regmap_update_bits(st->regmap, 0x1D, + ADF4377_001D_MUXOUT_MSK, + FIELD_PREP(ADF4377_001D_MUXOUT_MSK, st->muxout_select)); + if (ret) + return ret; + + /* Compute PFD */ + st->ref_div_factor = 0; + do { + st->ref_div_factor++; + st->f_pfd = st->clkin_freq / st->ref_div_factor; + } while (st->f_pfd > ADF4377_MAX_FREQ_PFD); + + if (st->f_pfd > ADF4377_MAX_FREQ_PFD || st->f_pfd < ADF4377_MIN_FREQ_PFD) + return -EINVAL; + + st->f_div_rclk = st->f_pfd; + + if (st->f_pfd <= ADF4377_FREQ_PFD_80MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 0; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_125MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 1; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_160MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 0; + st->f_div_rclk /= 2; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_250MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 1; + st->f_div_rclk /= 2; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_320MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; + st->dclk_mode = 0; + st->f_div_rclk /= 4; + } else { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; + st->dclk_mode = 1; + st->f_div_rclk /= 4; + } + + st->synth_lock_timeout = DIV_ROUND_UP(st->f_div_rclk, 50000); + st->vco_alc_timeout = DIV_ROUND_UP(st->f_div_rclk, 20000); + st->vco_band_div = DIV_ROUND_UP(st->f_div_rclk, 150000 * 16 * (1 << st->dclk_mode)); + st->adc_clk_div = DIV_ROUND_UP((st->f_div_rclk / 400000 - 2), 4); + + return 0; +} + +static ssize_t adf4377_read(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct adf4377_state *st = iio_priv(indio_dev); + u64 val = 0; + int ret; + + switch ((u32)private) { + case ADF4377_FREQ: + ret = adf4377_get_freq(st, &val); + if (ret) + return ret; + + return sysfs_emit(buf, "%llu\n", val); + default: + return -EINVAL; + } +} + +static ssize_t adf4377_write(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, const char *buf, + size_t len) +{ + struct adf4377_state *st = iio_priv(indio_dev); + unsigned long long freq; + int ret; + + switch ((u32)private) { + case ADF4377_FREQ: + ret = kstrtoull(buf, 10, &freq); + if (ret) + return ret; + + ret = adf4377_set_freq(st, freq); + if (ret) + return ret; + + return len; + default: + return -EINVAL; + } +} + +#define _ADF4377_EXT_INFO(_name, _shared, _ident) { \ + .name = _name, \ + .read = adf4377_read, \ + .write = adf4377_write, \ + .private = _ident, \ + .shared = _shared, \ + } + +static const struct iio_chan_spec_ext_info adf4377_ext_info[] = { + /* + * Usually we use IIO_CHAN_INFO_FREQUENCY, but there are + * values > 2^32 in order to support the entire frequency range + * in Hz. + */ + _ADF4377_EXT_INFO("frequency", IIO_SEPARATE, ADF4377_FREQ), + { } +}; + +static const struct iio_chan_spec adf4377_channels[] = { + { + .type = IIO_ALTVOLTAGE, + .indexed = 1, + .output = 1, + .channel = 0, + .ext_info = adf4377_ext_info, + }, +}; + +static int adf4377_properties_parse(struct adf4377_state *st) +{ + struct spi_device *spi = st->spi; + const char *str; + int ret; + + st->clkin = devm_clk_get_enabled(&spi->dev, "ref_in"); + if (IS_ERR(st->clkin)) + return dev_err_probe(&spi->dev, PTR_ERR(st->clkin), + "failed to get the reference input clock\n"); + + st->gpio_ce = devm_gpiod_get_optional(&st->spi->dev, "chip-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_ce)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_ce), + "failed to get the CE GPIO\n"); + + st->gpio_enclk1 = devm_gpiod_get_optional(&st->spi->dev, "clk1-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_enclk1)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk1), + "failed to get the CE GPIO\n"); + + st->gpio_enclk2 = devm_gpiod_get_optional(&st->spi->dev, "clk2-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_enclk2)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk2), + "failed to get the CE GPIO\n"); + + ret = device_property_read_string(&spi->dev, "adi,muxout-select", &str); + if (ret) { + st->muxout_select = ADF4377_MUXOUT_HIGH_Z; + } else { + ret = match_string(adf4377_muxout_modes, ARRAY_SIZE(adf4377_muxout_modes), str); + if (ret < 0) + return ret; + + st->muxout_select = ret; + } + + return 0; +} + +static int adf4377_freq_change(struct notifier_block *nb, unsigned long action, void *data) +{ + struct adf4377_state *st = container_of(nb, struct adf4377_state, nb); + int ret; + + if (action == POST_RATE_CHANGE) { + mutex_lock(&st->lock); + ret = notifier_from_errno(adf4377_init(st)); + mutex_unlock(&st->lock); + return ret; + } + + return NOTIFY_OK; +} + +static int adf4377_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct regmap *regmap; + struct adf4377_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + regmap = devm_regmap_init_spi(spi, &adf4377_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + st = iio_priv(indio_dev); + + indio_dev->info = &adf4377_info; + indio_dev->name = "adf4377"; + indio_dev->channels = adf4377_channels; + indio_dev->num_channels = ARRAY_SIZE(adf4377_channels); + + st->regmap = regmap; + st->spi = spi; + mutex_init(&st->lock); + + ret = adf4377_properties_parse(st); + if (ret) + return ret; + + st->nb.notifier_call = adf4377_freq_change; + ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb); + if (ret) + return ret; + + ret = adf4377_init(st); + if (ret) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct spi_device_id adf4377_id[] = { + { "adf4377", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, adf4377_id); + +static const struct of_device_id adf4377_of_match[] = { + { .compatible = "adi,adf4377" }, + {} +}; +MODULE_DEVICE_TABLE(of, adf4377_of_match); + +static struct spi_driver adf4377_driver = { + .driver = { + .name = "adf4377", + .of_match_table = adf4377_of_match, + }, + .probe = adf4377_probe, + .id_table = adf4377_id, +}; +module_spi_driver(adf4377_driver); + +MODULE_AUTHOR("Antoniu Miclaus "); +MODULE_DESCRIPTION("Analog Devices ADF4377"); +MODULE_LICENSE("GPL"); -- GitLab From 78a01feb4024ffb6c6321e45dc2bfcafb2d1d1e5 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Tue, 25 Oct 2022 15:39:23 +0000 Subject: [PATCH 1156/1480] ftrace: Clean comments related to FTRACE_OPS_FL_PER_CPU Commit b3a88803ac5b ("ftrace: Kill FTRACE_OPS_FL_PER_CPU") didn't completely remove the comments related to FTRACE_OPS_FL_PER_CPU. Link: https://lkml.kernel.org/r/20221025153923.1995973-1-zhengyejian1@huawei.com Fixes: b3a88803ac5b ("ftrace: Kill FTRACE_OPS_FL_PER_CPU") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ftrace.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 33236241f2364..65a5d36463e05 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -163,7 +163,7 @@ static void ftrace_sync_ipi(void *data) static ftrace_func_t ftrace_ops_get_list_func(struct ftrace_ops *ops) { /* - * If this is a dynamic, RCU, or per CPU ops, or we force list func, + * If this is a dynamic or RCU ops, or we force list func, * then it needs to call the list anyway. */ if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_RCU) || @@ -3071,8 +3071,6 @@ out: /* * Dynamic ops may be freed, we must make sure that all * callers are done before leaving this function. - * The same goes for freeing the per_cpu data of the per_cpu - * ops. */ if (ops->flags & FTRACE_OPS_FL_DYNAMIC) { /* @@ -7519,8 +7517,6 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, /* * Check the following for each ops before calling their func: * if RCU flag is set, then rcu_is_watching() must be true - * if PER_CPU is set, then ftrace_function_local_disable() - * must be false * Otherwise test if the ip matches the ops filter * * If any of the above fails then the op->func() is not executed. @@ -7570,8 +7566,8 @@ NOKPROBE_SYMBOL(arch_ftrace_ops_list_func); /* * If there's only one function registered but it does not support - * recursion, needs RCU protection and/or requires per cpu handling, then - * this function will be called by the mcount trampoline. + * recursion, needs RCU protection, then this function will be called + * by the mcount trampoline. */ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct ftrace_regs *fregs) -- GitLab From 8230f27b1ccc4b8976c137e3d6d690f9d4ffca8d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Fri, 14 Oct 2022 08:04:56 -0400 Subject: [PATCH 1157/1480] tracing: Add __cpumask to denote a trace event field that is a cpumask_t The trace events have a __bitmask field that can be used for anything that requires bitmasks. Although currently it is only used for CPU masks, it could be used in the future for any type of bitmasks. There is some user space tooling that wants to know if a field is a CPU mask and not just some random unsigned long bitmask. Introduce "__cpumask()" helper functions that work the same as the current __bitmask() helpers but displays in the format file: field:__data_loc cpumask_t *[] mask; offset:36; size:4; signed:0; Instead of: field:__data_loc unsigned long[] mask; offset:32; size:4; signed:0; The main difference is the type. Instead of "unsigned long" it is "cpumask_t *". Note, this type field needs to be a real type in the __dynamic_array() logic that both __cpumask and__bitmask use, but the comparison field requires it to be a scalar type whereas cpumask_t is a structure (non-scalar). But everything works when making it a pointer. Valentin added changes to remove the need of passing in "nr_bits" and the __cpumask will always use nr_cpumask_bits as its size. Link: https://lkml.kernel.org/r/20221014080456.1d32b989@rorschach.local.home Requested-by: Valentin Schneider Reviewed-by: Valentin Schneider Signed-off-by: Valentin Schneider Signed-off-by: Steven Rostedt (Google) --- include/trace/bpf_probe.h | 6 ++++ include/trace/perf.h | 6 ++++ include/trace/stages/stage1_struct_define.h | 6 ++++ include/trace/stages/stage2_data_offsets.h | 6 ++++ include/trace/stages/stage3_trace_output.h | 6 ++++ include/trace/stages/stage4_event_fields.h | 6 ++++ include/trace/stages/stage5_get_offsets.h | 6 ++++ include/trace/stages/stage6_event_callback.h | 20 ++++++++++++ include/trace/stages/stage7_class_define.h | 2 ++ samples/trace_events/trace-events-sample.c | 2 +- samples/trace_events/trace-events-sample.h | 34 +++++++++++++++----- 11 files changed, 91 insertions(+), 9 deletions(-) diff --git a/include/trace/bpf_probe.h b/include/trace/bpf_probe.h index 6a13220d2d27b..155c495b89ead 100644 --- a/include/trace/bpf_probe.h +++ b/include/trace/bpf_probe.h @@ -21,6 +21,9 @@ #undef __get_bitmask #define __get_bitmask(field) (char *)__get_dynamic_array(field) +#undef __get_cpumask +#define __get_cpumask(field) (char *)__get_dynamic_array(field) + #undef __get_sockaddr #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field)) @@ -40,6 +43,9 @@ #undef __get_rel_bitmask #define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field) +#undef __get_rel_cpumask +#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) + #undef __get_rel_sockaddr #define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field)) diff --git a/include/trace/perf.h b/include/trace/perf.h index 5800d13146c3d..8f3bf1e177070 100644 --- a/include/trace/perf.h +++ b/include/trace/perf.h @@ -21,6 +21,9 @@ #undef __get_bitmask #define __get_bitmask(field) (char *)__get_dynamic_array(field) +#undef __get_cpumask +#define __get_cpumask(field) (char *)__get_dynamic_array(field) + #undef __get_sockaddr #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field)) @@ -41,6 +44,9 @@ #undef __get_rel_bitmask #define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field) +#undef __get_rel_cpumask +#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) + #undef __get_rel_sockaddr #define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field)) diff --git a/include/trace/stages/stage1_struct_define.h b/include/trace/stages/stage1_struct_define.h index 1b7bab60434c1..69e0dae453bfa 100644 --- a/include/trace/stages/stage1_struct_define.h +++ b/include/trace/stages/stage1_struct_define.h @@ -32,6 +32,9 @@ #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(char, item, -1) +#undef __cpumask +#define __cpumask(item) __dynamic_array(char, item, -1) + #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) @@ -47,6 +50,9 @@ #undef __rel_bitmask #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(char, item, -1) +#undef __rel_cpumask +#define __rel_cpumask(item) __rel_dynamic_array(char, item, -1) + #undef __rel_sockaddr #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len) diff --git a/include/trace/stages/stage2_data_offsets.h b/include/trace/stages/stage2_data_offsets.h index 1b7a8f764fddd..469b6a64293de 100644 --- a/include/trace/stages/stage2_data_offsets.h +++ b/include/trace/stages/stage2_data_offsets.h @@ -38,6 +38,9 @@ #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) +#undef __cpumask +#define __cpumask(item) __dynamic_array(unsigned long, item, -1) + #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) @@ -53,5 +56,8 @@ #undef __rel_bitmask #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1) +#undef __rel_cpumask +#define __rel_cpumask(item) __rel_dynamic_array(unsigned long, item, -1) + #undef __rel_sockaddr #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len) diff --git a/include/trace/stages/stage3_trace_output.h b/include/trace/stages/stage3_trace_output.h index e3b183e9d18ea..66374df61ed30 100644 --- a/include/trace/stages/stage3_trace_output.h +++ b/include/trace/stages/stage3_trace_output.h @@ -42,6 +42,9 @@ trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ }) +#undef __get_cpumask +#define __get_cpumask(field) __get_bitmask(field) + #undef __get_rel_bitmask #define __get_rel_bitmask(field) \ ({ \ @@ -51,6 +54,9 @@ trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ }) +#undef __get_rel_cpumask +#define __get_rel_cpumask(field) __get_rel_bitmask(field) + #undef __get_sockaddr #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field)) diff --git a/include/trace/stages/stage4_event_fields.h b/include/trace/stages/stage4_event_fields.h index a8fb25f39a99d..f2990d22313cf 100644 --- a/include/trace/stages/stage4_event_fields.h +++ b/include/trace/stages/stage4_event_fields.h @@ -46,6 +46,9 @@ #undef __bitmask #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) +#undef __cpumask +#define __cpumask(item) __dynamic_array(cpumask_t *, item, -1) + #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) @@ -64,5 +67,8 @@ #undef __rel_bitmask #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1) +#undef __rel_cpumask +#define __rel_cpumask(item) __rel_dynamic_array(cpumask_t *, item, -1) + #undef __rel_sockaddr #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len) diff --git a/include/trace/stages/stage5_get_offsets.h b/include/trace/stages/stage5_get_offsets.h index fba4c24ed9e60..ac5c24d3beeb2 100644 --- a/include/trace/stages/stage5_get_offsets.h +++ b/include/trace/stages/stage5_get_offsets.h @@ -82,10 +82,16 @@ #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, \ __bitmask_size_in_longs(nr_bits)) +#undef __cpumask +#define __cpumask(item) __bitmask(item, nr_cpumask_bits) + #undef __rel_bitmask #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, \ __bitmask_size_in_longs(nr_bits)) +#undef __rel_cpumask +#define __rel_cpumask(item) __rel_bitmask(item, nr_cpumask_bits) + #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) diff --git a/include/trace/stages/stage6_event_callback.h b/include/trace/stages/stage6_event_callback.h index 3c554a5853204..49c32394b53fb 100644 --- a/include/trace/stages/stage6_event_callback.h +++ b/include/trace/stages/stage6_event_callback.h @@ -57,6 +57,16 @@ #define __assign_bitmask(dst, src, nr_bits) \ memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) +#undef __cpumask +#define __cpumask(item) __dynamic_array(unsigned long, item, -1) + +#undef __get_cpumask +#define __get_cpumask(field) (char *)__get_dynamic_array(field) + +#undef __assign_cpumask +#define __assign_cpumask(dst, src) \ + memcpy(__get_cpumask(dst), (src), __bitmask_size_in_bytes(nr_cpumask_bits)) + #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) @@ -98,6 +108,16 @@ #define __assign_rel_bitmask(dst, src, nr_bits) \ memcpy(__get_rel_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) +#undef __rel_cpumask +#define __rel_cpumask(item) __rel_dynamic_array(unsigned long, item, -1) + +#undef __get_rel_cpumask +#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) + +#undef __assign_rel_cpumask +#define __assign_rel_cpumask(dst, src) \ + memcpy(__get_rel_cpumask(dst), (src), __bitmask_size_in_bytes(nr_cpumask_bits)) + #undef __rel_sockaddr #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len) diff --git a/include/trace/stages/stage7_class_define.h b/include/trace/stages/stage7_class_define.h index 8a7ec24c246dd..8795429f388b0 100644 --- a/include/trace/stages/stage7_class_define.h +++ b/include/trace/stages/stage7_class_define.h @@ -13,11 +13,13 @@ #undef __get_dynamic_array_len #undef __get_str #undef __get_bitmask +#undef __get_cpumask #undef __get_sockaddr #undef __get_rel_dynamic_array #undef __get_rel_dynamic_array_len #undef __get_rel_str #undef __get_rel_bitmask +#undef __get_rel_cpumask #undef __get_rel_sockaddr #undef __print_array #undef __print_hex_dump diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c index 608c4ae3b08a3..ecc7db237f2ef 100644 --- a/samples/trace_events/trace-events-sample.c +++ b/samples/trace_events/trace-events-sample.c @@ -50,7 +50,7 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...) trace_foo_with_template_print("I have to be different", cnt); - trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask); + trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask, current->cpus_ptr); } static void simple_thread_func(int cnt) diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h index 1a92226202fc5..fb4548a44153c 100644 --- a/samples/trace_events/trace-events-sample.h +++ b/samples/trace_events/trace-events-sample.h @@ -200,6 +200,16 @@ * * __assign_bitmask(target_cpus, cpumask_bits(bar), nr_cpumask_bits); * + * __cpumask: This is pretty much the same as __bitmask but is specific for + * CPU masks. The type displayed to the user via the format files will + * be "cpumaks_t" such that user space may deal with them differently + * if they choose to do so, and the bits is always set to nr_cpumask_bits. + * + * __cpumask(target_cpu) + * + * To assign a cpumask, use the __assign_cpumask() helper macro. + * + * __assign_cpumask(target_cpus, cpumask_bits(bar)); * * fast_assign: This is a C like function that is used to store the items * into the ring buffer. A special variable called "__entry" will be the @@ -212,8 +222,8 @@ * This is also used to print out the data from the trace files. * Again, the __entry macro is used to access the data from the ring buffer. * - * Note, __dynamic_array, __string, and __bitmask require special helpers - * to access the data. + * Note, __dynamic_array, __string, __bitmask and __cpumask require special + * helpers to access the data. * * For __dynamic_array(int, foo, bar) use __get_dynamic_array(foo) * Use __get_dynamic_array_len(foo) to get the length of the array @@ -226,6 +236,8 @@ * * For __bitmask(target_cpus, nr_cpumask_bits) use __get_bitmask(target_cpus) * + * For __cpumask(target_cpus) use __get_cpumask(target_cpus) + * * * Note, that for both the assign and the printk, __entry is the handler * to the data structure in the ring buffer, and is defined by the @@ -288,6 +300,7 @@ TRACE_EVENT(foo_bar, __dynamic_array(int, list, __length_of(lst)) __string( str, string ) __bitmask( cpus, num_possible_cpus() ) + __cpumask( cpum ) __vstring( vstr, fmt, va ) ), @@ -299,9 +312,10 @@ TRACE_EVENT(foo_bar, __assign_str(str, string); __assign_vstr(vstr, fmt, va); __assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus()); + __assign_cpumask(cpum, cpumask_bits(mask)); ), - TP_printk("foo %s %d %s %s %s %s (%s) %s", __entry->foo, __entry->bar, + TP_printk("foo %s %d %s %s %s %s (%s) (%s) %s", __entry->foo, __entry->bar, /* * Notice here the use of some helper functions. This includes: @@ -345,7 +359,8 @@ TRACE_EVENT(foo_bar, __print_array(__get_dynamic_array(list), __get_dynamic_array_len(list) / sizeof(int), sizeof(int)), - __get_str(str), __get_bitmask(cpus), __get_str(vstr)) + __get_str(str), __get_bitmask(cpus), __get_cpumask(cpus), + __get_str(vstr)) ); /* @@ -542,15 +557,16 @@ DEFINE_EVENT_PRINT(foo_template, foo_with_template_print, TRACE_EVENT(foo_rel_loc, - TP_PROTO(const char *foo, int bar, unsigned long *mask), + TP_PROTO(const char *foo, int bar, unsigned long *mask, const cpumask_t *cpus), - TP_ARGS(foo, bar, mask), + TP_ARGS(foo, bar, mask, cpus), TP_STRUCT__entry( __rel_string( foo, foo ) __field( int, bar ) __rel_bitmask( bitmask, BITS_PER_BYTE * sizeof(unsigned long) ) + __rel_cpumask( cpumask ) ), TP_fast_assign( @@ -558,10 +574,12 @@ TRACE_EVENT(foo_rel_loc, __entry->bar = bar; __assign_rel_bitmask(bitmask, mask, BITS_PER_BYTE * sizeof(unsigned long)); + __assign_rel_cpumask(cpumask, cpus); ), - TP_printk("foo_rel_loc %s, %d, %s", __get_rel_str(foo), __entry->bar, - __get_rel_bitmask(bitmask)) + TP_printk("foo_rel_loc %s, %d, %s, %s", __get_rel_str(foo), __entry->bar, + __get_rel_bitmask(bitmask), + __get_rel_cpumask(cpumask)) ); #endif -- GitLab From a01fdc897fa56ffb596d0a0cd7ea2ab3bd8398c5 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Thu, 20 Oct 2022 21:00:56 -0400 Subject: [PATCH 1158/1480] tracing: Add trace_trigger kernel command line option Allow triggers to be enabled at kernel boot up. For example: trace_trigger="sched_switch.stacktrace if prev_state == 2" The above will enable the stacktrace trigger on top of the sched_switch event and only trigger if its prev_state is 2 (TASK_UNINTERRUPTIBLE). Then at boot up, a stacktrace will trigger and be recorded in the tracing ring buffer every time the sched_switch happens where the previous state is TASK_INTERRUPTIBLE. Another useful trigger would be "traceoff" which can stop tracing on an event if a field of the event matches a certain value defined by the filter ("if" statement). Link: https://lore.kernel.org/linux-trace-kernel/20221020210056.0d8d0a5b@gandalf.local.home Signed-off-by: Steven Rostedt (Google) --- .../admin-guide/kernel-parameters.txt | 19 +++++ kernel/trace/trace_events.c | 72 ++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index a465d5242774a..ccf91a4bf113f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6257,6 +6257,25 @@ See also Documentation/trace/ftrace.rst "trace options" section. + trace_trigger=[trigger-list] + [FTRACE] Add a event trigger on specific events. + Set a trigger on top of a specific event, with an optional + filter. + + The format is is "trace_trigger=.[ if ],..." + Where more than one trigger may be specified that are comma deliminated. + + For example: + + trace_trigger="sched_switch.stacktrace if prev_state == 2" + + The above will enable the "stacktrace" trigger on the "sched_switch" + event but only trigger it if the "prev_state" of the "sched_switch" + event is "2" (TASK_UNINTERUPTIBLE). + + See also "Event triggers" in Documentation/trace/events.rst + + traceoff_on_warning [FTRACE] enable this option to disable tracing when a warning is hit. This turns off "tracing_on". Tracing can diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index f71ea6e79b3c8..3bfaf560ecc46 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2796,6 +2796,44 @@ trace_create_new_event(struct trace_event_call *call, return file; } +#ifdef CONFIG_HIST_TRIGGERS +#define MAX_BOOT_TRIGGERS 32 + +static struct boot_triggers { + const char *event; + char *trigger; +} bootup_triggers[MAX_BOOT_TRIGGERS]; + +static char bootup_trigger_buf[COMMAND_LINE_SIZE]; +static int nr_boot_triggers; + +static __init int setup_trace_triggers(char *str) +{ + char *trigger; + char *buf; + int i; + + strlcpy(bootup_trigger_buf, str, COMMAND_LINE_SIZE); + ring_buffer_expanded = true; + disable_tracing_selftest("running event triggers"); + + buf = bootup_trigger_buf; + for (i = 0; i < MAX_BOOT_TRIGGERS; i++) { + trigger = strsep(&buf, ","); + if (!trigger) + break; + bootup_triggers[i].event = strsep(&trigger, "."); + bootup_triggers[i].trigger = strsep(&trigger, "."); + if (!bootup_triggers[i].trigger) + break; + } + + nr_boot_triggers = i; + return 1; +} +__setup("trace_trigger=", setup_trace_triggers); +#endif + /* Add an event to a trace directory */ static int __trace_add_new_event(struct trace_event_call *call, struct trace_array *tr) @@ -2812,6 +2850,28 @@ __trace_add_new_event(struct trace_event_call *call, struct trace_array *tr) return event_define_fields(call); } +#ifdef CONFIG_HIST_TRIGGERS +static void trace_early_triggers(struct trace_event_file *file, const char *name) +{ + int ret; + int i; + + for (i = 0; i < nr_boot_triggers; i++) { + if (strcmp(name, bootup_triggers[i].event)) + continue; + mutex_lock(&event_mutex); + ret = trigger_process_regex(file, bootup_triggers[i].trigger); + mutex_unlock(&event_mutex); + if (ret) + pr_err("Failed to register trigger '%s' on event %s\n", + bootup_triggers[i].trigger, + bootup_triggers[i].event); + } +} +#else +static inline void trace_early_triggers(struct trace_event_file *file, const char *name) { } +#endif + /* * Just create a descriptor for early init. A descriptor is required * for enabling events at boot. We want to enable events before @@ -2822,12 +2882,19 @@ __trace_early_add_new_event(struct trace_event_call *call, struct trace_array *tr) { struct trace_event_file *file; + int ret; file = trace_create_new_event(call, tr); if (!file) return -ENOMEM; - return event_define_fields(call); + ret = event_define_fields(call); + if (ret) + return ret; + + trace_early_triggers(file, trace_event_name(call)); + + return 0; } struct ftrace_module_file_ops; @@ -3735,6 +3802,8 @@ static __init int event_trace_enable(void) list_add(&call->list, &ftrace_events); } + register_trigger_cmds(); + /* * We need the top trace array to have a working set of trace * points at early init, before the debug files and directories @@ -3749,7 +3818,6 @@ static __init int event_trace_enable(void) register_event_cmds(); - register_trigger_cmds(); return 0; } -- GitLab From 04aabc32fb677f91d676fd306bca1043805e78d5 Mon Sep 17 00:00:00 2001 From: Song Chen Date: Thu, 20 Oct 2022 22:06:51 +0800 Subject: [PATCH 1159/1480] ring_buffer: Remove unused "event" parameter After commit a389d86f7fd0 ("ring-buffer: Have nested events still record running time stamp"), the "event" parameter is no longer used in either ring_buffer_unlock_commit() or rb_commit(). Best to remove it. Link: https://lkml.kernel.org/r/1666274811-24138-1-git-send-email-chensong_2000@189.cn Signed-off-by: Song Chen Signed-off-by: Steven Rostedt (Google) --- include/linux/ring_buffer.h | 3 +-- kernel/trace/ring_buffer.c | 12 +++++------- kernel/trace/ring_buffer_benchmark.c | 2 +- kernel/trace/trace.c | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 3c7d295746f67..782e14f62201f 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -113,8 +113,7 @@ void ring_buffer_change_overwrite(struct trace_buffer *buffer, int val); struct ring_buffer_event *ring_buffer_lock_reserve(struct trace_buffer *buffer, unsigned long length); -int ring_buffer_unlock_commit(struct trace_buffer *buffer, - struct ring_buffer_event *event); +int ring_buffer_unlock_commit(struct trace_buffer *buffer); int ring_buffer_write(struct trace_buffer *buffer, unsigned long length, void *data); diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index b21bf14bae9bd..843818ee4814e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -3180,8 +3180,7 @@ static inline void rb_event_discard(struct ring_buffer_event *event) event->time_delta = 1; } -static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer, - struct ring_buffer_event *event) +static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer) { local_inc(&cpu_buffer->entries); rb_end_commit(cpu_buffer); @@ -3383,15 +3382,14 @@ void ring_buffer_nest_end(struct trace_buffer *buffer) * * Must be paired with ring_buffer_lock_reserve. */ -int ring_buffer_unlock_commit(struct trace_buffer *buffer, - struct ring_buffer_event *event) +int ring_buffer_unlock_commit(struct trace_buffer *buffer) { struct ring_buffer_per_cpu *cpu_buffer; int cpu = raw_smp_processor_id(); cpu_buffer = buffer->buffers[cpu]; - rb_commit(cpu_buffer, event); + rb_commit(cpu_buffer); rb_wakeups(buffer, cpu_buffer); @@ -3977,7 +3975,7 @@ int ring_buffer_write(struct trace_buffer *buffer, memcpy(body, data, length); - rb_commit(cpu_buffer, event); + rb_commit(cpu_buffer); rb_wakeups(buffer, cpu_buffer); @@ -5998,7 +5996,7 @@ static __init int rb_write_something(struct rb_test_data *data, bool nested) } out: - ring_buffer_unlock_commit(data->buffer, event); + ring_buffer_unlock_commit(data->buffer); return 0; } diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c index 78e576575b79e..aef34673d79d0 100644 --- a/kernel/trace/ring_buffer_benchmark.c +++ b/kernel/trace/ring_buffer_benchmark.c @@ -258,7 +258,7 @@ static void ring_buffer_producer(void) hit++; entry = ring_buffer_event_data(event); *entry = smp_processor_id(); - ring_buffer_unlock_commit(buffer, event); + ring_buffer_unlock_commit(buffer); } } end_time = ktime_get(); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5cfc95a52bc37..5c97dbef741b4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -999,7 +999,7 @@ __buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *ev /* ring_buffer_unlock_commit() enables preemption */ preempt_enable_notrace(); } else - ring_buffer_unlock_commit(buffer, event); + ring_buffer_unlock_commit(buffer); } /** -- GitLab From b179d48b6aab21f3999f5006685ea4254c0618a9 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Thu, 17 Nov 2022 14:46:18 +0100 Subject: [PATCH 1160/1480] tracing/osnoise: Add osnoise/options file Add the tracing/osnoise/options file to control osnoise/timerlat tracer features. It is a single file to contain multiple features, similar to the sched/features file. Reading the file displays a list of options. Writing the OPTION_NAME enables it, writing NO_OPTION_NAME disables it. The DEAFULTS is a particular option that resets the options to the default ones. It uses a bitmask to keep track of the status of the option. When needed, we can add a list of static keys, but for now it does not justify the memory increase. Link: https://lkml.kernel.org/r/f8d34aefdb225d2603fcb4c02a120832a0cd3339.1668692096.git.bristot@kernel.org Cc: Daniel Bristot de Oliveira Cc: Masami Hiramatsu Cc: Jonathan Corbet Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_osnoise.c | 170 +++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 4300c5dc4e5db..17b77fe3950b8 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -48,6 +48,19 @@ #define DEFAULT_TIMERLAT_PERIOD 1000 /* 1ms */ #define DEFAULT_TIMERLAT_PRIO 95 /* FIFO 95 */ +/* + * osnoise/options entries. + */ +enum osnoise_options_index { + OSN_DEFAULTS = 0, + OSN_MAX +}; + +static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS" }; + +#define OSN_DEFAULT_OPTIONS 0 +unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; + /* * trace_array of the enabled osnoise/timerlat instances. */ @@ -1860,6 +1873,150 @@ static void osnoise_init_hotplug_support(void) } #endif /* CONFIG_HOTPLUG_CPU */ +/* + * seq file functions for the osnoise/options file. + */ +static void *s_options_start(struct seq_file *s, loff_t *pos) +{ + int option = *pos; + + mutex_lock(&interface_lock); + + if (option >= OSN_MAX) + return NULL; + + return pos; +} + +static void *s_options_next(struct seq_file *s, void *v, loff_t *pos) +{ + int option = ++(*pos); + + if (option >= OSN_MAX) + return NULL; + + return pos; +} + +static int s_options_show(struct seq_file *s, void *v) +{ + loff_t *pos = v; + int option = *pos; + + if (option == OSN_DEFAULTS) { + if (osnoise_options == OSN_DEFAULT_OPTIONS) + seq_printf(s, "%s", osnoise_options_str[option]); + else + seq_printf(s, "NO_%s", osnoise_options_str[option]); + goto out; + } + + if (test_bit(option, &osnoise_options)) + seq_printf(s, "%s", osnoise_options_str[option]); + else + seq_printf(s, "NO_%s", osnoise_options_str[option]); + +out: + if (option != OSN_MAX) + seq_puts(s, " "); + + return 0; +} + +static void s_options_stop(struct seq_file *s, void *v) +{ + seq_puts(s, "\n"); + mutex_unlock(&interface_lock); +} + +static const struct seq_operations osnoise_options_seq_ops = { + .start = s_options_start, + .next = s_options_next, + .show = s_options_show, + .stop = s_options_stop +}; + +static int osnoise_options_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &osnoise_options_seq_ops); +}; + +/** + * osnoise_options_write - Write function for "options" entry + * @filp: The active open file structure + * @ubuf: The user buffer that contains the value to write + * @cnt: The maximum number of bytes to write to "file" + * @ppos: The current position in @file + * + * Writing the option name sets the option, writing the "NO_" + * prefix in front of the option name disables it. + * + * Writing "DEFAULTS" resets the option values to the default ones. + */ +static ssize_t osnoise_options_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + int running, option, enable, retval; + char buf[256], *option_str; + + if (cnt >= 256) + return -EINVAL; + + if (copy_from_user(buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + if (strncmp(buf, "NO_", 3)) { + option_str = strstrip(buf); + enable = true; + } else { + option_str = strstrip(&buf[3]); + enable = false; + } + + option = match_string(osnoise_options_str, OSN_MAX, option_str); + if (option < 0) + return -EINVAL; + + /* + * trace_types_lock is taken to avoid concurrency on start/stop. + */ + mutex_lock(&trace_types_lock); + running = osnoise_has_registered_instances(); + if (running) + stop_per_cpu_kthreads(); + + mutex_lock(&interface_lock); + /* + * avoid CPU hotplug operations that might read options. + */ + cpus_read_lock(); + + retval = cnt; + + if (enable) { + if (option == OSN_DEFAULTS) + osnoise_options = OSN_DEFAULT_OPTIONS; + else + set_bit(option, &osnoise_options); + } else { + if (option == OSN_DEFAULTS) + retval = -EINVAL; + else + clear_bit(option, &osnoise_options); + } + + cpus_read_unlock(); + mutex_unlock(&interface_lock); + + if (running) + start_per_cpu_kthreads(); + mutex_unlock(&trace_types_lock); + + return retval; +} + /* * osnoise_cpus_read - Read function for reading the "cpus" file * @filp: The active open file structure @@ -2042,6 +2199,14 @@ static const struct file_operations cpus_fops = { .llseek = generic_file_llseek, }; +static const struct file_operations osnoise_options_fops = { + .open = osnoise_options_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = osnoise_options_write +}; + #ifdef CONFIG_TIMERLAT_TRACER #ifdef CONFIG_STACKTRACE static int init_timerlat_stack_tracefs(struct dentry *top_dir) @@ -2128,6 +2293,11 @@ static int init_tracefs(void) if (!tmp) goto err; + tmp = trace_create_file("options", TRACE_MODE_WRITE, top_dir, NULL, + &osnoise_options_fops); + if (!tmp) + goto err; + ret = init_timerlat_tracefs(top_dir); if (ret) goto err; -- GitLab From 30838fcd81078d078b10209bc18a6357ba4dd5fa Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Thu, 17 Nov 2022 14:46:19 +0100 Subject: [PATCH 1161/1480] tracing/osnoise: Add OSNOISE_WORKLOAD option The osnoise tracer is not only a tracer, and a set of tracepoints, but also a workload dispatcher. In preparation for having other workloads, e.g., in user-space, add an option to avoid dispatching the workload. By not dispatching the workload, the osnoise: tracepoints become generic events to measure the execution time of *any* task on Linux. For example: # cd /sys/kernel/tracing/ # cat osnoise/options DEFAULTS OSNOISE_WORKLOAD # echo NO_OSNOISE_WORKLOAD > osnoise/options # cat osnoise/options NO_DEFAULTS NO_OSNOISE_WORKLOAD # echo osnoise > set_event # echo osnoise > current_tracer # tail -8 trace make-94722 [002] d..3. 1371.794507: thread_noise: make:94722 start 1371.794302286 duration 200897 ns sh-121042 [020] d..3. 1371.794534: thread_noise: sh:121042 start 1371.781610976 duration 8943683 ns make-121097 [005] d..3. 1371.794542: thread_noise: make:121097 start 1371.794481522 duration 60444 ns <...>-40 [005] d..3. 1371.794550: thread_noise: migration/5:40 start 1371.794542256 duration 7154 ns -0 [018] dNh2. 1371.794554: irq_noise: reschedule:253 start 1371.794553547 duration 40 ns -0 [018] dNh2. 1371.794561: irq_noise: local_timer:236 start 1371.794556222 duration 4890 ns -0 [018] .Ns2. 1371.794563: softirq_noise: SCHED:7 start 1371.794561803 duration 992 ns -0 [018] d..3. 1371.794566: thread_noise: swapper/18:0 start 1371.781368110 duration 13191798 ns In preparation for the rtla exec_time tracer/tool and rtla osnoise --user option. Link: https://lkml.kernel.org/r/f5cfbd37aefd419eefe9243b4d2fc38ed5753fe4.1668692096.git.bristot@kernel.org Cc: Daniel Bristot de Oliveira Cc: Masami Hiramatsu Cc: Jonathan Corbet Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_osnoise.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 17b77fe3950b8..3f10dd1f2f1ce 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -53,12 +53,13 @@ */ enum osnoise_options_index { OSN_DEFAULTS = 0, + OSN_WORKLOAD, OSN_MAX }; -static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS" }; +static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD" }; -#define OSN_DEFAULT_OPTIONS 0 +#define OSN_DEFAULT_OPTIONS 0x2 unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; /* @@ -1186,11 +1187,12 @@ trace_sched_switch_callback(void *data, bool preempt, unsigned int prev_state) { struct osnoise_variables *osn_var = this_cpu_osn_var(); + int workload = test_bit(OSN_WORKLOAD, &osnoise_options); - if (p->pid != osn_var->pid) + if ((p->pid != osn_var->pid) || !workload) thread_exit(osn_var, p); - if (n->pid != osn_var->pid) + if ((n->pid != osn_var->pid) || !workload) thread_entry(osn_var, n); } @@ -1723,9 +1725,16 @@ static void stop_kthread(unsigned int cpu) struct task_struct *kthread; kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; - if (kthread) + if (kthread) { kthread_stop(kthread); - per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; + per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; + } else { + if (!test_bit(OSN_WORKLOAD, &osnoise_options)) { + per_cpu(per_cpu_osnoise_var, cpu).sampling = false; + barrier(); + return; + } + } } /* @@ -1759,6 +1768,13 @@ static int start_kthread(unsigned int cpu) snprintf(comm, 24, "timerlat/%d", cpu); main = timerlat_main; } else { + /* if no workload, just return */ + if (!test_bit(OSN_WORKLOAD, &osnoise_options)) { + per_cpu(per_cpu_osnoise_var, cpu).sampling = true; + barrier(); + return 0; + } + snprintf(comm, 24, "osnoise/%d", cpu); } -- GitLab From 67543cd6b8eee53959e624b9ce420ca4d47be0c8 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Thu, 17 Nov 2022 14:46:20 +0100 Subject: [PATCH 1162/1480] Documentation/osnoise: Add osnoise/options documentation Add the documentation about the osnoise/options file, along with an explanation about the OSNOISE_WORKLOAD option. Link: https://lkml.kernel.org/r/777af8f3d87beedd304805f98eff6c8291d64226.1668692096.git.bristot@kernel.org Cc: Daniel Bristot de Oliveira Cc: Masami Hiramatsu Cc: Jonathan Corbet Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- Documentation/trace/osnoise-tracer.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/trace/osnoise-tracer.rst b/Documentation/trace/osnoise-tracer.rst index 963def9f97c6e..3c675ed82b27a 100644 --- a/Documentation/trace/osnoise-tracer.rst +++ b/Documentation/trace/osnoise-tracer.rst @@ -109,6 +109,11 @@ The tracer has a set of options inside the osnoise directory, they are: - tracing_threshold: the minimum delta between two time() reads to be considered as noise, in us. When set to 0, the default value will be used, which is currently 5 us. + - osnoise/options: a set of on/off options that can be enabled by + writing the option name to the file or disabled by writing the option + name preceded with the 'NO_' prefix. For example, writing + NO_OSNOISE_WORKLOAD disables the OSNOISE_WORKLOAD option. The + special DEAFAULTS option resets all options to the default value. Additional Tracing ------------------ @@ -150,3 +155,10 @@ tracepoints is smaller than eight us reported in the sample_threshold. The reason roots in the overhead of the entry and exit code that happens before and after any interference execution. This justifies the dual approach: measuring thread and tracing. + +Running osnoise tracer without workload +--------------------------------------- + +By enabling the osnoise tracer with the NO_OSNOISE_WORKLOAD option set, +the osnoise: tracepoints serve to measure the execution time of +any type of Linux task, free from the interference of other tasks. -- GitLab From 9430cd62b6ccdf1f06915cc06561f0e364809604 Mon Sep 17 00:00:00 2001 From: Chuang Wang Date: Mon, 21 Nov 2022 16:08:31 +0800 Subject: [PATCH 1163/1480] tracing/perf: Use strndup_user instead of kzalloc/strncpy_from_user This patch uses strndup_user instead of kzalloc + strncpy_from_user, which makes the code more concise. Link: https://lkml.kernel.org/r/20221121080831.707409-1-nashuiliang@gmail.com Signed-off-by: Chuang Wang Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_event_perf.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 61e3a2620fa3c..05e7912418126 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -251,16 +251,12 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) struct trace_event_call *tp_event; if (p_event->attr.kprobe_func) { - func = kzalloc(KSYM_NAME_LEN, GFP_KERNEL); - if (!func) - return -ENOMEM; - ret = strncpy_from_user( - func, u64_to_user_ptr(p_event->attr.kprobe_func), - KSYM_NAME_LEN); - if (ret == KSYM_NAME_LEN) - ret = -E2BIG; - if (ret < 0) - goto out; + func = strndup_user(u64_to_user_ptr(p_event->attr.kprobe_func), + KSYM_NAME_LEN); + if (IS_ERR(func)) { + ret = PTR_ERR(func); + return (ret == -EINVAL) ? -E2BIG : ret; + } if (func[0] == '\0') { kfree(func); -- GitLab From a76d4648a0bbd624a1322c15073b5032a5135f01 Mon Sep 17 00:00:00 2001 From: Xiu Jianfeng Date: Tue, 22 Nov 2022 17:14:56 +0800 Subject: [PATCH 1164/1480] tracing: Make tracepoint_print_iter static After change in commit 4239174570da ("tracing: Make tracepoint_printk a static_key"), this symbol is not used outside of the file, so mark it static. Link: https://lkml.kernel.org/r/20221122091456.72055-1-xiujianfeng@huawei.com Signed-off-by: Xiu Jianfeng Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 2 +- kernel/trace/trace.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5c97dbef741b4..93a75a97118f1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -85,7 +85,7 @@ void __init disable_tracing_selftest(const char *reason) #endif /* Pipe tracepoints to printk */ -struct trace_iterator *tracepoint_print_iter; +static struct trace_iterator *tracepoint_print_iter; int tracepoint_printk; static bool tracepoint_printk_stop_on_boot __initdata; static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d42e245071525..48643f07bc018 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1942,8 +1942,6 @@ static inline void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { } static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { } #endif -extern struct trace_iterator *tracepoint_print_iter; - /* * Reset the state of the trace_iterator so that it can read consumed data. * Normally, the trace_iterator is used for reading the data when it is not -- GitLab From 96e6122cb79616c622ae0d025eb9f981120b568d Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Thu, 10 Nov 2022 10:03:19 +0800 Subject: [PATCH 1165/1480] tracing: Optimize event type allocation with IDA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 060fa5c83e67 ("tracing/events: reuse trace event ids after overflow"), trace events with dynamic type are linked up in list 'ftrace_event_list' through field 'trace_event.list'. Then when max event type number used up, it's possible to reuse type number of some freed one by traversing 'ftrace_event_list'. As instead, using IDA to manage available type numbers can make codes simpler and then the field 'trace_event.list' can be dropped. Since 'struct trace_event' is used in static tracepoints, drop 'trace_event.list' can make vmlinux smaller. Local test with about 2000 tracepoints, vmlinux reduced about 64KB: before:-rwxrwxr-x 1 root root 76669448 Nov 8 17:14 vmlinux after: -rwxrwxr-x 1 root root 76604176 Nov 8 17:15 vmlinux Link: https://lkml.kernel.org/r/20221110020319.1259291-1-zhengyejian1@huawei.com Signed-off-by: Zheng Yejian Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- include/linux/trace_events.h | 1 - kernel/trace/trace_output.c | 66 +++++++++--------------------------- 2 files changed, 16 insertions(+), 51 deletions(-) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 20749bd9db718..bb2053246d6a2 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -136,7 +136,6 @@ struct trace_event_functions { struct trace_event { struct hlist_node node; - struct list_head list; int type; struct trace_event_functions *funcs; }; diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 67f47ea27921d..f0ba97121345b 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "trace_output.h" @@ -21,8 +22,6 @@ DECLARE_RWSEM(trace_event_sem); static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; -static int next_event_type = __TRACE_LAST_TYPE; - enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; @@ -688,38 +687,23 @@ struct trace_event *ftrace_find_event(int type) return NULL; } -static LIST_HEAD(ftrace_event_list); +static DEFINE_IDA(trace_event_ida); -static int trace_search_list(struct list_head **list) +static void free_trace_event_type(int type) { - struct trace_event *e = NULL, *iter; - int next = __TRACE_LAST_TYPE; - - if (list_empty(&ftrace_event_list)) { - *list = &ftrace_event_list; - return next; - } + if (type >= __TRACE_LAST_TYPE) + ida_free(&trace_event_ida, type); +} - /* - * We used up all possible max events, - * lets see if somebody freed one. - */ - list_for_each_entry(iter, &ftrace_event_list, list) { - if (iter->type != next) { - e = iter; - break; - } - next++; - } +static int alloc_trace_event_type(void) +{ + int next; - /* Did we used up all 65 thousand events??? */ - if (next > TRACE_EVENT_TYPE_MAX) + /* Skip static defined type numbers */ + next = ida_alloc_range(&trace_event_ida, __TRACE_LAST_TYPE, + TRACE_EVENT_TYPE_MAX, GFP_KERNEL); + if (next < 0) return 0; - - if (e) - *list = &e->list; - else - *list = &ftrace_event_list; return next; } @@ -761,28 +745,10 @@ int register_trace_event(struct trace_event *event) if (WARN_ON(!event->funcs)) goto out; - INIT_LIST_HEAD(&event->list); - if (!event->type) { - struct list_head *list = NULL; - - if (next_event_type > TRACE_EVENT_TYPE_MAX) { - - event->type = trace_search_list(&list); - if (!event->type) - goto out; - - } else { - - event->type = next_event_type++; - list = &ftrace_event_list; - } - - if (WARN_ON(ftrace_find_event(event->type))) + event->type = alloc_trace_event_type(); + if (!event->type) goto out; - - list_add_tail(&event->list, list); - } else if (WARN(event->type > __TRACE_LAST_TYPE, "Need to add type to trace.h")) { goto out; @@ -819,7 +785,7 @@ EXPORT_SYMBOL_GPL(register_trace_event); int __unregister_trace_event(struct trace_event *event) { hlist_del(&event->node); - list_del(&event->list); + free_trace_event_type(event->type); return 0; } -- GitLab From bd604f3db49c5b21171abea0414a2020dcbf2646 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 22 Nov 2022 18:09:05 -0500 Subject: [PATCH 1166/1480] ftrace: Avoid needless updates of the ftrace function call Song Shuai reported: The list func (ftrace_ops_list_func) will be patched first before the transition between old and new calls are set, which fixed the race described in this commit `59338f75`. While ftrace_trace_function changes from the list func to a ftrace_ops func, like unregistering the klp_ops to leave the only global_ops in ftrace_ops_list, the ftrace_[regs]_call will be replaced with the list func although it already exists. So there should be a condition to avoid this. And suggested using another variable to keep track of what the ftrace function is set to. But this could be simplified by using a helper function that does the same with a static variable. Link: https://lore.kernel.org/lkml/20221026132039.2236233-1-suagrfillet@gmail.com/ Link: https://lore.kernel.org/linux-trace-kernel/20221122180905.737b6f52@gandalf.local.home Reported-by: Song Shuai Reviewed-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ftrace.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 65a5d36463e05..d04552c0c275d 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2763,6 +2763,19 @@ void __weak ftrace_arch_code_modify_post_process(void) { } +static int update_ftrace_func(ftrace_func_t func) +{ + static ftrace_func_t save_func; + + /* Avoid updating if it hasn't changed */ + if (func == save_func) + return 0; + + save_func = func; + + return ftrace_update_ftrace_func(func); +} + void ftrace_modify_all_code(int command) { int update = command & FTRACE_UPDATE_TRACE_FUNC; @@ -2783,7 +2796,7 @@ void ftrace_modify_all_code(int command) * traced. */ if (update) { - err = ftrace_update_ftrace_func(ftrace_ops_list_func); + err = update_ftrace_func(ftrace_ops_list_func); if (FTRACE_WARN_ON(err)) return; } @@ -2799,7 +2812,7 @@ void ftrace_modify_all_code(int command) /* If irqs are disabled, we are in stop machine */ if (!irqs_disabled()) smp_call_function(ftrace_sync_ipi, NULL, 1); - err = ftrace_update_ftrace_func(ftrace_trace_function); + err = update_ftrace_func(ftrace_trace_function); if (FTRACE_WARN_ON(err)) return; } -- GitLab From 15792642db6946890416a6d1616b03ab25c26fa7 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:54 -0800 Subject: [PATCH 1167/1480] perf stat: Fix cgroup display in JSON output It missed the 'else' keyword after checking json output mode. Fixes: 41cb875242e71bf1 ("perf stat: Split print_cgroup() function") Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f5501760ff2e1..46e90f0bb423f 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -175,7 +175,7 @@ static void print_cgroup(struct perf_stat_config *config, struct cgroup *cgrp) if (config->json_output) print_cgroup_json(config, cgrp_name); - if (config->csv_output) + else if (config->csv_output) print_cgroup_csv(config, cgrp_name); else print_cgroup_std(config, cgrp_name); -- GitLab From 6d74ed369d4342bb7d4fecbc1cde6061b5bb5604 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:55 -0800 Subject: [PATCH 1168/1480] perf stat: Move summary prefix printing logic in CSV output It matches to the prefix (interval timestamp), so better to have them together. No functional change intended. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 46e90f0bb423f..d86f2f8e020d4 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -713,11 +713,6 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int nl = config->metric_only ? new_line_metric : new_line_std; } - if (!config->no_csv_summary && config->csv_output && - config->summary && !config->interval && !config->metric_only) { - fprintf(config->output, "%16s%s", "summary", config->csv_sep); - } - if (run == 0 || ena == 0 || counter->counts->scaled == -1) { if (config->metric_only) { pm(config, &os, NULL, "", "", 0); @@ -828,8 +823,13 @@ static void print_counter_aggrdata(struct perf_stat_config *config, ena = aggr->counts.ena; run = aggr->counts.run; - if (prefix && !metric_only) - fprintf(output, "%s", prefix); + if (!metric_only) { + if (prefix) + fprintf(output, "%s", prefix); + else if (config->summary && config->csv_output && + !config->no_csv_summary && !config->interval) + fprintf(output, "%16s%s", "summary", config->csv_sep); + } uval = val * counter->scale; -- GitLab From 8e55ae24c08fd5bf39b632df72122a7c2591c03c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:56 -0800 Subject: [PATCH 1169/1480] perf stat: Do not align time prefix in CSV output We don't care about the alignment in the CSV output as it's intended for machine processing. Let's get rid of it to make the output more compact. Before: # perf stat -a --summary -I 1 -x, true 0.001149309,219.20,msec,cpu-clock,219322251,100.00,219.200,CPUs utilized 0.001149309,144,,context-switches,219241902,100.00,656.935,/sec 0.001149309,38,,cpu-migrations,219173705,100.00,173.358,/sec 0.001149309,61,,page-faults,219093635,100.00,278.285,/sec 0.001149309,10679310,,cycles,218746228,100.00,0.049,GHz 0.001149309,6288296,,instructions,218589869,100.00,0.59,insn per cycle 0.001149309,1386904,,branches,218428851,100.00,6.327,M/sec 0.001149309,56863,,branch-misses,218219951,100.00,4.10,of all branches summary,219.20,msec,cpu-clock,219322251,100.00,20.025,CPUs utilized summary,144,,context-switches,219241902,100.00,656.935,/sec summary,38,,cpu-migrations,219173705,100.00,173.358,/sec summary,61,,page-faults,219093635,100.00,278.285,/sec summary,10679310,,cycles,218746228,100.00,0.049,GHz summary,6288296,,instructions,218589869,100.00,0.59,insn per cycle summary,1386904,,branches,218428851,100.00,6.327,M/sec summary,56863,,branch-misses,218219951,100.00,4.10,of all branches After: 0.001148449,224.75,msec,cpu-clock,224870589,100.00,224.747,CPUs utilized 0.001148449,176,,context-switches,224775564,100.00,783.103,/sec 0.001148449,38,,cpu-migrations,224707428,100.00,169.079,/sec 0.001148449,61,,page-faults,224629326,100.00,271.416,/sec 0.001148449,12172071,,cycles,224266368,100.00,0.054,GHz 0.001148449,6901907,,instructions,224108764,100.00,0.57,insn per cycle 0.001148449,1515655,,branches,223946693,100.00,6.744,M/sec 0.001148449,70027,,branch-misses,223735385,100.00,4.62,of all branches summary,224.75,msec,cpu-clock,224870589,100.00,21.066,CPUs utilized summary,176,,context-switches,224775564,100.00,783.103,/sec summary,38,,cpu-migrations,224707428,100.00,169.079,/sec summary,61,,page-faults,224629326,100.00,271.416,/sec summary,12172071,,cycles,224266368,100.00,0.054,GHz summary,6901907,,instructions,224108764,100.00,0.57,insn per cycle summary,1515655,,branches,223946693,100.00,6.744,M/sec summary,70027,,branch-misses,223735385,100.00,4.62,of all branches Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index d86f2f8e020d4..15c88b9b5aa34 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -828,7 +828,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, fprintf(output, "%s", prefix); else if (config->summary && config->csv_output && !config->no_csv_summary && !config->interval) - fprintf(output, "%16s%s", "summary", config->csv_sep); + fprintf(output, "%s%s", "summary", config->csv_sep); } uval = val * counter->scale; @@ -1078,9 +1078,12 @@ static void prepare_interval(struct perf_stat_config *config, if (config->iostat_run) return; - if (!config->json_output) - sprintf(prefix, "%6lu.%09lu%s", (unsigned long) ts->tv_sec, + if (config->csv_output) + sprintf(prefix, "%lu.%09lu%s", (unsigned long) ts->tv_sec, ts->tv_nsec, config->csv_sep); + else if (!config->json_output) + sprintf(prefix, "%6lu.%09lu ", (unsigned long) ts->tv_sec, + ts->tv_nsec); else if (!config->metric_only) sprintf(prefix, "{\"interval\" : %lu.%09lu, ", (unsigned long) ts->tv_sec, ts->tv_nsec); -- GitLab From a7ec1dd2d744208ca814ebde8c97f94e041625ef Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:57 -0800 Subject: [PATCH 1170/1480] perf stat: Use scnprintf() in prepare_interval() It should not use sprintf() anymore. Let's pass the buffer size and use the safer scnprintf() instead. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 15c88b9b5aa34..744b7a40f59ad 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1073,23 +1073,23 @@ static void print_metric_headers(struct perf_stat_config *config, } static void prepare_interval(struct perf_stat_config *config, - char *prefix, struct timespec *ts) + char *prefix, size_t len, struct timespec *ts) { if (config->iostat_run) return; if (config->csv_output) - sprintf(prefix, "%lu.%09lu%s", (unsigned long) ts->tv_sec, - ts->tv_nsec, config->csv_sep); + scnprintf(prefix, len, "%lu.%09lu%s", + (unsigned long) ts->tv_sec, ts->tv_nsec, config->csv_sep); else if (!config->json_output) - sprintf(prefix, "%6lu.%09lu ", (unsigned long) ts->tv_sec, - ts->tv_nsec); + scnprintf(prefix, len, "%6lu.%09lu ", + (unsigned long) ts->tv_sec, ts->tv_nsec); else if (!config->metric_only) - sprintf(prefix, "{\"interval\" : %lu.%09lu, ", (unsigned long) - ts->tv_sec, ts->tv_nsec); + scnprintf(prefix, len, "{\"interval\" : %lu.%09lu, ", + (unsigned long) ts->tv_sec, ts->tv_nsec); else - sprintf(prefix, "{\"interval\" : %lu.%09lu}", (unsigned long) - ts->tv_sec, ts->tv_nsec); + scnprintf(prefix, len, "{\"interval\" : %lu.%09lu}", + (unsigned long) ts->tv_sec, ts->tv_nsec); } static void print_header_interval_std(struct perf_stat_config *config, @@ -1390,7 +1390,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf if (interval) { prefix = buf; - prepare_interval(config, prefix, ts); + prepare_interval(config, buf, sizeof(buf), ts); } print_header(config, _target, evlist, argc, argv); -- GitLab From f123b2d84ecec9a3c551e745f43d36bba1d69e1c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:58 -0800 Subject: [PATCH 1171/1480] perf stat: Remove prefix argument in print_metric_headers() It always passes a whitespace to the function, thus we can just add it to the function body. Furthermore, it's only used in the normal output mode. Well, actually CSV used it but it doesn't need to since we don't care about the indentation or alignment in the CSV output. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 744b7a40f59ad..deed6ccf072f5 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -996,10 +996,9 @@ static void print_no_aggr_metric(struct perf_stat_config *config, } static void print_metric_headers_std(struct perf_stat_config *config, - const char *prefix, bool no_indent) + bool no_indent) { - if (prefix) - fprintf(config->output, "%s", prefix); + fputc(' ', config->output); if (!no_indent) { int len = aggr_header_lens[config->aggr_mode]; @@ -1012,11 +1011,8 @@ static void print_metric_headers_std(struct perf_stat_config *config, } static void print_metric_headers_csv(struct perf_stat_config *config, - const char *prefix, bool no_indent __maybe_unused) { - if (prefix) - fprintf(config->output, "%s", prefix); if (config->interval) fputs("time,", config->output); if (!config->iostat_run) @@ -1024,7 +1020,6 @@ static void print_metric_headers_csv(struct perf_stat_config *config, } static void print_metric_headers_json(struct perf_stat_config *config, - const char *prefix __maybe_unused, bool no_indent __maybe_unused) { if (config->interval) @@ -1032,8 +1027,7 @@ static void print_metric_headers_json(struct perf_stat_config *config, } static void print_metric_headers(struct perf_stat_config *config, - struct evlist *evlist, - const char *prefix, bool no_indent) + struct evlist *evlist, bool no_indent) { struct evsel *counter; struct outstate os = { @@ -1047,11 +1041,11 @@ static void print_metric_headers(struct perf_stat_config *config, }; if (config->json_output) - print_metric_headers_json(config, prefix, no_indent); + print_metric_headers_json(config, no_indent); else if (config->csv_output) - print_metric_headers_csv(config, prefix, no_indent); + print_metric_headers_csv(config, no_indent); else - print_metric_headers_std(config, prefix, no_indent); + print_metric_headers_std(config, no_indent); if (config->iostat_run) iostat_print_header_prefix(config); @@ -1132,7 +1126,7 @@ static void print_header_interval_std(struct perf_stat_config *config, } if (config->metric_only) - print_metric_headers(config, evlist, " ", true); + print_metric_headers(config, evlist, true); else fprintf(output, " %*s %*s events\n", COUNTS_LEN, "counts", config->unit_width, "unit"); @@ -1168,7 +1162,7 @@ static void print_header_std(struct perf_stat_config *config, fprintf(output, ":\n\n"); if (config->metric_only) - print_metric_headers(config, evlist, " ", false); + print_metric_headers(config, evlist, false); } static void print_header_csv(struct perf_stat_config *config, @@ -1178,7 +1172,7 @@ static void print_header_csv(struct perf_stat_config *config, const char **argv __maybe_unused) { if (config->metric_only) - print_metric_headers(config, evlist, " ", true); + print_metric_headers(config, evlist, true); } static void print_header_json(struct perf_stat_config *config, struct target *_target __maybe_unused, @@ -1187,7 +1181,7 @@ static void print_header_json(struct perf_stat_config *config, const char **argv __maybe_unused) { if (config->metric_only) - print_metric_headers(config, evlist, " ", true); + print_metric_headers(config, evlist, true); } static void print_header(struct perf_stat_config *config, -- GitLab From ce551ec923445b821893bddfb13c116d7e8fe454 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:01:59 -0800 Subject: [PATCH 1172/1480] perf stat: Remove metric_only argument in print_counter_aggrdata() It already passes the stat_config argument, then it can find the value in the config. No need to pass it separately. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-7-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index deed6ccf072f5..b8432c0a0ec33 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -804,7 +804,7 @@ static void uniquify_counter(struct perf_stat_config *config, struct evsel *coun static void print_counter_aggrdata(struct perf_stat_config *config, struct evsel *counter, int s, - char *prefix, bool metric_only) + char *prefix) { FILE *output = config->output; u64 ena, run, val; @@ -813,6 +813,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, struct perf_stat_aggr *aggr = &ps->aggr[s]; struct aggr_cpu_id id = config->aggr_map->map[s]; double avg = aggr->counts.val; + bool metric_only = config->metric_only; if (counter->supported && aggr->nr == 0) return; @@ -875,7 +876,6 @@ static void print_aggr(struct perf_stat_config *config, struct evlist *evlist, char *prefix) { - bool metric_only = config->metric_only; struct evsel *counter; int s; @@ -893,8 +893,7 @@ static void print_aggr(struct perf_stat_config *config, if (counter->merged_stat) continue; - print_counter_aggrdata(config, counter, s, prefix, - metric_only); + print_counter_aggrdata(config, counter, s, prefix); } print_metric_end(config); } @@ -904,7 +903,6 @@ static void print_aggr_cgroup(struct perf_stat_config *config, struct evlist *evlist, char *prefix) { - bool metric_only = config->metric_only; struct evsel *counter, *evsel; struct cgroup *cgrp = NULL; int s; @@ -928,8 +926,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config, if (counter->cgrp != cgrp) continue; - print_counter_aggrdata(config, counter, s, prefix, - metric_only); + print_counter_aggrdata(config, counter, s, prefix); } print_metric_end(config); } @@ -939,7 +936,6 @@ static void print_aggr_cgroup(struct perf_stat_config *config, static void print_counter(struct perf_stat_config *config, struct evsel *counter, char *prefix) { - bool metric_only = config->metric_only; int s; /* AGGR_THREAD doesn't have config->aggr_get_id */ @@ -950,8 +946,7 @@ static void print_counter(struct perf_stat_config *config, return; for (s = 0; s < config->aggr_map->nr; s++) { - print_counter_aggrdata(config, counter, s, prefix, - metric_only); + print_counter_aggrdata(config, counter, s, prefix); } } @@ -1339,7 +1334,7 @@ static void print_percore(struct perf_stat_config *config, if (found) continue; - print_counter_aggrdata(config, counter, s, prefix, metric_only); + print_counter_aggrdata(config, counter, s, prefix); core_map->map[c++] = core_id; } -- GitLab From 991991ab99635d9e368f9671fa8c30ec1113042c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:00 -0800 Subject: [PATCH 1173/1480] perf stat: Pass const char *prefix to display routines This is a minor cleanup and preparation for the later change. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/iostat.h | 2 +- tools/perf/util/stat-display.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/iostat.h b/tools/perf/util/iostat.h index 23c1c46a331ad..c22688f87cb2d 100644 --- a/tools/perf/util/iostat.h +++ b/tools/perf/util/iostat.h @@ -28,7 +28,7 @@ enum iostat_mode_t { extern enum iostat_mode_t iostat_mode; -typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, char *); +typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, const char *); int iostat_prepare(struct evlist *evlist, struct perf_stat_config *config); int iostat_parse(const struct option *opt, const char *str, diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index b8432c0a0ec33..d2894a519d61b 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -675,7 +675,7 @@ static bool is_mixed_hw_group(struct evsel *counter) static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int nr, struct evsel *counter, double uval, - char *prefix, u64 run, u64 ena, double noise, + const char *prefix, u64 run, u64 ena, double noise, struct runtime_stat *st, int map_idx) { struct perf_stat_output_ctx out; @@ -804,7 +804,7 @@ static void uniquify_counter(struct perf_stat_config *config, struct evsel *coun static void print_counter_aggrdata(struct perf_stat_config *config, struct evsel *counter, int s, - char *prefix) + const char *prefix) { FILE *output = config->output; u64 ena, run, val; @@ -843,7 +843,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, static void print_metric_begin(struct perf_stat_config *config, struct evlist *evlist, - char *prefix, int aggr_idx, + const char *prefix, int aggr_idx, struct cgroup *cgrp) { struct perf_stat_aggr *aggr; @@ -874,7 +874,7 @@ static void print_metric_end(struct perf_stat_config *config) static void print_aggr(struct perf_stat_config *config, struct evlist *evlist, - char *prefix) + const char *prefix) { struct evsel *counter; int s; @@ -901,7 +901,7 @@ static void print_aggr(struct perf_stat_config *config, static void print_aggr_cgroup(struct perf_stat_config *config, struct evlist *evlist, - char *prefix) + const char *prefix) { struct evsel *counter, *evsel; struct cgroup *cgrp = NULL; @@ -934,7 +934,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config, } static void print_counter(struct perf_stat_config *config, - struct evsel *counter, char *prefix) + struct evsel *counter, const char *prefix) { int s; @@ -952,7 +952,7 @@ static void print_counter(struct perf_stat_config *config, static void print_no_aggr_metric(struct perf_stat_config *config, struct evlist *evlist, - char *prefix) + const char *prefix) { int all_idx; struct perf_cpu cpu; @@ -1301,7 +1301,7 @@ static void print_footer(struct perf_stat_config *config) } static void print_percore(struct perf_stat_config *config, - struct evsel *counter, char *prefix) + struct evsel *counter, const char *prefix) { bool metric_only = config->metric_only; FILE *output = config->output; @@ -1345,7 +1345,7 @@ static void print_percore(struct perf_stat_config *config, } static void print_cgroup_counter(struct perf_stat_config *config, struct evlist *evlist, - char *prefix) + const char *prefix) { struct cgroup *cgrp = NULL; struct evsel *counter; -- GitLab From 92ccf7f11d68fa55dc82cb7ae01043b3691918cf Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:01 -0800 Subject: [PATCH 1174/1480] perf stat: Use 'struct outstate' in evlist__print_counters() This is a preparation for the later cleanup. No functional changes intended. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-9-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index d2894a519d61b..70aebf359e163 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1372,13 +1372,16 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf bool metric_only = config->metric_only; int interval = config->interval; struct evsel *counter; - char buf[64], *prefix = NULL; + char buf[64]; + struct outstate os = { + .fh = config->output, + }; if (config->iostat_run) evlist->selected = evlist__first(evlist); if (interval) { - prefix = buf; + os.prefix = buf; prepare_interval(config, buf, sizeof(buf), ts); } @@ -1390,35 +1393,35 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf case AGGR_SOCKET: case AGGR_NODE: if (config->cgroup_list) - print_aggr_cgroup(config, evlist, prefix); + print_aggr_cgroup(config, evlist, os.prefix); else - print_aggr(config, evlist, prefix); + print_aggr(config, evlist, os.prefix); break; case AGGR_THREAD: case AGGR_GLOBAL: if (config->iostat_run) { - iostat_print_counters(evlist, config, ts, prefix = buf, + iostat_print_counters(evlist, config, ts, buf, print_counter); } else if (config->cgroup_list) { - print_cgroup_counter(config, evlist, prefix); + print_cgroup_counter(config, evlist, os.prefix); } else { - print_metric_begin(config, evlist, prefix, + print_metric_begin(config, evlist, os.prefix, /*aggr_idx=*/0, /*cgrp=*/NULL); evlist__for_each_entry(evlist, counter) { - print_counter(config, counter, prefix); + print_counter(config, counter, os.prefix); } print_metric_end(config); } break; case AGGR_NONE: if (metric_only) - print_no_aggr_metric(config, evlist, prefix); + print_no_aggr_metric(config, evlist, os.prefix); else { evlist__for_each_entry(evlist, counter) { if (counter->percore) - print_percore(config, counter, prefix); + print_percore(config, counter, os.prefix); else - print_counter(config, counter, prefix); + print_counter(config, counter, os.prefix); } } break; -- GitLab From 922ae948c429a9b396761f2071eebf6a19688dd2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:02 -0800 Subject: [PATCH 1175/1480] perf stat: Pass 'struct outstate' to print_metric_begin() It passes prefix and cgroup pointers but the outstate already has them. Let's pass the outstate pointer instead. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-10-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 50 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 70aebf359e163..3ed63061d6f82 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -843,8 +843,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, static void print_metric_begin(struct perf_stat_config *config, struct evlist *evlist, - const char *prefix, int aggr_idx, - struct cgroup *cgrp) + struct outstate *os, int aggr_idx) { struct perf_stat_aggr *aggr; struct aggr_cpu_id id; @@ -853,15 +852,15 @@ static void print_metric_begin(struct perf_stat_config *config, if (!config->metric_only) return; - if (prefix) - fprintf(config->output, "%s", prefix); + if (os->prefix) + fprintf(config->output, "%s", os->prefix); evsel = evlist__first(evlist); id = config->aggr_map->map[aggr_idx]; aggr = &evsel->stats->aggr[aggr_idx]; aggr_printout(config, evsel, id, aggr->nr); - print_cgroup(config, cgrp); + print_cgroup(config, os->cgrp); } static void print_metric_end(struct perf_stat_config *config) @@ -877,6 +876,9 @@ static void print_aggr(struct perf_stat_config *config, const char *prefix) { struct evsel *counter; + struct outstate os = { + .prefix = prefix, + }; int s; if (!config->aggr_map || !config->aggr_get_id) @@ -887,7 +889,7 @@ static void print_aggr(struct perf_stat_config *config, * Without each counter has its own line. */ for (s = 0; s < config->aggr_map->nr; s++) { - print_metric_begin(config, evlist, prefix, s, /*cgrp=*/NULL); + print_metric_begin(config, evlist, &os, s); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) @@ -904,26 +906,28 @@ static void print_aggr_cgroup(struct perf_stat_config *config, const char *prefix) { struct evsel *counter, *evsel; - struct cgroup *cgrp = NULL; + struct outstate os = { + .prefix = prefix, + }; int s; if (!config->aggr_map || !config->aggr_get_id) return; evlist__for_each_entry(evlist, evsel) { - if (cgrp == evsel->cgrp) + if (os.cgrp == evsel->cgrp) continue; - cgrp = evsel->cgrp; + os.cgrp = evsel->cgrp; for (s = 0; s < config->aggr_map->nr; s++) { - print_metric_begin(config, evlist, prefix, s, cgrp); + print_metric_begin(config, evlist, &os, s); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) continue; - if (counter->cgrp != cgrp) + if (counter->cgrp != os.cgrp) continue; print_counter_aggrdata(config, counter, s, prefix); @@ -956,6 +960,9 @@ static void print_no_aggr_metric(struct perf_stat_config *config, { int all_idx; struct perf_cpu cpu; + struct outstate os = { + .prefix = prefix, + }; perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.user_requested_cpus) { struct evsel *counter; @@ -973,8 +980,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); if (first) { - print_metric_begin(config, evlist, prefix, - counter_idx, /*cgrp=*/NULL); + print_metric_begin(config, evlist, &os, counter_idx); first = false; } val = ps->aggr[counter_idx].counts.val; @@ -1347,22 +1353,23 @@ static void print_percore(struct perf_stat_config *config, static void print_cgroup_counter(struct perf_stat_config *config, struct evlist *evlist, const char *prefix) { - struct cgroup *cgrp = NULL; struct evsel *counter; + struct outstate os = { + .prefix = prefix, + }; evlist__for_each_entry(evlist, counter) { - if (cgrp != counter->cgrp) { - if (cgrp != NULL) + if (os.cgrp != counter->cgrp) { + if (os.cgrp != NULL) print_metric_end(config); - cgrp = counter->cgrp; - print_metric_begin(config, evlist, prefix, - /*aggr_idx=*/0, cgrp); + os.cgrp = counter->cgrp; + print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); } print_counter(config, counter, prefix); } - if (cgrp) + if (os.cgrp) print_metric_end(config); } @@ -1405,8 +1412,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf } else if (config->cgroup_list) { print_cgroup_counter(config, evlist, os.prefix); } else { - print_metric_begin(config, evlist, os.prefix, - /*aggr_idx=*/0, /*cgrp=*/NULL); + print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); evlist__for_each_entry(evlist, counter) { print_counter(config, counter, os.prefix); } -- GitLab From e7f4da312259e61877ae8e26d216993c4128bddc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:03 -0800 Subject: [PATCH 1176/1480] perf stat: Pass struct outstate to printout() The printout() takes a lot of arguments and sets an outstate with the value. Instead, we can fill the outstate first and then pass it to reduce the number of arguments. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-11-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 38 ++++++++++++++++------------------ 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 3ed63061d6f82..dd190f71e9333 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -673,22 +673,15 @@ static bool is_mixed_hw_group(struct evsel *counter) return false; } -static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int nr, - struct evsel *counter, double uval, - const char *prefix, u64 run, u64 ena, double noise, +static void printout(struct perf_stat_config *config, struct outstate *os, + double uval, u64 run, u64 ena, double noise, struct runtime_stat *st, int map_idx) { struct perf_stat_output_ctx out; - struct outstate os = { - .fh = config->output, - .prefix = prefix ? prefix : "", - .id = id, - .nr = nr, - .evsel = counter, - }; print_metric_t pm; new_line_t nl; bool ok = true; + struct evsel *counter = os->evsel; if (config->csv_output) { static const int aggr_fields[AGGR_MAX] = { @@ -704,7 +697,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int pm = config->metric_only ? print_metric_only_csv : print_metric_csv; nl = config->metric_only ? new_line_metric : new_line_csv; - os.nfields = 3 + aggr_fields[config->aggr_mode] + (counter->cgrp ? 1 : 0); + os->nfields = 3 + aggr_fields[config->aggr_mode] + (counter->cgrp ? 1 : 0); } else if (config->json_output) { pm = config->metric_only ? print_metric_only_json : print_metric_json; nl = config->metric_only ? new_line_metric : new_line_json; @@ -715,7 +708,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int if (run == 0 || ena == 0 || counter->counts->scaled == -1) { if (config->metric_only) { - pm(config, &os, NULL, "", "", 0); + pm(config, os, NULL, "", "", 0); return; } @@ -732,11 +725,11 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int out.print_metric = pm; out.new_line = nl; - out.ctx = &os; + out.ctx = os; out.force_header = false; if (!config->metric_only) { - abs_printout(config, id, nr, counter, uval, ok); + abs_printout(config, os->id, os->nr, counter, uval, ok); print_noise(config, counter, noise, /*before_metric=*/true); print_running(config, run, ena, /*before_metric=*/true); @@ -814,6 +807,13 @@ static void print_counter_aggrdata(struct perf_stat_config *config, struct aggr_cpu_id id = config->aggr_map->map[s]; double avg = aggr->counts.val; bool metric_only = config->metric_only; + struct outstate os = { + .fh = config->output, + .prefix = prefix ? prefix : "", + .id = id, + .nr = aggr->nr, + .evsel = counter, + }; if (counter->supported && aggr->nr == 0) return; @@ -834,8 +834,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, uval = val * counter->scale; - printout(config, id, aggr->nr, counter, uval, - prefix, run, ena, avg, &rt_stat, s); + printout(config, &os, uval, run, ena, avg, &rt_stat, s); if (!metric_only) fputc('\n', output); @@ -971,14 +970,14 @@ static void print_no_aggr_metric(struct perf_stat_config *config, evlist__for_each_entry(evlist, counter) { u64 ena, run, val; double uval; - struct aggr_cpu_id id; struct perf_stat_evsel *ps = counter->stats; int counter_idx = perf_cpu_map__idx(evsel__cpus(counter), cpu); if (counter_idx < 0) continue; - id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); + os.evsel = counter; + os.id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); if (first) { print_metric_begin(config, evlist, &os, counter_idx); first = false; @@ -988,8 +987,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, run = ps->aggr[counter_idx].counts.run; uval = val * counter->scale; - printout(config, id, 0, counter, uval, prefix, - run, ena, 1.0, &rt_stat, counter_idx); + printout(config, &os, uval, run, ena, 1.0, &rt_stat, counter_idx); } if (!first) print_metric_end(config); -- GitLab From 01577597493dc8bded8a5880fbf84a6d5bf13f1b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:04 -0800 Subject: [PATCH 1177/1480] perf stat: Do not pass runtime_stat to printout() It always passes a pointer to rt_stat as it's the only one. Let's not pass it and directly refer it in the printout(). Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-12-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index dd190f71e9333..cdf4ca7f6e3a4 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -674,8 +674,7 @@ static bool is_mixed_hw_group(struct evsel *counter) } static void printout(struct perf_stat_config *config, struct outstate *os, - double uval, u64 run, u64 ena, double noise, - struct runtime_stat *st, int map_idx) + double uval, u64 run, u64 ena, double noise, int map_idx) { struct perf_stat_output_ctx out; print_metric_t pm; @@ -737,7 +736,7 @@ static void printout(struct perf_stat_config *config, struct outstate *os, if (ok) { perf_stat__print_shadow_stats(config, counter, uval, map_idx, - &out, &config->metric_events, st); + &out, &config->metric_events, &rt_stat); } else { pm(config, &os, /*color=*/NULL, /*format=*/NULL, /*unit=*/"", /*val=*/0); } @@ -834,7 +833,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, uval = val * counter->scale; - printout(config, &os, uval, run, ena, avg, &rt_stat, s); + printout(config, &os, uval, run, ena, avg, s); if (!metric_only) fputc('\n', output); @@ -987,7 +986,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, run = ps->aggr[counter_idx].counts.run; uval = val * counter->scale; - printout(config, &os, uval, run, ena, 1.0, &rt_stat, counter_idx); + printout(config, &os, uval, run, ena, 1.0, counter_idx); } if (!first) print_metric_end(config); -- GitLab From 5f334d88c25e0dbdbc199ad38becc5cc5aa33081 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:05 -0800 Subject: [PATCH 1178/1480] perf stat: Pass through 'struct outstate' Now most of the print functions take a pointer to the struct outstate. We have one in the evlist__print_counters() and pass it through the child functions. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-13-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/iostat.c | 4 +- tools/perf/util/iostat.c | 3 +- tools/perf/util/iostat.h | 4 +- tools/perf/util/stat-display.c | 102 +++++++++++++----------------- 4 files changed, 50 insertions(+), 63 deletions(-) diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/iostat.c index 404de795ec0bf..7eb0a7b00b95a 100644 --- a/tools/perf/arch/x86/util/iostat.c +++ b/tools/perf/arch/x86/util/iostat.c @@ -449,7 +449,7 @@ void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel, void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config, struct timespec *ts, - char *prefix, iostat_print_counter_t print_cnt_cb) + char *prefix, iostat_print_counter_t print_cnt_cb, void *arg) { void *perf_device = NULL; struct evsel *counter = evlist__first(evlist); @@ -464,7 +464,7 @@ void iostat_print_counters(struct evlist *evlist, iostat_prefix(evlist, config, prefix, ts); fprintf(config->output, "\n%s", prefix); } - print_cnt_cb(config, counter, prefix); + print_cnt_cb(config, counter, arg); } fputc('\n', config->output); } diff --git a/tools/perf/util/iostat.c b/tools/perf/util/iostat.c index 57dd49da28fe4..b770bd473af71 100644 --- a/tools/perf/util/iostat.c +++ b/tools/perf/util/iostat.c @@ -48,6 +48,7 @@ __weak void iostat_print_counters(struct evlist *evlist __maybe_unused, struct perf_stat_config *config __maybe_unused, struct timespec *ts __maybe_unused, char *prefix __maybe_unused, - iostat_print_counter_t print_cnt_cb __maybe_unused) + iostat_print_counter_t print_cnt_cb __maybe_unused, + void *arg __maybe_unused) { } diff --git a/tools/perf/util/iostat.h b/tools/perf/util/iostat.h index c22688f87cb2d..a4e7299c5c2fb 100644 --- a/tools/perf/util/iostat.h +++ b/tools/perf/util/iostat.h @@ -28,7 +28,7 @@ enum iostat_mode_t { extern enum iostat_mode_t iostat_mode; -typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, const char *); +typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, void *); int iostat_prepare(struct evlist *evlist, struct perf_stat_config *config); int iostat_parse(const struct option *opt, const char *str, @@ -42,6 +42,6 @@ void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel, struct perf_stat_output_ctx *out); void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config, struct timespec *ts, - char *prefix, iostat_print_counter_t print_cnt_cb); + char *prefix, iostat_print_counter_t print_cnt_cb, void *arg); #endif /* _IOSTAT_H */ diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index cdf4ca7f6e3a4..335627e8542dc 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -796,7 +796,7 @@ static void uniquify_counter(struct perf_stat_config *config, struct evsel *coun static void print_counter_aggrdata(struct perf_stat_config *config, struct evsel *counter, int s, - const char *prefix) + struct outstate *os) { FILE *output = config->output; u64 ena, run, val; @@ -806,13 +806,10 @@ static void print_counter_aggrdata(struct perf_stat_config *config, struct aggr_cpu_id id = config->aggr_map->map[s]; double avg = aggr->counts.val; bool metric_only = config->metric_only; - struct outstate os = { - .fh = config->output, - .prefix = prefix ? prefix : "", - .id = id, - .nr = aggr->nr, - .evsel = counter, - }; + + os->id = id; + os->nr = aggr->nr; + os->evsel = counter; if (counter->supported && aggr->nr == 0) return; @@ -824,8 +821,8 @@ static void print_counter_aggrdata(struct perf_stat_config *config, run = aggr->counts.run; if (!metric_only) { - if (prefix) - fprintf(output, "%s", prefix); + if (os->prefix) + fprintf(output, "%s", os->prefix); else if (config->summary && config->csv_output && !config->no_csv_summary && !config->interval) fprintf(output, "%s%s", "summary", config->csv_sep); @@ -833,7 +830,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, uval = val * counter->scale; - printout(config, &os, uval, run, ena, avg, s); + printout(config, os, uval, run, ena, avg, s); if (!metric_only) fputc('\n', output); @@ -871,12 +868,9 @@ static void print_metric_end(struct perf_stat_config *config) static void print_aggr(struct perf_stat_config *config, struct evlist *evlist, - const char *prefix) + struct outstate *os) { struct evsel *counter; - struct outstate os = { - .prefix = prefix, - }; int s; if (!config->aggr_map || !config->aggr_get_id) @@ -887,13 +881,13 @@ static void print_aggr(struct perf_stat_config *config, * Without each counter has its own line. */ for (s = 0; s < config->aggr_map->nr; s++) { - print_metric_begin(config, evlist, &os, s); + print_metric_begin(config, evlist, os, s); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) continue; - print_counter_aggrdata(config, counter, s, prefix); + print_counter_aggrdata(config, counter, s, os); } print_metric_end(config); } @@ -901,34 +895,31 @@ static void print_aggr(struct perf_stat_config *config, static void print_aggr_cgroup(struct perf_stat_config *config, struct evlist *evlist, - const char *prefix) + struct outstate *os) { struct evsel *counter, *evsel; - struct outstate os = { - .prefix = prefix, - }; int s; if (!config->aggr_map || !config->aggr_get_id) return; evlist__for_each_entry(evlist, evsel) { - if (os.cgrp == evsel->cgrp) + if (os->cgrp == evsel->cgrp) continue; - os.cgrp = evsel->cgrp; + os->cgrp = evsel->cgrp; for (s = 0; s < config->aggr_map->nr; s++) { - print_metric_begin(config, evlist, &os, s); + print_metric_begin(config, evlist, os, s); evlist__for_each_entry(evlist, counter) { if (counter->merged_stat) continue; - if (counter->cgrp != os.cgrp) + if (counter->cgrp != os->cgrp) continue; - print_counter_aggrdata(config, counter, s, prefix); + print_counter_aggrdata(config, counter, s, os); } print_metric_end(config); } @@ -936,7 +927,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config, } static void print_counter(struct perf_stat_config *config, - struct evsel *counter, const char *prefix) + struct evsel *counter, struct outstate *os) { int s; @@ -948,19 +939,16 @@ static void print_counter(struct perf_stat_config *config, return; for (s = 0; s < config->aggr_map->nr; s++) { - print_counter_aggrdata(config, counter, s, prefix); + print_counter_aggrdata(config, counter, s, os); } } static void print_no_aggr_metric(struct perf_stat_config *config, struct evlist *evlist, - const char *prefix) + struct outstate *os) { int all_idx; struct perf_cpu cpu; - struct outstate os = { - .prefix = prefix, - }; perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.user_requested_cpus) { struct evsel *counter; @@ -975,10 +963,10 @@ static void print_no_aggr_metric(struct perf_stat_config *config, if (counter_idx < 0) continue; - os.evsel = counter; - os.id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); + os->evsel = counter; + os->id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); if (first) { - print_metric_begin(config, evlist, &os, counter_idx); + print_metric_begin(config, evlist, os, counter_idx); first = false; } val = ps->aggr[counter_idx].counts.val; @@ -986,7 +974,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, run = ps->aggr[counter_idx].counts.run; uval = val * counter->scale; - printout(config, &os, uval, run, ena, 1.0, counter_idx); + printout(config, os, uval, run, ena, 1.0, counter_idx); } if (!first) print_metric_end(config); @@ -1304,7 +1292,7 @@ static void print_footer(struct perf_stat_config *config) } static void print_percore(struct perf_stat_config *config, - struct evsel *counter, const char *prefix) + struct evsel *counter, struct outstate *os) { bool metric_only = config->metric_only; FILE *output = config->output; @@ -1315,7 +1303,7 @@ static void print_percore(struct perf_stat_config *config, return; if (config->percore_show_thread) - return print_counter(config, counter, prefix); + return print_counter(config, counter, os); core_map = cpu_aggr_map__empty_new(config->aggr_map->nr); if (core_map == NULL) { @@ -1337,7 +1325,7 @@ static void print_percore(struct perf_stat_config *config, if (found) continue; - print_counter_aggrdata(config, counter, s, prefix); + print_counter_aggrdata(config, counter, s, os); core_map->map[c++] = core_id; } @@ -1348,30 +1336,28 @@ static void print_percore(struct perf_stat_config *config, } static void print_cgroup_counter(struct perf_stat_config *config, struct evlist *evlist, - const char *prefix) + struct outstate *os) { struct evsel *counter; - struct outstate os = { - .prefix = prefix, - }; evlist__for_each_entry(evlist, counter) { - if (os.cgrp != counter->cgrp) { - if (os.cgrp != NULL) + if (os->cgrp != counter->cgrp) { + if (os->cgrp != NULL) print_metric_end(config); - os.cgrp = counter->cgrp; - print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); + os->cgrp = counter->cgrp; + print_metric_begin(config, evlist, os, /*aggr_idx=*/0); } - print_counter(config, counter, prefix); + print_counter(config, counter, os); } - if (os.cgrp) + if (os->cgrp) print_metric_end(config); } void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, - struct target *_target, struct timespec *ts, int argc, const char **argv) + struct target *_target, struct timespec *ts, + int argc, const char **argv) { bool metric_only = config->metric_only; int interval = config->interval; @@ -1397,34 +1383,34 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf case AGGR_SOCKET: case AGGR_NODE: if (config->cgroup_list) - print_aggr_cgroup(config, evlist, os.prefix); + print_aggr_cgroup(config, evlist, &os); else - print_aggr(config, evlist, os.prefix); + print_aggr(config, evlist, &os); break; case AGGR_THREAD: case AGGR_GLOBAL: if (config->iostat_run) { iostat_print_counters(evlist, config, ts, buf, - print_counter); + (iostat_print_counter_t)print_counter, &os); } else if (config->cgroup_list) { - print_cgroup_counter(config, evlist, os.prefix); + print_cgroup_counter(config, evlist, &os); } else { print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); evlist__for_each_entry(evlist, counter) { - print_counter(config, counter, os.prefix); + print_counter(config, counter, &os); } print_metric_end(config); } break; case AGGR_NONE: if (metric_only) - print_no_aggr_metric(config, evlist, os.prefix); + print_no_aggr_metric(config, evlist, &os); else { evlist__for_each_entry(evlist, counter) { if (counter->percore) - print_percore(config, counter, os.prefix); + print_percore(config, counter, &os); else - print_counter(config, counter, os.prefix); + print_counter(config, counter, &os); } } break; -- GitLab From ab6baaae273572909f1e957fc27a9459fc95dd8c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:06 -0800 Subject: [PATCH 1179/1480] perf stat: Fix JSON output in metric-only mode It generated a broken JSON output when aggregation mode or cgroup is used with --metric-only option. Also get rid of the header line and make the output single line for each entry. It needs to know whether the current metric is the first one or not. So add 'first' field in the outstate and mark it false after printing. Before: # perf stat -a -j --metric-only true {"unit" : "GHz"}{"unit" : "insn per cycle"}{"unit" : "branch-misses of all branches"} {{"metric-value" : "0.797"}{"metric-value" : "1.65"}{"metric-value" : "0.89"} ^ # perf stat -a -j --metric-only --per-socket true {"unit" : "GHz"}{"unit" : "insn per cycle"}{"unit" : "branch-misses of all branches"} {"socket" : "S0", "aggregate-number" : 8, {"metric-value" : "0.295"}{"metric-value" : "1.88"}{"metric-value" : "0.64"} ^ After: # perf stat -a -j --metric-only true {"GHz" : "0.990", "insn per cycle" : "2.06", "branch-misses of all branches" : "0.59"} # perf stat -a -j --metric-only --per-socket true {"socket" : "S0", "aggregate-number" : 8, "GHz" : "0.439", "insn per cycle" : "2.14", "branch-misses of all branches" : "0.51"} Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-14-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 42 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 335627e8542dc..43640115454cf 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -279,9 +279,6 @@ static void print_aggr_id_json(struct perf_stat_config *config, { FILE *output = config->output; - if (!config->interval) - fputc('{', output); - switch (config->aggr_mode) { case AGGR_CORE: fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ", @@ -335,6 +332,7 @@ static void aggr_printout(struct perf_stat_config *config, struct outstate { FILE *fh; bool newline; + bool first; const char *prefix; int nfields; int nr; @@ -491,6 +489,7 @@ static void print_metric_only(struct perf_stat_config *config, color_snprintf(str, sizeof(str), color ?: "", fmt, val); fprintf(out, "%*s ", mlen, str); + os->first = false; } static void print_metric_only_csv(struct perf_stat_config *config __maybe_unused, @@ -512,6 +511,7 @@ static void print_metric_only_csv(struct perf_stat_config *config __maybe_unused ends++; *ends = 0; fprintf(out, "%s%s", vals, config->csv_sep); + os->first = false; } static void print_metric_only_json(struct perf_stat_config *config __maybe_unused, @@ -532,7 +532,8 @@ static void print_metric_only_json(struct perf_stat_config *config __maybe_unuse while (isdigit(*ends) || *ends == '.') ends++; *ends = 0; - fprintf(out, "{\"metric-value\" : \"%s\"}", vals); + fprintf(out, "%s\"%s\" : \"%s\"", os->first ? "" : ", ", unit, vals); + os->first = false; } static void new_line_metric(struct perf_stat_config *config __maybe_unused, @@ -561,7 +562,7 @@ static void print_metric_header(struct perf_stat_config *config, unit = fixunit(tbuf, os->evsel, unit); if (config->json_output) - fprintf(os->fh, "{\"unit\" : \"%s\"}", unit); + return; else if (config->csv_output) fprintf(os->fh, "%s%s", unit, config->csv_sep); else @@ -821,6 +822,8 @@ static void print_counter_aggrdata(struct perf_stat_config *config, run = aggr->counts.run; if (!metric_only) { + if (config->json_output) + fputc('{', output); if (os->prefix) fprintf(output, "%s", os->prefix); else if (config->summary && config->csv_output && @@ -844,9 +847,12 @@ static void print_metric_begin(struct perf_stat_config *config, struct aggr_cpu_id id; struct evsel *evsel; + os->first = true; if (!config->metric_only) return; + if (config->json_output) + fputc('{', config->output); if (os->prefix) fprintf(config->output, "%s", os->prefix); @@ -855,7 +861,7 @@ static void print_metric_begin(struct perf_stat_config *config, aggr = &evsel->stats->aggr[aggr_idx]; aggr_printout(config, evsel, id, aggr->nr); - print_cgroup(config, os->cgrp); + print_cgroup(config, os->cgrp ? : evsel->cgrp); } static void print_metric_end(struct perf_stat_config *config) @@ -863,6 +869,8 @@ static void print_metric_end(struct perf_stat_config *config) if (!config->metric_only) return; + if (config->json_output) + fputc('}', config->output); fputc('\n', config->output); } @@ -1005,11 +1013,9 @@ static void print_metric_headers_csv(struct perf_stat_config *config, fputs(aggr_header_csv[config->aggr_mode], config->output); } -static void print_metric_headers_json(struct perf_stat_config *config, +static void print_metric_headers_json(struct perf_stat_config *config __maybe_unused, bool no_indent __maybe_unused) { - if (config->interval) - fputs("{\"unit\" : \"sec\"}", config->output); } static void print_metric_headers(struct perf_stat_config *config, @@ -1049,7 +1055,9 @@ static void print_metric_headers(struct perf_stat_config *config, &config->metric_events, &rt_stat); } - fputc('\n', config->output); + + if (!config->json_output) + fputc('\n', config->output); } static void prepare_interval(struct perf_stat_config *config, @@ -1058,17 +1066,14 @@ static void prepare_interval(struct perf_stat_config *config, if (config->iostat_run) return; - if (config->csv_output) + if (config->json_output) + scnprintf(prefix, len, "\"interval\" : %lu.%09lu, ", + (unsigned long) ts->tv_sec, ts->tv_nsec); + else if (config->csv_output) scnprintf(prefix, len, "%lu.%09lu%s", (unsigned long) ts->tv_sec, ts->tv_nsec, config->csv_sep); - else if (!config->json_output) - scnprintf(prefix, len, "%6lu.%09lu ", - (unsigned long) ts->tv_sec, ts->tv_nsec); - else if (!config->metric_only) - scnprintf(prefix, len, "{\"interval\" : %lu.%09lu, ", - (unsigned long) ts->tv_sec, ts->tv_nsec); else - scnprintf(prefix, len, "{\"interval\" : %lu.%09lu}", + scnprintf(prefix, len, "%6lu.%09lu ", (unsigned long) ts->tv_sec, ts->tv_nsec); } @@ -1365,6 +1370,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf char buf[64]; struct outstate os = { .fh = config->output, + .first = true, }; if (config->iostat_run) -- GitLab From c4b41b83c25073c09bfcc4e5ec496c9dd316656b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:07 -0800 Subject: [PATCH 1180/1480] perf stat: Rename "aggregate-number" to "cpu-count" in JSON As the JSON output has been broken for a little while, I guess there are not many users. Let's rename the field to more intuitive one. :) Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-15-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 43640115454cf..7a39a1a7261d2 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -281,19 +281,19 @@ static void print_aggr_id_json(struct perf_stat_config *config, switch (config->aggr_mode) { case AGGR_CORE: - fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ", + fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"cpu-count\" : %d, ", id.socket, id.die, id.core, nr); break; case AGGR_DIE: - fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ", + fprintf(output, "\"die\" : \"S%d-D%d\", \"cpu-count\" : %d, ", id.socket, id.die, nr); break; case AGGR_SOCKET: - fprintf(output, "\"socket\" : \"S%d\", \"aggregate-number\" : %d, ", + fprintf(output, "\"socket\" : \"S%d\", \"cpu-count\" : %d, ", id.socket, nr); break; case AGGR_NODE: - fprintf(output, "\"node\" : \"N%d\", \"aggregate-number\" : %d, ", + fprintf(output, "\"node\" : \"N%d\", \"cpu-count\" : %d, ", id.node, nr); break; case AGGR_NONE: -- GitLab From 765d4e497fc51c64b50e5947d0b63bc3ccbd83d3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Nov 2022 10:02:08 -0800 Subject: [PATCH 1181/1480] perf stat: Tidy up JSON metric-only output when no metrics It printed empty strings for each metric. I guess it's needed for CSV output to match the column number. We could just ignore the empty metrics in JSON but it ended up with a broken JSON object with a trailing comma. So I added a dummy '"metric-value" : "none"' part. To do that, it needs to pass struct outstate to print_metric_end() to check if any metric value is printed or not. Before: # perf stat -aj --metric-only --per-socket --for-each-cgroup system.slice true {"socket" : "S0", "cpu-count" : 8, "cgroup" : "system.slice", "" : "", "" : "", "" : "", "" : "", "" : "", "" : "", "" : "", "" : ""} After: # perf stat -aj --metric-only --per-socket --for-each-cgroup system.slice true {"socket" : "S0", "cpu-count" : 8, "cgroup" : "system.slice", "metric-value" : "none"} Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221123180208.2068936-16-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 7a39a1a7261d2..847acdb5dc407 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -532,6 +532,8 @@ static void print_metric_only_json(struct perf_stat_config *config __maybe_unuse while (isdigit(*ends) || *ends == '.') ends++; *ends = 0; + if (!unit[0] || !vals[0]) + return; fprintf(out, "%s\"%s\" : \"%s\"", os->first ? "" : ", ", unit, vals); os->first = false; } @@ -864,14 +866,19 @@ static void print_metric_begin(struct perf_stat_config *config, print_cgroup(config, os->cgrp ? : evsel->cgrp); } -static void print_metric_end(struct perf_stat_config *config) +static void print_metric_end(struct perf_stat_config *config, struct outstate *os) { + FILE *output = config->output; + if (!config->metric_only) return; - if (config->json_output) - fputc('}', config->output); - fputc('\n', config->output); + if (config->json_output) { + if (os->first) + fputs("\"metric-value\" : \"none\"", output); + fputc('}', output); + } + fputc('\n', output); } static void print_aggr(struct perf_stat_config *config, @@ -897,7 +904,7 @@ static void print_aggr(struct perf_stat_config *config, print_counter_aggrdata(config, counter, s, os); } - print_metric_end(config); + print_metric_end(config, os); } } @@ -929,7 +936,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config, print_counter_aggrdata(config, counter, s, os); } - print_metric_end(config); + print_metric_end(config, os); } } } @@ -985,7 +992,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, printout(config, os, uval, run, ena, 1.0, counter_idx); } if (!first) - print_metric_end(config); + print_metric_end(config, os); } } @@ -1348,7 +1355,7 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist evlist__for_each_entry(evlist, counter) { if (os->cgrp != counter->cgrp) { if (os->cgrp != NULL) - print_metric_end(config); + print_metric_end(config, os); os->cgrp = counter->cgrp; print_metric_begin(config, evlist, os, /*aggr_idx=*/0); @@ -1357,7 +1364,7 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist print_counter(config, counter, os); } if (os->cgrp) - print_metric_end(config); + print_metric_end(config, os); } void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, @@ -1405,7 +1412,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf evlist__for_each_entry(evlist, counter) { print_counter(config, counter, &os); } - print_metric_end(config); + print_metric_end(config, &os); } break; case AGGR_NONE: -- GitLab From eafcbb6838b67ae67bcab3f794dff593250a71bb Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Thu, 24 Nov 2022 11:14:38 +0800 Subject: [PATCH 1182/1480] perf vendor events intel: Add core event list for Alderlake-N Alderlake-N only has E-core, it has been moved to non-hybrid code path on the kernel side, so add the cpuid for Alderlake-N separately. Add core event list for Alderlake-N, it is based on the ADL gracemont v1.16 JSON file. https://github.com/intel/perfmon/tree/main/ADL/events/ Reviewed-by: Kan Liang Signed-off-by: Xing Zhengjun Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221124031441.110134-1-zhengjun.xing@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/x86/alderlaken/cache.json | 330 +++++++++++ .../arch/x86/alderlaken/floating-point.json | 18 + .../arch/x86/alderlaken/frontend.json | 26 + .../arch/x86/alderlaken/memory.json | 81 +++ .../pmu-events/arch/x86/alderlaken/other.json | 38 ++ .../arch/x86/alderlaken/pipeline.json | 533 ++++++++++++++++++ .../arch/x86/alderlaken/virtual-memory.json | 47 ++ tools/perf/pmu-events/arch/x86/mapfile.csv | 3 +- 8 files changed, 1075 insertions(+), 1 deletion(-) create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/cache.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/floating-point.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/frontend.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/memory.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/other.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/pipeline.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/virtual-memory.json diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/cache.json b/tools/perf/pmu-events/arch/x86/alderlaken/cache.json new file mode 100644 index 0000000000000..043445ae14a8c --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/cache.json @@ -0,0 +1,330 @@ +[ + { + "BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts the number of cacheable memory requests that miss in the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x41" + }, + { + "BriefDescription": "Counts the number of cacheable memory requests that access the LLC. Counts on a per core basis.", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts the number of cacheable memory requests that access the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x4f" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or translation lookaside buffer (TLB) miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "SampleAfterValue": "200003", + "UMask": "0x38" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_DRAM_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or translation lookaside buffer (TLB) miss which hit in DRAM or MMIO (non-DRAM).", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2 cache.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_L2_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) miss which hit in the L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the LLC or other core with HITE/F/M.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_LLC_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) miss which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD", + "SampleAfterValue": "200003", + "UMask": "0x7" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_DRAM_HIT", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the L2 cache.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_L2_HIT", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the LLC or other core with HITE/F/M.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_LLC_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in DRAM.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.DRAM_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L2 cache.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L3 cache.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked for any of the following reasons: load buffer, store buffer or RSV full.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.ALL", + "SampleAfterValue": "20003", + "UMask": "0x7" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to a load buffer full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.LD_BUF", + "SampleAfterValue": "20003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to an RSV full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.RSV", + "SampleAfterValue": "20003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to a store buffer full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.ST_BUF", + "SampleAfterValue": "20003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of load uops retired.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_LOADS", + "PEBS": "1", + "PublicDescription": "Counts the total number of load uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x81" + }, + { + "BriefDescription": "Counts the number of store uops retired.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_STORES", + "PEBS": "1", + "PublicDescription": "Counts the total number of store uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x82" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "MSRValue": "0x80", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "MSRValue": "0x10", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "MSRValue": "0x100", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "MSRValue": "0x20", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "MSRValue": "0x4", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "MSRValue": "0x200", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "MSRValue": "0x40", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "MSRValue": "0x8", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Counts the number of retired split load uops.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.SPLIT_LOADS", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x41" + }, + { + "BriefDescription": "Counts the number of stores uops retired. Counts with or without PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.STORE_LATENCY", + "PEBS": "2", + "PublicDescription": "Counts the number of stores uops retired. Counts with or without PEBS enabled. If PEBS is enabled and a PEBS record is generated, will populate PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x6" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, but no data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x4003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and non-modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x8003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_HIT", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0002", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0002", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to instruction cache misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ICACHE", + "SampleAfterValue": "1000003", + "UMask": "0x20" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/floating-point.json b/tools/perf/pmu-events/arch/x86/alderlaken/floating-point.json new file mode 100644 index 0000000000000..30e8ca3c14854 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/floating-point.json @@ -0,0 +1,18 @@ +[ + { + "BriefDescription": "Counts the number of floating point operations retired that required microcode assist.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.FP_ASSIST", + "PublicDescription": "Counts the number of floating point operations retired that required microcode assist, which is not a reflection of the number of FP operations, instructions or uops.", + "SampleAfterValue": "20003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of floating point divide uops retired (x87 and SSE, including x87 sqrt).", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.FPDIV", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x8" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/frontend.json b/tools/perf/pmu-events/arch/x86/alderlaken/frontend.json new file mode 100644 index 0000000000000..36898bab2bba6 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/frontend.json @@ -0,0 +1,26 @@ +[ + { + "BriefDescription": "Counts the total number of BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "EventCode": "0xe6", + "EventName": "BACLEARS.ANY", + "PublicDescription": "Counts the total number of BACLEARS, which occur when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of requests to the instruction cache for one or more bytes of a cache line.", + "EventCode": "0x80", + "EventName": "ICACHE.ACCESSES", + "PublicDescription": "Counts the total number of requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line or byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts the number of instruction cache misses.", + "EventCode": "0x80", + "EventName": "ICACHE.MISSES", + "PublicDescription": "Counts the number of missed requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line and byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x2" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/memory.json b/tools/perf/pmu-events/arch/x86/alderlaken/memory.json new file mode 100644 index 0000000000000..f84bf8c43495c --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/memory.json @@ -0,0 +1,81 @@ +[ + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to any number of reasons, including an L1 miss, WCB full, pagewalk, store address block or store data block, on a load that retires.", + "EventCode": "0x05", + "EventName": "LD_HEAD.ANY_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0xff" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to a core bound stall including a store address match, a DTLB miss or a page walk that detains the load from retiring.", + "EventCode": "0x05", + "EventName": "LD_HEAD.L1_BOUND_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0xf4" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to other block cases.", + "EventCode": "0x05", + "EventName": "LD_HEAD.OTHER_AT_RET", + "PublicDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to other block cases such as pipeline conflicts, fences, etc.", + "SampleAfterValue": "1000003", + "UMask": "0xc0" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a pagewalk.", + "EventCode": "0x05", + "EventName": "LD_HEAD.PGWALK_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0xa0" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a store address match.", + "EventCode": "0x05", + "EventName": "LD_HEAD.ST_ADDR_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0x84" + }, + { + "BriefDescription": "Counts the number of machine clears due to memory ordering caused by a snoop from an external agent. Does not count internally generated machine clears such as those due to memory disambiguation.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "SampleAfterValue": "20003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400002", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400002", + "SampleAfterValue": "100003", + "UMask": "0x1" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/other.json b/tools/perf/pmu-events/arch/x86/alderlaken/other.json new file mode 100644 index 0000000000000..6336de61f628f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/other.json @@ -0,0 +1,38 @@ +[ + { + "BriefDescription": "Counts modified writebacks from L1 cache and L2 cache that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.COREWB_M.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10008", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand data reads that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10001", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10002", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts streaming stores that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.STREAMING_WR.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10800", + "SampleAfterValue": "100003", + "UMask": "0x1" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/pipeline.json b/tools/perf/pmu-events/arch/x86/alderlaken/pipeline.json new file mode 100644 index 0000000000000..fa53ff11a5096 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/pipeline.json @@ -0,0 +1,533 @@ +[ + { + "BriefDescription": "Counts the total number of branch instructions retired for all branch types.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions in which the instruction pointer (IP) of the processor is resteered due to a branch instruction and the branch instruction successfully retires. All branch type instructions are accounted for.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_CALL", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf9" + }, + { + "BriefDescription": "Counts the number of retired JCC (Jump on Conditional Code) branch instructions retired, includes both taken and not taken branches.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "Counts the number of taken JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_TAKEN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the number of far branch instructions retired, includes far jump, far call and return, and interrupt call and return.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xbf" + }, + { + "BriefDescription": "Counts the number of near indirect JMP and near indirect CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.INDIRECT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb" + }, + { + "BriefDescription": "Counts the number of near indirect CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.INDIRECT_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT_CALL", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.IND_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "Counts the number of near CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf9" + }, + { + "BriefDescription": "Counts the number of near RET branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NON_RETURN_IND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb" + }, + { + "BriefDescription": "Counts the number of near relative CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.REL_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfd" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_RETURN", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND_TAKEN", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.TAKEN_JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the total number of mispredicted branch instructions retired for all branch types.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PublicDescription": "Counts the total number of mispredicted branch instructions retired. All branch type instructions are accounted for. Prediction of the branch target address enables the processor to begin executing instructions before the non-speculative execution path is known. The branch prediction unit (BPU) predicts the target address based on the instruction pointer (IP) of the branch and on the execution path through which execution reached this IP. A branch misprediction occurs when the prediction is wrong, and results in discarding all instructions executed in the speculative path and re-fetching from the correct path.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "Counts the number of mispredicted JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "Counts the number of mispredicted taken JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND_TAKEN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the number of mispredicted near indirect JMP and near indirect CALL branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb" + }, + { + "BriefDescription": "Counts the number of mispredicted near indirect CALL branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT_CALL", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.IND_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.NON_RETURN_IND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb" + }, + { + "BriefDescription": "Counts the number of mispredicted near RET branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND_TAKEN", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.TAKEN_JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.CORE", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.CORE_P", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses fixed counter 2.", + "SampleAfterValue": "2000003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF_TSC_P", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the total number of instructions retired. (Fixed event)", + "EventName": "INST_RETIRED.ANY", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses fixed counter 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the total number of instructions retired.", + "EventCode": "0xc0", + "EventName": "INST_RETIRED.ANY_P", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event LD_BLOCKS.ADDRESS_ALIAS", + "Deprecated": "1", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.4K_ALIAS", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of retired loads that are blocked because it initially appears to be store forward blocked, but subsequently is shown not to be blocked based on 4K alias check.", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.ADDRESS_ALIAS", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of retired loads that are blocked because its address exactly matches an older store whose data is not ready.", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.DATA_UNKNOWN", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of machine clears due to memory ordering in which an internal load passes an older store within the same CPU.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.DISAMBIGUATION", + "SampleAfterValue": "20003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of machines clears due to memory renaming.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.MRN_NUKE", + "SampleAfterValue": "1000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of machine clears due to a page fault. Counts both I-Side and D-Side (Loads/Stores) page faults. A page fault occurs when either the page is not present, or an access violation occurs.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.PAGE_FAULT", + "SampleAfterValue": "20003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine with the use of microcode due to SMC, MEMORY_ORDERING, FP_ASSISTS, PAGE_FAULT, DISAMBIGUATION, and FPC_VIRTUAL_TRAP.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.SLOW", + "SampleAfterValue": "20003", + "UMask": "0x6f" + }, + { + "BriefDescription": "Counts the number of machine clears due to program modifying data (self modifying code) within 1K of a recently fetched code page.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.SMC", + "SampleAfterValue": "20003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires.", + "EventCode": "0x75", + "EventName": "SERIALIZATION.NON_C01_MS_SCB", + "PublicDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires. The most commonly executed instruction with an MS scoreboard is PAUSE.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.ALL", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear. Only issue slots wasted due to fast nukes such as memory ordering nukes are counted. Other nukes are not accounted for. Counts all issue slots blocked during this recovery window including relevant microcode flows and while uops are not yet available in the instruction queue (IQ) even if an FE_bound event occurs during this period. Also includes the issue slots that were consumed by the backend but were thrown away because they were younger than the mispredict or machine clear.", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to fast nukes such as memory ordering and memory disambiguation machine clears.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.FASTNUKE", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a machine clear (nuke) of any kind including memory ordering and memory disambiguation.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MACHINE_CLEARS", + "SampleAfterValue": "1000003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to branch mispredicts.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MISPREDICT", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to a machine clear (nuke).", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.NUKE", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to backend stalls.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALL", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to certain allocation restrictions.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALLOC_RESTRICTIONS", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to memory reservation stalls in which a scheduler is not able to accept uops.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.MEM_SCHEDULER", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to IEC or FPC RAT stalls, which can be due to FIQ or IEC reservation stalls in which the integer, floating point or SIMD scheduler is not able to accept uops.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.NON_MEM_SCHEDULER", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the physical register file unable to accept an entry (marble stalls).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REGISTER", + "SampleAfterValue": "1000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the reorder buffer being full (ROB stalls).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REORDER_BUFFER", + "SampleAfterValue": "1000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to scoreboards from the instruction queue (IQ), jump execution unit (JEU), or microcode sequencer (MS).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.SERIALIZATION", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to frontend stalls.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ALL", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_DETECT", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS, which occurs when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_RESTEER", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS, which occurs when the Branch Target Buffer (BTB) predicts a taken branch.", + "SampleAfterValue": "1000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to the microcode sequencer (MS).", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.CISC", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to decode stalls.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.DECODE", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to frontend bandwidth restrictions due to decode, predecode, cisc, and other limitations.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.FRONTEND_BANDWIDTH", + "SampleAfterValue": "1000003", + "UMask": "0x8d" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to a latency related stalls including BACLEARs, BTCLEARs, ITLB misses, and ICache misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.FRONTEND_LATENCY", + "SampleAfterValue": "1000003", + "UMask": "0x72" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to ITLB misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ITLB", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to Instruction Table Lookaside Buffer (ITLB) misses.", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to other common frontend stalls not categorized.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.OTHER", + "SampleAfterValue": "1000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to wrong predecodes.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.PREDECODE", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the total number of consumed retirement slots.", + "EventCode": "0xc2", + "EventName": "TOPDOWN_RETIRING.ALL", + "PEBS": "1", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the total number of uops retired.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.ALL", + "PEBS": "1", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the number of integer divide uops retired.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.IDIV", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of uops that are from complex flows issued by the micro-sequencer (MS).", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.MS", + "PEBS": "1", + "PublicDescription": "Counts the number of uops that are from complex flows issued by the Microcode Sequencer (MS). This includes uops from flows due to complex instructions, faults, assists, and inserted flows.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of x87 uops retired, includes those in MS flows.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.X87", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x2" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/virtual-memory.json b/tools/perf/pmu-events/arch/x86/alderlaken/virtual-memory.json new file mode 100644 index 0000000000000..67fd640f790e6 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/virtual-memory.json @@ -0,0 +1,47 @@ +[ + { + "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to any page size.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0xe" + }, + { + "BriefDescription": "Counts the number of page walks completed due to store DTLB misses to any page size.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0xe" + }, + { + "BriefDescription": "Counts the number of page walks initiated by a instruction fetch that missed the first and second level TLBs.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.MISS_CAUSED_WALK", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of page walks due to an instruction fetch that miss the PDE (Page Directory Entry) cache.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.PDE_CACHE_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of page walks completed due to instruction fetch misses to any page size.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to instruction fetches whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0xe" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a DTLB miss.", + "EventCode": "0x05", + "EventName": "LD_HEAD.DTLB_MISS_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0x90" + } +] diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 5e609b8767903..78af105ca2367 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -1,5 +1,6 @@ Family-model,Version,Filename,EventType -GenuineIntel-6-(97|9A|B7|BA|BE|BF),v1.15,alderlake,core +GenuineIntel-6-(97|9A|B7|BA|BF),v1.15,alderlake,core +GenuineIntel-6-BE,v1.16,alderlaken,core GenuineIntel-6-(1C|26|27|35|36),v4,bonnell,core GenuineIntel-6-(3D|47),v26,broadwell,core GenuineIntel-6-56,v23,broadwellde,core -- GitLab From a6a29bcf596141f95fc0f9756ba68de31ba1f46c Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Thu, 24 Nov 2022 11:14:39 +0800 Subject: [PATCH 1183/1480] perf vendor events intel: Add uncore event list for Alderlake-N Add JSON uncore events for Alderlake-N Based on JSON list v1.16: https://github.com/intel/perfmon/tree/main/ADL/events/ Reviewed-by: Kan Liang Signed-off-by: Xing Zhengjun Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221124031441.110134-2-zhengjun.xing@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/x86/alderlaken/uncore-memory.json | 175 ++++++++++++++++++ .../arch/x86/alderlaken/uncore-other.json | 33 ++++ 2 files changed, 208 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/uncore-memory.json create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/uncore-other.json diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/uncore-memory.json b/tools/perf/pmu-events/arch/x86/alderlaken/uncore-memory.json new file mode 100644 index 0000000000000..2ccd9cf96957f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/uncore-memory.json @@ -0,0 +1,175 @@ +[ + { + "BriefDescription": "Counts every 64B read request entering the Memory Controller 0 to DRAM (sum of all channels).", + "EventName": "UNC_MC0_RDCAS_COUNT_FREERUN", + "PerPkg": "1", + "PublicDescription": "Counts every 64B read request entering the Memory Controller 0 to DRAM (sum of all channels).", + "Unit": "iMC" + }, + { + "BriefDescription": "Counts every 64B write request entering the Memory Controller 0 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM.", + "EventName": "UNC_MC0_WRCAS_COUNT_FREERUN", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Counts every 64B read request entering the Memory Controller 1 to DRAM (sum of all channels).", + "EventName": "UNC_MC1_RDCAS_COUNT_FREERUN", + "PerPkg": "1", + "PublicDescription": "Counts every 64B read entering the Memory Controller 1 to DRAM (sum of all channels).", + "Unit": "iMC" + }, + { + "BriefDescription": "Counts every 64B write request entering the Memory Controller 1 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM.", + "EventName": "UNC_MC1_WRCAS_COUNT_FREERUN", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "ACT command for a read request sent to DRAM", + "EventCode": "0x24", + "EventName": "UNC_M_ACT_COUNT_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "ACT command sent to DRAM", + "EventCode": "0x26", + "EventName": "UNC_M_ACT_COUNT_TOTAL", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "ACT command for a write request sent to DRAM", + "EventCode": "0x25", + "EventName": "UNC_M_ACT_COUNT_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Read CAS command sent to DRAM", + "EventCode": "0x22", + "EventName": "UNC_M_CAS_COUNT_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Write CAS command sent to DRAM", + "EventCode": "0x23", + "EventName": "UNC_M_CAS_COUNT_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Number of clocks", + "EventCode": "0x01", + "EventName": "UNC_M_CLOCKTICKS", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming read request page status is Page Empty", + "EventCode": "0x1D", + "EventName": "UNC_M_DRAM_PAGE_EMPTY_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming write request page status is Page Empty", + "EventCode": "0x20", + "EventName": "UNC_M_DRAM_PAGE_EMPTY_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming read request page status is Page Hit", + "EventCode": "0x1C", + "EventName": "UNC_M_DRAM_PAGE_HIT_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming write request page status is Page Hit", + "EventCode": "0x1F", + "EventName": "UNC_M_DRAM_PAGE_HIT_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming read request page status is Page Miss", + "EventCode": "0x1E", + "EventName": "UNC_M_DRAM_PAGE_MISS_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming write request page status is Page Miss", + "EventCode": "0x21", + "EventName": "UNC_M_DRAM_PAGE_MISS_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Any Rank at Hot state", + "EventCode": "0x19", + "EventName": "UNC_M_DRAM_THERMAL_HOT", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Any Rank at Warm state", + "EventCode": "0x1A", + "EventName": "UNC_M_DRAM_THERMAL_WARM", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Incoming read prefetch request from IA.", + "EventCode": "0x0A", + "EventName": "UNC_M_PREFETCH_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "PRE command sent to DRAM due to page table idle timer expiration", + "EventCode": "0x28", + "EventName": "UNC_M_PRE_COUNT_IDLE", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "PRE command sent to DRAM for a read/write request", + "EventCode": "0x27", + "EventName": "UNC_M_PRE_COUNT_PAGE_MISS", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Incoming VC0 read request", + "EventCode": "0x02", + "EventName": "UNC_M_VC0_REQUESTS_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Incoming VC0 write request", + "EventCode": "0x03", + "EventName": "UNC_M_VC0_REQUESTS_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Incoming VC1 read request", + "EventCode": "0x04", + "EventName": "UNC_M_VC1_REQUESTS_RD", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Incoming VC1 write request", + "EventCode": "0x05", + "EventName": "UNC_M_VC1_REQUESTS_WR", + "PerPkg": "1", + "Unit": "iMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/uncore-other.json b/tools/perf/pmu-events/arch/x86/alderlaken/uncore-other.json new file mode 100644 index 0000000000000..f9e7777cd2be9 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/uncore-other.json @@ -0,0 +1,33 @@ +[ + { + "BriefDescription": "Number of requests allocated in Coherency Tracker.", + "EventCode": "0x84", + "EventName": "UNC_ARB_COH_TRK_REQUESTS.ALL", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "ARB" + }, + { + "BriefDescription": "Each cycle counts number of all outgoing valid entries in ReqTrk. Such entry is defined as valid from its allocation in ReqTrk till deallocation. Accounts for Coherent and non-coherent traffic.", + "EventCode": "0x80", + "EventName": "UNC_ARB_TRK_OCCUPANCY.ALL", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "ARB" + }, + { + "BriefDescription": "Counts the number of coherent and in-coherent requests initiated by IA cores, processor graphic units, or LLC.", + "EventCode": "0x81", + "EventName": "UNC_ARB_TRK_REQUESTS.ALL", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "ARB" + }, + { + "BriefDescription": "This 48-bit fixed counter counts the UCLK cycles.", + "EventCode": "0xff", + "EventName": "UNC_CLOCK.SOCKET", + "PerPkg": "1", + "Unit": "CLOCK" + } +] -- GitLab From 2bb3fbad4c3b3b5b6d5ac537b6ab404443fc5224 Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Thu, 24 Nov 2022 11:14:40 +0800 Subject: [PATCH 1184/1480] perf vendor events intel: Add metrics for Alderlake-N Add JSON metrics for Alderlake-N to perf. It only included E-core metrics. E-core metrics based on E-core TMA v2.2 (E-core_TMA_Metrics.csv) It is downloaded from: https://github.com/intel/perfmon/ Reviewed-by: Kan Liang Signed-off-by: Xing Zhengjun Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221124031441.110134-3-zhengjun.xing@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/x86/alderlaken/adln-metrics.json | 583 ++++++++++++++++++ 1 file changed, 583 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/alderlaken/adln-metrics.json diff --git a/tools/perf/pmu-events/arch/x86/alderlaken/adln-metrics.json b/tools/perf/pmu-events/arch/x86/alderlaken/adln-metrics.json new file mode 100644 index 0000000000000..c57e9f325fb05 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/alderlaken/adln-metrics.json @@ -0,0 +1,583 @@ +[ + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to frontend stalls.", + "MetricExpr": "TOPDOWN_FE_BOUND.ALL / SLOTS", + "MetricGroup": "TopdownL1", + "MetricName": "tma_frontend_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to frontend bandwidth restrictions due to decode, predecode, cisc, and other limitations.", + "MetricExpr": "TOPDOWN_FE_BOUND.FRONTEND_LATENCY / SLOTS", + "MetricGroup": "TopdownL2;tma_frontend_bound_group", + "MetricName": "tma_frontend_latency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to instruction cache misses.", + "MetricExpr": "TOPDOWN_FE_BOUND.ICACHE / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_latency_group", + "MetricName": "tma_icache", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to Instruction Table Lookaside Buffer (ITLB) misses.", + "MetricExpr": "TOPDOWN_FE_BOUND.ITLB / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_latency_group", + "MetricName": "tma_itlb", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to BACLEARS, which occurs when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend", + "MetricExpr": "TOPDOWN_FE_BOUND.BRANCH_DETECT / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_latency_group", + "MetricName": "tma_branch_detect", + "PublicDescription": "Counts the number of issue slots that were not delivered by the frontend due to BACLEARS, which occurs when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to BTCLEARS, which occurs when the Branch Target Buffer (BTB) predicts a taken branch.", + "MetricExpr": "TOPDOWN_FE_BOUND.BRANCH_RESTEER / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_latency_group", + "MetricName": "tma_branch_resteer", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to frontend bandwidth restrictions due to decode, predecode, cisc, and other limitations.", + "MetricExpr": "TOPDOWN_FE_BOUND.FRONTEND_BANDWIDTH / SLOTS", + "MetricGroup": "TopdownL2;tma_frontend_bound_group", + "MetricName": "tma_frontend_bandwidth", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to the microcode sequencer (MS).", + "MetricExpr": "TOPDOWN_FE_BOUND.CISC / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_bandwidth_group", + "MetricName": "tma_cisc", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to decode stalls.", + "MetricExpr": "TOPDOWN_FE_BOUND.DECODE / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_bandwidth_group", + "MetricName": "tma_decode", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to wrong predecodes.", + "MetricExpr": "TOPDOWN_FE_BOUND.PREDECODE / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_bandwidth_group", + "MetricName": "tma_predecode", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not delivered by the frontend due to other common frontend stalls not categorized.", + "MetricExpr": "TOPDOWN_FE_BOUND.OTHER / SLOTS", + "MetricGroup": "TopdownL3;tma_frontend_bandwidth_group", + "MetricName": "tma_other_fb", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear", + "MetricExpr": "(SLOTS - (TOPDOWN_FE_BOUND.ALL + TOPDOWN_BE_BOUND.ALL + TOPDOWN_RETIRING.ALL)) / SLOTS", + "MetricGroup": "TopdownL1", + "MetricName": "tma_bad_speculation", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear. Only issue slots wasted due to fast nukes such as memory ordering nukes are counted. Other nukes are not accounted for. Counts all issue slots blocked during this recovery window including relevant microcode flows and while uops are not yet available in the instruction queue (IQ). Also includes the issue slots that were consumed by the backend but were thrown away because they were younger than the mispredict or machine clear.", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to branch mispredicts.", + "MetricExpr": "TOPDOWN_BAD_SPECULATION.MISPREDICT / SLOTS", + "MetricGroup": "TopdownL2;tma_bad_speculation_group", + "MetricName": "tma_branch_mispredicts", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a machine clear (nuke) of any kind including memory ordering and memory disambiguation.", + "MetricExpr": "TOPDOWN_BAD_SPECULATION.MACHINE_CLEARS / SLOTS", + "MetricGroup": "TopdownL2;tma_bad_speculation_group", + "MetricName": "tma_machine_clears", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to a machine clear (slow nuke).", + "MetricExpr": "TOPDOWN_BAD_SPECULATION.NUKE / SLOTS", + "MetricGroup": "TopdownL3;tma_machine_clears_group", + "MetricName": "tma_nuke", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of machine clears relative to the number of nuke slots due to SMC. ", + "MetricExpr": "tma_nuke * (MACHINE_CLEARS.SMC / MACHINE_CLEARS.SLOW)", + "MetricGroup": "TopdownL4;tma_nuke_group", + "MetricName": "tma_smc", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of machine clears relative to the number of nuke slots due to memory ordering. ", + "MetricExpr": "tma_nuke * (MACHINE_CLEARS.MEMORY_ORDERING / MACHINE_CLEARS.SLOW)", + "MetricGroup": "TopdownL4;tma_nuke_group", + "MetricName": "tma_memory_ordering", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of machine clears relative to the number of nuke slots due to FP assists. ", + "MetricExpr": "tma_nuke * (MACHINE_CLEARS.FP_ASSIST / MACHINE_CLEARS.SLOW)", + "MetricGroup": "TopdownL4;tma_nuke_group", + "MetricName": "tma_fp_assist", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of machine clears relative to the number of nuke slots due to memory disambiguation. ", + "MetricExpr": "tma_nuke * (MACHINE_CLEARS.DISAMBIGUATION / MACHINE_CLEARS.SLOW)", + "MetricGroup": "TopdownL4;tma_nuke_group", + "MetricName": "tma_disambiguation", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of machine clears relative to the number of nuke slots due to page faults. ", + "MetricExpr": "tma_nuke * (MACHINE_CLEARS.PAGE_FAULT / MACHINE_CLEARS.SLOW)", + "MetricGroup": "TopdownL4;tma_nuke_group", + "MetricName": "tma_page_fault", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to a machine clear classified as a fast nuke due to memory ordering, memory disambiguation and memory renaming.", + "MetricExpr": "TOPDOWN_BAD_SPECULATION.FASTNUKE / SLOTS", + "MetricGroup": "TopdownL3;tma_machine_clears_group", + "MetricName": "tma_fast_nuke", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls", + "MetricExpr": "TOPDOWN_BE_BOUND.ALL / SLOTS", + "MetricGroup": "TopdownL1", + "MetricName": "tma_backend_bound", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls. Note that uops must be available for consumption in order for this event to count. If a uop is not available (IQ is empty), this event will not count. The rest of these subevents count backend stalls, in cycles, due to an outstanding request which is memory bound vs core bound. The subevents are not slot based events and therefore can not be precisely added or subtracted from the Backend_Bound_Aux subevents which are slot based.", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles due to backend bound stalls that are core execution bound and not attributed to outstanding demand load or store stalls. ", + "MetricExpr": "max(0, tma_backend_bound - tma_load_store_bound)", + "MetricGroup": "TopdownL2;tma_backend_bound_group", + "MetricName": "tma_core_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to stores or loads. ", + "MetricExpr": "min((TOPDOWN_BE_BOUND.ALL / SLOTS), (LD_HEAD.ANY_AT_RET / CLKS) + tma_store_bound)", + "MetricGroup": "TopdownL2;tma_backend_bound_group", + "MetricName": "tma_load_store_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to store buffer full.", + "MetricExpr": "tma_mem_scheduler * (MEM_SCHEDULER_BLOCK.ST_BUF / MEM_SCHEDULER_BLOCK.ALL)", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_store_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles that the oldest load of the load buffer is stalled at retirement due to a load block.", + "MetricExpr": "LD_HEAD.L1_BOUND_AT_RET / CLKS", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_l1_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles that the oldest load of the load buffer is stalled at retirement due to a store forward block.", + "MetricExpr": "LD_HEAD.ST_ADDR_AT_RET / CLKS", + "MetricGroup": "TopdownL4;tma_l1_bound_group", + "MetricName": "tma_store_fwd", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles that the oldest load of the load buffer is stalled at retirement due to a first level TLB miss.", + "MetricExpr": "LD_HEAD.DTLB_MISS_AT_RET / CLKS", + "MetricGroup": "TopdownL4;tma_l1_bound_group", + "MetricName": "tma_stlb_hit", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles that the oldest load of the load buffer is stalled at retirement due to a second level TLB miss requiring a page walk.", + "MetricExpr": "LD_HEAD.PGWALK_AT_RET / CLKS", + "MetricGroup": "TopdownL4;tma_l1_bound_group", + "MetricName": "tma_stlb_miss", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles that the oldest load of the load buffer is stalled at retirement due to a number of other load blocks.", + "MetricExpr": "LD_HEAD.OTHER_AT_RET / CLKS", + "MetricGroup": "TopdownL4;tma_l1_bound_group", + "MetricName": "tma_other_l1", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles a core is stalled due to a demand load which hit in the L2 Cache.", + "MetricExpr": "(MEM_BOUND_STALLS.LOAD_L2_HIT / CLKS) - (MEM_BOUND_STALLS_AT_RET_CORRECTION * MEM_BOUND_STALLS.LOAD_L2_HIT / MEM_BOUND_STALLS.LOAD)", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_l2_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles a core is stalled due to a demand load which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "MetricExpr": "(MEM_BOUND_STALLS.LOAD_LLC_HIT / CLKS) - (MEM_BOUND_STALLS_AT_RET_CORRECTION * MEM_BOUND_STALLS.LOAD_LLC_HIT / MEM_BOUND_STALLS.LOAD)", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_l3_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in DRAM or MMIO (Non-DRAM).", + "MetricExpr": "(MEM_BOUND_STALLS.LOAD_DRAM_HIT / CLKS) - (MEM_BOUND_STALLS_AT_RET_CORRECTION * MEM_BOUND_STALLS.LOAD_DRAM_HIT / MEM_BOUND_STALLS.LOAD)", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_dram_bound", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hits in the L2, LLC, DRAM or MMIO (Non-DRAM) but could not be correctly attributed or cycles in which the load miss is waiting on a request buffer.", + "MetricExpr": "max(0, tma_load_store_bound - (tma_store_bound + tma_l1_bound + tma_l2_bound + tma_l3_bound + tma_dram_bound))", + "MetricGroup": "TopdownL3;tma_load_store_bound_group", + "MetricName": "tma_other_load_store", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls", + "MetricExpr": "tma_backend_bound", + "MetricGroup": "TopdownL1", + "MetricName": "tma_backend_bound_aux", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls. Note that UOPS must be available for consumption in order for this event to count. If a uop is not available (IQ is empty), this event will not count. All of these subevents count backend stalls, in slots, due to a resource limitation. These are not cycle based events and therefore can not be precisely added or subtracted from the Backend_Bound subevents which are cycle based. These subevents are supplementary to Backend_Bound and can be used to analyze results from a resource perspective at allocation. ", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls", + "MetricExpr": "tma_backend_bound", + "MetricGroup": "TopdownL2;tma_backend_bound_aux_group", + "MetricName": "tma_resource_bound", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend due to backend stalls. Note that uops must be available for consumption in order for this event to count. If a uop is not available (IQ is empty), this event will not count. ", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to memory reservation stalls in which a scheduler is not able to accept uops.", + "MetricExpr": "TOPDOWN_BE_BOUND.MEM_SCHEDULER / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_mem_scheduler", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles, relative to the number of mem_scheduler slots, in which uops are blocked due to store buffer full", + "MetricExpr": "tma_mem_scheduler * (MEM_SCHEDULER_BLOCK.ST_BUF / MEM_SCHEDULER_BLOCK.ALL)", + "MetricGroup": "TopdownL4;tma_mem_scheduler_group", + "MetricName": "tma_st_buffer", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles, relative to the number of mem_scheduler slots, in which uops are blocked due to load buffer full", + "MetricExpr": "tma_mem_scheduler * MEM_SCHEDULER_BLOCK.LD_BUF / MEM_SCHEDULER_BLOCK.ALL", + "MetricGroup": "TopdownL4;tma_mem_scheduler_group", + "MetricName": "tma_ld_buffer", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of cycles, relative to the number of mem_scheduler slots, in which uops are blocked due to RSV full relative ", + "MetricExpr": "tma_mem_scheduler * MEM_SCHEDULER_BLOCK.RSV / MEM_SCHEDULER_BLOCK.ALL", + "MetricGroup": "TopdownL4;tma_mem_scheduler_group", + "MetricName": "tma_rsv", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to IEC or FPC RAT stalls, which can be due to FIQ or IEC reservation stalls in which the integer, floating point or SIMD scheduler is not able to accept uops.", + "MetricExpr": "TOPDOWN_BE_BOUND.NON_MEM_SCHEDULER / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_non_mem_scheduler", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to the physical register file unable to accept an entry (marble stalls).", + "MetricExpr": "TOPDOWN_BE_BOUND.REGISTER / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_register", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to the reorder buffer being full (ROB stalls).", + "MetricExpr": "TOPDOWN_BE_BOUND.REORDER_BUFFER / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_reorder_buffer", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to certain allocation restrictions.", + "MetricExpr": "TOPDOWN_BE_BOUND.ALLOC_RESTRICTIONS / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_alloc_restriction", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to scoreboards from the instruction queue (IQ), jump execution unit (JEU), or microcode sequencer (MS).", + "MetricExpr": "TOPDOWN_BE_BOUND.SERIALIZATION / SLOTS", + "MetricGroup": "TopdownL3;tma_resource_bound_group", + "MetricName": "tma_serialization", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the numer of issue slots that result in retirement slots. ", + "MetricExpr": "TOPDOWN_RETIRING.ALL / SLOTS", + "MetricGroup": "TopdownL1", + "MetricName": "tma_retiring", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of uops that are not from the microsequencer. ", + "MetricExpr": "(TOPDOWN_RETIRING.ALL - UOPS_RETIRED.MS) / SLOTS", + "MetricGroup": "TopdownL2;tma_retiring_group", + "MetricName": "tma_base", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of floating point operations per uop with all default weighting.", + "MetricExpr": "UOPS_RETIRED.FPDIV / SLOTS", + "MetricGroup": "TopdownL3;tma_base_group", + "MetricName": "tma_fp_uops", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of uops retired excluding ms and fp div uops.", + "MetricExpr": "(TOPDOWN_RETIRING.ALL - UOPS_RETIRED.MS - UOPS_RETIRED.FPDIV) / SLOTS", + "MetricGroup": "TopdownL3;tma_base_group", + "MetricName": "tma_other_ret", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "Counts the number of uops that are from the complex flows issued by the micro-sequencer (MS)", + "MetricExpr": "UOPS_RETIRED.MS / SLOTS", + "MetricGroup": "TopdownL2;tma_retiring_group", + "MetricName": "tma_ms_uops", + "PublicDescription": "Counts the number of uops that are from the complex flows issued by the micro-sequencer (MS). This includes uops from flows due to complex instructions, faults, assists, and inserted flows.", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "", + "MetricExpr": "CPU_CLK_UNHALTED.CORE", + "MetricName": "CLKS" + }, + { + "BriefDescription": "", + "MetricExpr": "CPU_CLK_UNHALTED.CORE_P", + "MetricName": "CLKS_P" + }, + { + "BriefDescription": "", + "MetricExpr": "5 * CLKS", + "MetricName": "SLOTS" + }, + { + "BriefDescription": "Instructions Per Cycle", + "MetricExpr": "INST_RETIRED.ANY / CLKS", + "MetricName": "IPC" + }, + { + "BriefDescription": "Cycles Per Instruction", + "MetricExpr": "CLKS / INST_RETIRED.ANY", + "MetricName": "CPI" + }, + { + "BriefDescription": "Uops Per Instruction", + "MetricExpr": "UOPS_RETIRED.ALL / INST_RETIRED.ANY", + "MetricName": "UPI" + }, + { + "BriefDescription": "Percentage of total non-speculative loads with a store forward or unknown store address block", + "MetricExpr": "100 * LD_BLOCKS.DATA_UNKNOWN / MEM_UOPS_RETIRED.ALL_LOADS", + "MetricName": "Store_Fwd_Blocks" + }, + { + "BriefDescription": "Percentage of total non-speculative loads with a address aliasing block", + "MetricExpr": "100 * LD_BLOCKS.4K_ALIAS / MEM_UOPS_RETIRED.ALL_LOADS", + "MetricName": "Address_Alias_Blocks" + }, + { + "BriefDescription": "Percentage of total non-speculative loads that are splits", + "MetricExpr": "100 * MEM_UOPS_RETIRED.SPLIT_LOADS / MEM_UOPS_RETIRED.ALL_LOADS", + "MetricName": "Load_Splits" + }, + { + "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", + "MetricName": "IpBranch" + }, + { + "BriefDescription": "Instruction per (near) call (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.CALL", + "MetricName": "IpCall" + }, + { + "BriefDescription": "Instructions per Load", + "MetricExpr": "INST_RETIRED.ANY / MEM_UOPS_RETIRED.ALL_LOADS", + "MetricName": "IpLoad" + }, + { + "BriefDescription": "Instructions per Store", + "MetricExpr": "INST_RETIRED.ANY / MEM_UOPS_RETIRED.ALL_STORES", + "MetricName": "IpStore" + }, + { + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction", + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "MetricName": "IpMispredict" + }, + { + "BriefDescription": "Instructions per Far Branch", + "MetricExpr": "INST_RETIRED.ANY / (BR_INST_RETIRED.FAR_BRANCH / 2)", + "MetricName": "IpFarBranch" + }, + { + "BriefDescription": "Ratio of all branches which mispredict", + "MetricExpr": "BR_MISP_RETIRED.ALL_BRANCHES / BR_INST_RETIRED.ALL_BRANCHES", + "MetricName": "Branch_Mispredict_Ratio" + }, + { + "BriefDescription": "Ratio between Mispredicted branches and unknown branches", + "MetricExpr": "BR_MISP_RETIRED.ALL_BRANCHES / BACLEARS.ANY", + "MetricName": "Branch_Mispredict_to_Unknown_Branch_Ratio" + }, + { + "BriefDescription": "Percentage of all uops which are ucode ops", + "MetricExpr": "100 * UOPS_RETIRED.MS / UOPS_RETIRED.ALL", + "MetricName": "Microcode_Uop_Ratio" + }, + { + "BriefDescription": "Percentage of all uops which are FPDiv uops", + "MetricExpr": "100 * UOPS_RETIRED.FPDIV / UOPS_RETIRED.ALL", + "MetricName": "FPDiv_Uop_Ratio" + }, + { + "BriefDescription": "Percentage of all uops which are IDiv uops", + "MetricExpr": "100 * UOPS_RETIRED.IDIV / UOPS_RETIRED.ALL", + "MetricName": "IDiv_Uop_Ratio" + }, + { + "BriefDescription": "Percentage of all uops which are x87 uops", + "MetricExpr": "100 * UOPS_RETIRED.X87 / UOPS_RETIRED.ALL", + "MetricName": "X87_Uop_Ratio" + }, + { + "BriefDescription": "Average Frequency Utilization relative nominal frequency", + "MetricExpr": "CLKS / CPU_CLK_UNHALTED.REF_TSC", + "MetricName": "Turbo_Utilization" + }, + { + "BriefDescription": "Fraction of cycles spent in Kernel mode", + "MetricExpr": "cpu@CPU_CLK_UNHALTED.CORE@k / CPU_CLK_UNHALTED.CORE", + "MetricName": "Kernel_Utilization" + }, + { + "BriefDescription": "Average CPU Utilization", + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / TSC", + "MetricName": "CPU_Utilization" + }, + { + "BriefDescription": "Cycle cost per L2 hit", + "MetricExpr": "MEM_BOUND_STALLS.LOAD_L2_HIT / MEM_LOAD_UOPS_RETIRED.L2_HIT", + "MetricName": "Cycles_per_Demand_Load_L2_Hit" + }, + { + "BriefDescription": "Cycle cost per LLC hit", + "MetricExpr": "MEM_BOUND_STALLS.LOAD_LLC_HIT / MEM_LOAD_UOPS_RETIRED.L3_HIT", + "MetricName": "Cycles_per_Demand_Load_L3_Hit" + }, + { + "BriefDescription": "Cycle cost per DRAM hit", + "MetricExpr": "MEM_BOUND_STALLS.LOAD_DRAM_HIT / MEM_LOAD_UOPS_RETIRED.DRAM_HIT", + "MetricName": "Cycles_per_Demand_Load_DRAM_Hit" + }, + { + "BriefDescription": "Percent of instruction miss cost that hit in the L2", + "MetricExpr": "100 * MEM_BOUND_STALLS.IFETCH_L2_HIT / (MEM_BOUND_STALLS.IFETCH)", + "MetricName": "Inst_Miss_Cost_L2Hit_Percent" + }, + { + "BriefDescription": "Percent of instruction miss cost that hit in the L3", + "MetricExpr": "100 * MEM_BOUND_STALLS.IFETCH_LLC_HIT / (MEM_BOUND_STALLS.IFETCH)", + "MetricName": "Inst_Miss_Cost_L3Hit_Percent" + }, + { + "BriefDescription": "Percent of instruction miss cost that hit in DRAM", + "MetricExpr": "100 * MEM_BOUND_STALLS.IFETCH_DRAM_HIT / (MEM_BOUND_STALLS.IFETCH)", + "MetricName": "Inst_Miss_Cost_DRAMHit_Percent" + }, + { + "BriefDescription": "load ops retired per 1000 instruction", + "MetricExpr": "1000 * MEM_UOPS_RETIRED.ALL_LOADS / INST_RETIRED.ANY", + "MetricName": "MemLoadPKI" + }, + { + "BriefDescription": "C1 residency percent per core", + "MetricExpr": "cstate_core@c1\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C1_Core_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C6 residency percent per core", + "MetricExpr": "cstate_core@c6\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C6_Core_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C7 residency percent per core", + "MetricExpr": "cstate_core@c7\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C7_Core_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C2 residency percent per package", + "MetricExpr": "cstate_pkg@c2\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C2_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C3 residency percent per package", + "MetricExpr": "cstate_pkg@c3\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C3_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C6 residency percent per package", + "MetricExpr": "cstate_pkg@c6\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C6_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C7 residency percent per package", + "MetricExpr": "cstate_pkg@c7\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C7_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C8 residency percent per package", + "MetricExpr": "cstate_pkg@c8\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C8_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C9 residency percent per package", + "MetricExpr": "cstate_pkg@c9\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C9_Pkg_Residency", + "ScaleUnit": "100%" + }, + { + "BriefDescription": "C10 residency percent per package", + "MetricExpr": "cstate_pkg@c10\\-residency@ / TSC", + "MetricGroup": "Power", + "MetricName": "C10_Pkg_Residency", + "ScaleUnit": "100%" + } +] -- GitLab From 4c12f41a14d6c4dd2b4e387eaea249cee68bc01a Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Thu, 24 Nov 2022 11:14:41 +0800 Subject: [PATCH 1185/1480] perf vendor events intel: Update events and metrics for alderlake Update JSON events and metrics for alderlake to perf. Based on ADL JSON event list v1.16: https://github.com/intel/perfmon/tree/main/ADL/events Generate the event list and metrics with the converter scripts: https://github.com/intel/perfmon/pull/32 Reviewed-by: Kan Liang Signed-off-by: Xing Zhengjun Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221124031441.110134-4-zhengjun.xing@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/x86/alderlake/adl-metrics.json | 73 +- .../pmu-events/arch/x86/alderlake/cache.json | 1391 +++++------- .../arch/x86/alderlake/floating-point.json | 91 +- .../arch/x86/alderlake/frontend.json | 224 +- .../pmu-events/arch/x86/alderlake/memory.json | 214 +- .../pmu-events/arch/x86/alderlake/other.json | 132 +- .../arch/x86/alderlake/pipeline.json | 1932 ++++++----------- .../arch/x86/alderlake/uncore-memory.json | 185 +- .../arch/x86/alderlake/uncore-other.json | 73 +- .../arch/x86/alderlake/virtual-memory.json | 223 +- tools/perf/pmu-events/arch/x86/mapfile.csv | 2 +- 11 files changed, 1687 insertions(+), 2853 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/alderlake/adl-metrics.json b/tools/perf/pmu-events/arch/x86/alderlake/adl-metrics.json index e06d26ad51385..edf440e9359af 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/adl-metrics.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/adl-metrics.json @@ -1287,14 +1287,14 @@ }, { "BriefDescription": "Average CPU Utilization", - "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / TSC", "MetricGroup": "HPC;Summary", "MetricName": "CPU_Utilization", "Unit": "cpu_core" }, { "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", - "MetricExpr": "Turbo_Utilization * msr@tsc@ / 1000000000 / duration_time", + "MetricExpr": "Turbo_Utilization * TSC / 1000000000 / duration_time", "MetricGroup": "Power;Summary", "MetricName": "Average_Frequency", "Unit": "cpu_core" @@ -1337,18 +1337,25 @@ }, { "BriefDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]", - "MetricExpr": "64 * (arb@event\\=0x81\\,umask\\=0x1@ + arb@event\\=0x84\\,umask\\=0x1@) / 1000000 / duration_time / 1000", + "MetricExpr": "64 * (UNC_ARB_TRK_REQUESTS.ALL + UNC_ARB_COH_TRK_REQUESTS.ALL) / 1000000 / duration_time / 1000", "MetricGroup": "HPC;Mem;MemoryBW;SoC", "MetricName": "DRAM_BW_Use", "Unit": "cpu_core" }, { "BriefDescription": "Average number of parallel requests to external memory. Accounts for all requests", - "MetricExpr": "UNC_ARB_TRK_OCCUPANCY.ALL / arb@event\\=0x81\\,umask\\=0x1@", + "MetricExpr": "UNC_ARB_TRK_OCCUPANCY.ALL / UNC_ARB_TRK_REQUESTS.ALL", "MetricGroup": "Mem;SoC", "MetricName": "MEM_Parallel_Requests", "Unit": "cpu_core" }, + { + "BriefDescription": "Socket actual clocks when any core is active on that socket", + "MetricExpr": "UNC_CLOCK.SOCKET", + "MetricGroup": "SoC", + "MetricName": "Socket_CLKS", + "Unit": "cpu_core" + }, { "BriefDescription": "Instructions per Far Branch ( Far Branches apply upon transition from application to operating system, handling interrupts, exceptions) [lower number means higher occurrence rate]", "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.FAR_BRANCH:u", @@ -1356,6 +1363,12 @@ "MetricName": "IpFarBranch", "Unit": "cpu_core" }, + { + "BriefDescription": "Uncore frequency per die [GHZ]", + "MetricExpr": "Socket_CLKS / #num_dies / duration_time / 1000000000", + "MetricGroup": "SoC", + "MetricName": "UNCORE_FREQ" + }, { "BriefDescription": "Counts the number of issue slots that were not consumed by the backend due to frontend stalls.", "MetricExpr": "TOPDOWN_FE_BOUND.ALL / SLOTS", @@ -1902,7 +1915,7 @@ }, { "BriefDescription": "Average CPU Utilization", - "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / TSC", "MetricName": "CPU_Utilization", "Unit": "cpu_atom" }, @@ -1950,62 +1963,72 @@ }, { "BriefDescription": "C1 residency percent per core", - "MetricExpr": "(cstate_core@c1\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_core@c1\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C1_Core_Residency" + "MetricName": "C1_Core_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C6 residency percent per core", - "MetricExpr": "(cstate_core@c6\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_core@c6\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C6_Core_Residency" + "MetricName": "C6_Core_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C7 residency percent per core", - "MetricExpr": "(cstate_core@c7\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_core@c7\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C7_Core_Residency" + "MetricName": "C7_Core_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C2 residency percent per package", - "MetricExpr": "(cstate_pkg@c2\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c2\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C2_Pkg_Residency" + "MetricName": "C2_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C3 residency percent per package", - "MetricExpr": "(cstate_pkg@c3\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c3\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C3_Pkg_Residency" + "MetricName": "C3_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C6 residency percent per package", - "MetricExpr": "(cstate_pkg@c6\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c6\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C6_Pkg_Residency" + "MetricName": "C6_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C7 residency percent per package", - "MetricExpr": "(cstate_pkg@c7\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c7\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C7_Pkg_Residency" + "MetricName": "C7_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C8 residency percent per package", - "MetricExpr": "(cstate_pkg@c8\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c8\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C8_Pkg_Residency" + "MetricName": "C8_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C9 residency percent per package", - "MetricExpr": "(cstate_pkg@c9\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c9\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C9_Pkg_Residency" + "MetricName": "C9_Pkg_Residency", + "ScaleUnit": "100%" }, { "BriefDescription": "C10 residency percent per package", - "MetricExpr": "(cstate_pkg@c10\\-residency@ / msr@tsc@) * 100", + "MetricExpr": "cstate_pkg@c10\\-residency@ / TSC", "MetricGroup": "Power", - "MetricName": "C10_Pkg_Residency" + "MetricName": "C10_Pkg_Residency", + "ScaleUnit": "100%" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/cache.json b/tools/perf/pmu-events/arch/x86/alderlake/cache.json index 2cc62d2779d20..adc9887b8ae0f 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/cache.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/cache.json @@ -1,1178 +1,871 @@ [ - { - "BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x2e", - "EventName": "LONGEST_LAT_CACHE.MISS", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x41", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cacheable memory requests that access the LLC. Counts on a per core basis.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x2e", - "EventName": "LONGEST_LAT_CACHE.REFERENCE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x4f", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.IFETCH", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x38", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in DRAM or MMIO (Non-DRAM).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.IFETCH_DRAM_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x20", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.IFETCH_L2_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x8", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the LLC or other core with HITE/F/M.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.IFETCH_LLC_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x10", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.LOAD", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x7", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in DRAM or MMIO (Non-DRAM).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.LOAD_DRAM_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.LOAD_L2_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the LLC or other core with HITE/F/M.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x34", - "EventName": "MEM_BOUND_STALLS.LOAD_LLC_HIT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of load uops retired that hit in DRAM.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_UOPS_RETIRED.DRAM_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x80", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of load uops retired that hit in the L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_UOPS_RETIRED.L2_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of load uops retired that hit in the L3 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles that uops are blocked for any of the following reasons: load buffer, store buffer or RSV full.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x04", - "EventName": "MEM_SCHEDULER_BLOCK.ALL", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x7", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles that uops are blocked due to a load buffer full condition.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x04", - "EventName": "MEM_SCHEDULER_BLOCK.LD_BUF", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles that uops are blocked due to an RSV full condition.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x04", - "EventName": "MEM_SCHEDULER_BLOCK.RSV", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles that uops are blocked due to a store buffer full condition.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x04", - "EventName": "MEM_SCHEDULER_BLOCK.ST_BUF", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of load uops retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.ALL_LOADS", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x81", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of store uops retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.ALL_STORES", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x82", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x80", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x10", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x100", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x20", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x4", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x200", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x40", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8", - "L1_Hit_Indication": "1", - "MSRIndex": "0x3F6", - "MSRValue": "0x8", - "PEBS": "2", - "PEBScounters": "0,1", - "SampleAfterValue": "1000003", - "TakenAlone": "1", - "UMask": "0x5", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of retired split load uops.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.SPLIT_LOADS", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x41", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of stores uops retired. Counts with or without PEBS enabled.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "Data_LA": "1", - "EventCode": "0xd0", - "EventName": "MEM_UOPS_RETIRED.STORE_LATENCY", - "L1_Hit_Indication": "1", - "PEBS": "2", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "UMask": "0x6", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that were supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HITM", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, but no data was forwarded.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x4003C0001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and non-modified data was forwarded.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x8003C0001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_RFO.L3_HIT", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0002", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0002", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to instruction cache misses.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.ICACHE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x20", - "Unit": "cpu_atom" - }, { "BriefDescription": "L1D.HWPF_MISS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x51", "EventName": "L1D.HWPF_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Counts the number of cache lines replaced in L1 data cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x51", "EventName": "L1D.REPLACEMENT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailability.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.FB_FULL", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { - "BriefDescription": "Number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailablability.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailability.", "CounterMask": "1", "EdgeDetect": "1", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.FB_FULL_PERIODS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event L1D_PEND_MISS.L2_STALLS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "Deprecated": "1", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.L2_STALL", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Number of cycles a demand request has waited due to L1D due to lack of L2 resources.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.L2_STALLS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D due to lack of L2 resources. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Number of L1D misses that are outstanding", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.PENDING", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of L1D misses that are outstanding in each cycle, that is each cycle the number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch. Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles with L1D load Misses outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x48", "EventName": "L1D_PEND_MISS.PENDING_CYCLES", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "L2 cache lines filling L2", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x25", "EventName": "L2_LINES_IN.ALL", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1f", "Unit": "cpu_core" }, { "BriefDescription": "Cache lines that have been L2 hardware prefetched but not used by demand accesses", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x26", "EventName": "L2_LINES_OUT.USELESS_HWPF", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cache lines that have been prefetched by the L2 hardware prefetcher but not used by demand access when evicted from the L2 cache", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "All accesses to L2 cache[This event is alias to L2_RQSTS.REFERENCES]", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_REQUEST.ALL", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all requests that were hit or true misses in L2 cache. True-miss excludes misses that were merged with ongoing L2 misses.[This event is alias to L2_RQSTS.REFERENCES]", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xff", "Unit": "cpu_core" }, { "BriefDescription": "Read requests with true-miss in L2 cache.[This event is alias to L2_RQSTS.MISS]", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_REQUEST.MISS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts read requests of any type with true-miss in the L2 cache. True-miss excludes L2 misses that were merged with ongoing L2 misses.[This event is alias to L2_RQSTS.MISS]", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x3f", "Unit": "cpu_core" }, { "BriefDescription": "L2 code requests", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.ALL_CODE_RD", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of L2 code requests.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xe4", "Unit": "cpu_core" }, { "BriefDescription": "Demand Data Read access L2 cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts Demand Data Read requests accessing the L2 cache. These requests may hit or miss L2 cache. True-miss exclude misses that were merged with ongoing L2 misses. An access is counted once.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xe1", "Unit": "cpu_core" }, { "BriefDescription": "Demand requests that miss L2 cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.ALL_DEMAND_MISS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts demand requests that miss L2 cache.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x27", "Unit": "cpu_core" }, { "BriefDescription": "L2_RQSTS.ALL_HWPF", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.ALL_HWPF", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xf0", "Unit": "cpu_core" }, { "BriefDescription": "RFO requests to L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.ALL_RFO", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xe2", "Unit": "cpu_core" }, { "BriefDescription": "L2 cache hits when fetching instructions, code reads.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.CODE_RD_HIT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xc4", "Unit": "cpu_core" }, { "BriefDescription": "L2 cache misses when fetching instructions", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.CODE_RD_MISS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x24", "Unit": "cpu_core" }, { "BriefDescription": "Demand Data Read requests that hit L2 cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of demand Data Read requests initiated by load instructions that hit L2 cache.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0xc1", "Unit": "cpu_core" }, { "BriefDescription": "Demand Data Read miss L2 cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts demand Data Read requests with true-miss in the L2 cache. True-miss excludes misses that were merged with ongoing L2 misses. An access is counted once.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x21", "Unit": "cpu_core" }, { "BriefDescription": "L2_RQSTS.HWPF_MISS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.HWPF_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x30", "Unit": "cpu_core" }, { "BriefDescription": "Read requests with true-miss in L2 cache.[This event is alias to L2_REQUEST.MISS]", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x24", "EventName": "L2_RQSTS.MISS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts read requests of any type with true-miss in the L2 cache. True-miss excludes L2 misses that were merged with ongoing L2 misses.[This event is alias to L2_REQUEST.MISS]", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x3f", "Unit": "cpu_core" }, { - "BriefDescription": "All accesses to L2 cache[This event is alias to L2_REQUEST.ALL]", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x24", - "EventName": "L2_RQSTS.REFERENCES", - "PEBScounters": "0,1,2,3", + "BriefDescription": "All accesses to L2 cache[This event is alias to L2_REQUEST.ALL]", + "EventCode": "0x24", + "EventName": "L2_RQSTS.REFERENCES", + "PublicDescription": "Counts all requests that were hit or true misses in L2 cache. True-miss excludes misses that were merged with ongoing L2 misses.[This event is alias to L2_REQUEST.ALL]", + "SampleAfterValue": "200003", + "UMask": "0xff", + "Unit": "cpu_core" + }, + { + "BriefDescription": "RFO requests that hit L2 cache.", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_HIT", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xc2", + "Unit": "cpu_core" + }, + { + "BriefDescription": "RFO requests that miss L2 cache", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_MISS", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x22", + "Unit": "cpu_core" + }, + { + "BriefDescription": "SW prefetch requests that hit L2 cache.", + "EventCode": "0x24", + "EventName": "L2_RQSTS.SWPF_HIT", + "PublicDescription": "Counts Software prefetch requests that hit the L2 cache. Accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions when FB is not full.", + "SampleAfterValue": "200003", + "UMask": "0xc8", + "Unit": "cpu_core" + }, + { + "BriefDescription": "SW prefetch requests that miss L2 cache.", + "EventCode": "0x24", + "EventName": "L2_RQSTS.SWPF_MISS", + "PublicDescription": "Counts Software prefetch requests that miss the L2 cache. Accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions when FB is not full.", + "SampleAfterValue": "200003", + "UMask": "0x28", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts the number of cacheable memory requests that miss in the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x41", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Core-originated cacheable requests that missed L3 (Except hardware prefetches to the L3)", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches to the L1 and L2. It does not include hardware prefetches to the L3, and may not count other types of requests to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x41", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of cacheable memory requests that access the LLC. Counts on a per core basis.", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts the number of cacheable memory requests that access the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x4f", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Core-originated cacheable requests that refer to L3 (Except hardware prefetches to the L3)", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches to the L1 and L2. It does not include hardware prefetches to the L3, and may not count other types of requests to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x4f", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or translation lookaside buffer (TLB) miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "SampleAfterValue": "200003", + "UMask": "0x38", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_DRAM_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or translation lookaside buffer (TLB) miss which hit in DRAM or MMIO (non-DRAM).", "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0xff", - "Unit": "cpu_core" + "UMask": "0x20", + "Unit": "cpu_atom" }, { - "BriefDescription": "RFO requests that hit L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x24", - "EventName": "L2_RQSTS.RFO_HIT", - "PEBScounters": "0,1,2,3", + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2 cache.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_L2_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) miss which hit in the L2 cache.", "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0xc2", - "Unit": "cpu_core" + "UMask": "0x8", + "Unit": "cpu_atom" }, { - "BriefDescription": "RFO requests that miss L2 cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x24", - "EventName": "L2_RQSTS.RFO_MISS", - "PEBScounters": "0,1,2,3", + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the LLC or other core with HITE/F/M.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_LLC_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) miss which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x22", - "Unit": "cpu_core" + "UMask": "0x10", + "Unit": "cpu_atom" }, { - "BriefDescription": "SW prefetch requests that hit L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x24", - "EventName": "L2_RQSTS.SWPF_HIT", - "PEBScounters": "0,1,2,3", + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in the L2, LLC, DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD", "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0xc8", - "Unit": "cpu_core" + "UMask": "0x7", + "Unit": "cpu_atom" }, { - "BriefDescription": "SW prefetch requests that miss L2 cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x24", - "EventName": "L2_RQSTS.SWPF_MISS", - "PEBScounters": "0,1,2,3", + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in DRAM or MMIO (Non-DRAM).", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_DRAM_HIT", "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x28", - "Unit": "cpu_core" + "UMask": "0x4", + "Unit": "cpu_atom" }, { - "BriefDescription": "Core-originated cacheable requests that missed L3 (Except hardware prefetches to the L3)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", - "EventCode": "0x2e", - "EventName": "LONGEST_LAT_CACHE.MISS", - "PEBScounters": "0,1,2,3,4,5,6,7", - "SampleAfterValue": "100003", - "Speculative": "1", - "UMask": "0x41", - "Unit": "cpu_core" + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the L2 cache.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_L2_HIT", + "SampleAfterValue": "200003", + "UMask": "0x1", + "Unit": "cpu_atom" }, { - "BriefDescription": "Core-originated cacheable requests that refer to L3 (Except hardware prefetches to the L3)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", - "EventCode": "0x2e", - "EventName": "LONGEST_LAT_CACHE.REFERENCE", - "PEBScounters": "0,1,2,3,4,5,6,7", - "SampleAfterValue": "100003", - "Speculative": "1", - "UMask": "0x4f", - "Unit": "cpu_core" + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the LLC or other core with HITE/F/M.", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_LLC_HIT", + "PublicDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "SampleAfterValue": "200003", + "UMask": "0x2", + "Unit": "cpu_atom" }, { "BriefDescription": "Retired load instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.ALL_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all retired load instructions. This event accounts for SW prefetch instructions of PREFETCHNTA or PREFETCHT0/1/2 or PREFETCHW.", "SampleAfterValue": "1000003", "UMask": "0x81", "Unit": "cpu_core" }, { "BriefDescription": "Retired store instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.ALL_STORES", - "L1_Hit_Indication": "1", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all retired store instructions.", "SampleAfterValue": "1000003", "UMask": "0x82", "Unit": "cpu_core" }, { "BriefDescription": "All retired memory instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.ANY", - "L1_Hit_Indication": "1", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all retired memory instructions - loads and stores.", "SampleAfterValue": "1000003", "UMask": "0x83", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions with locked access.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.LOCK_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with locked access.", "SampleAfterValue": "100007", "UMask": "0x21", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions that split across a cacheline boundary.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", "SampleAfterValue": "100003", "UMask": "0x41", "Unit": "cpu_core" }, { "BriefDescription": "Retired store instructions that split across a cacheline boundary.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.SPLIT_STORES", - "L1_Hit_Indication": "1", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", "SampleAfterValue": "100003", "UMask": "0x42", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions that miss the STLB.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of retired load instructions that (start a) miss in the 2nd-level TLB (STLB).", "SampleAfterValue": "100003", "UMask": "0x11", "Unit": "cpu_core" }, { "BriefDescription": "Retired store instructions that miss the STLB.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd0", "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", - "L1_Hit_Indication": "1", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of retired store instructions that (start a) miss in the 2nd-level TLB (STLB).", "SampleAfterValue": "100003", "UMask": "0x12", "Unit": "cpu_core" }, { "BriefDescription": "Completed demand load uops that miss the L1 d-cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x43", "EventName": "MEM_LOAD_COMPLETED.L1_MISS_ANY", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of completed demand load requests that missed the L1 data cache including shadow misses (FB hits, merge to an ongoing L1D miss)", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xfd", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions whose data sources were HitM responses from shared L3", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd2", "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_FWD", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions whose data sources were HitM responses from shared L3.", "SampleAfterValue": "20011", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd2", "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache.", "SampleAfterValue": "20011", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Retired load instructions whose data sources were HitM responses from shared L3", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Data_LA": "1", "EventCode": "0xd2", "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", "PEBS": "1", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions whose data sources were HitM responses from shared L3.", + "SampleAfterValue": "20011", + "UMask": "0x4", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "PEBS": "1", + "PublicDescription": "Counts the retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "SampleAfterValue": "20011", + "UMask": "0x1", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions whose data sources were hits in L3 without snoops required", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions whose data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "UMask": "0x8", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NO_FWD", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache.", "SampleAfterValue": "20011", + "UMask": "0x2", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", + "Data_LA": "1", + "EventCode": "0xd3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", + "SampleAfterValue": "100007", + "UMask": "0x1", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "Data_LA": "1", + "EventCode": "0xd4", + "EventName": "MEM_LOAD_MISC_RETIRED.UC", + "PEBS": "1", + "PublicDescription": "Retired instructions with at least one load to uncacheable memory-type, or at least one cache-line split locked access (Bus Lock).", + "SampleAfterValue": "100007", + "UMask": "0x4", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Number of completed demand load requests that missed the L1, but hit the FB(fill buffer), because a preceding miss to the same cacheline initiated the line to be brought into L1, but data is not yet ready in L1.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", + "SampleAfterValue": "100007", + "UMask": "0x40", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "200003", + "UMask": "0x8", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "200003", + "UMask": "0x2", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "100021", + "UMask": "0x10", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", + "SampleAfterValue": "100021", "UMask": "0x4", "Unit": "cpu_core" }, { - "BriefDescription": "Retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xd2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "20011", + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", + "SampleAfterValue": "50021", + "UMask": "0x20", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in DRAM.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.DRAM_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x80", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L2 cache.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L3 cache.", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked for any of the following reasons: load buffer, store buffer or RSV full.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.ALL", + "SampleAfterValue": "20003", + "UMask": "0x7", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to a load buffer full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.LD_BUF", + "SampleAfterValue": "20003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to an RSV full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.RSV", + "SampleAfterValue": "20003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of cycles that uops are blocked due to a store buffer full condition.", + "EventCode": "0x04", + "EventName": "MEM_SCHEDULER_BLOCK.ST_BUF", + "SampleAfterValue": "20003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "MEM_STORE_RETIRED.L2_HIT", + "EventCode": "0x44", + "EventName": "MEM_STORE_RETIRED.L2_HIT", + "SampleAfterValue": "200003", "UMask": "0x1", "Unit": "cpu_core" }, { - "BriefDescription": "Retired load instructions whose data sources were hits in L3 without snoops required", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of load uops retired.", "Data_LA": "1", - "EventCode": "0xd2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100003", - "UMask": "0x8", - "Unit": "cpu_core" + "PublicDescription": "Counts the total number of load uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x81", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of store uops retired.", "Data_LA": "1", - "EventCode": "0xd2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NO_FWD", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_STORES", "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "20011", - "UMask": "0x2", - "Unit": "cpu_core" + "PublicDescription": "Counts the total number of store uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x82", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100007", - "UMask": "0x1", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "MSRValue": "0x80", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd4", - "EventName": "MEM_LOAD_MISC_RETIRED.UC", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100007", - "UMask": "0x4", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "MSRValue": "0x10", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Number of completed demand load requests that missed the L1, but hit the FB(fill buffer), because a preceding miss to the same cacheline initiated the line to be brought into L1, but data is not yet ready in L1.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.FB_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100007", - "UMask": "0x40", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "MSRValue": "0x100", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions with L1 cache hits as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L1_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "MSRValue": "0x20", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", "SampleAfterValue": "1000003", - "UMask": "0x1", - "Unit": "cpu_core" + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions missed L1 cache as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L1_MISS", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "200003", - "UMask": "0x8", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "MSRValue": "0x4", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions with L2 cache hits as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L2_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "200003", - "UMask": "0x2", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "MSRValue": "0x200", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions missed L2 cache as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L2_MISS", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100021", - "UMask": "0x10", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "MSRValue": "0x40", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions with L3 cache hits as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L3_HIT", - "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "100021", - "UMask": "0x4", - "Unit": "cpu_core" + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "MSRValue": "0x8", + "PEBS": "2", + "PublicDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled. If a PEBS record is generated, will populate the PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x5", + "Unit": "cpu_atom" }, { - "BriefDescription": "Retired load instructions missed L3 cache as data sources", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "BriefDescription": "Counts the number of retired split load uops.", "Data_LA": "1", - "EventCode": "0xd1", - "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.SPLIT_LOADS", "PEBS": "1", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "50021", - "UMask": "0x20", - "Unit": "cpu_core" + "SampleAfterValue": "200003", + "UMask": "0x41", + "Unit": "cpu_atom" }, { - "BriefDescription": "MEM_STORE_RETIRED.L2_HIT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "EventCode": "0x44", - "EventName": "MEM_STORE_RETIRED.L2_HIT", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "200003", - "UMask": "0x1", - "Unit": "cpu_core" + "BriefDescription": "Counts the number of stores uops retired. Counts with or without PEBS enabled.", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.STORE_LATENCY", + "PEBS": "2", + "PublicDescription": "Counts the number of stores uops retired. Counts with or without PEBS enabled. If PEBS is enabled and a PEBS record is generated, will populate PEBS Latency and PEBS Data Source fields accordingly.", + "SampleAfterValue": "1000003", + "UMask": "0x6", + "Unit": "cpu_atom" }, { "BriefDescription": "Retired memory uops for any access", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe5", "EventName": "MEM_UOP_RETIRED.ANY", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of retired micro-operations (uops) for load or store memory accesses", "SampleAfterValue": "1000003", "UMask": "0x3", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Counts demand data reads that resulted in a snoop hit in another cores caches, data forwarding is required as the data is modified.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HITM", "MSRIndex": "0x1a6,0x1a7", @@ -1181,9 +874,28 @@ "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, but no data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x4003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand data reads that were supplied by the L3 cache where a snoop was sent, the snoop hit, and non-modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x8003C0001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", @@ -1192,9 +904,28 @@ "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_HIT", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0002", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were supplied by the L3 cache where a snoop was sent, the snoop hit, and modified data was forwarded.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0002", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Counts demand read for ownership (RFO) requests and software prefetches for exclusive ownership (PREFETCHW) that resulted in a snoop hit in another cores caches, data forwarding is required as the data is modified.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM", "MSRIndex": "0x1a6,0x1a7", @@ -1205,139 +936,111 @@ }, { "BriefDescription": "OFFCORE_REQUESTS.ALL_REQUESTS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x21", "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x80", "Unit": "cpu_core" }, { "BriefDescription": "Demand and prefetch data reads", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x21", "EventName": "OFFCORE_REQUESTS.DATA_RD", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Demand Data Read requests sent to uncore", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x21", "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event OFFCORE_REQUESTS_OUTSTANDING.DATA_RD", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", + "Deprecated": "1", "Errata": "ADL038", "EventCode": "0x20", "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "Errata": "ADL038", "EventCode": "0x20", "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "For every cycle where the core is waiting on at least 1 outstanding Demand RFO request, increments by 1.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x20", "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", - "PEBScounters": "0,1,2,3", + "PublicDescription": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "OFFCORE_REQUESTS_OUTSTANDING.DATA_RD", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "Errata": "ADL038", "EventCode": "0x20", "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DATA_RD", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Number of PREFETCHNTA instructions executed.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x40", "EventName": "SW_PREFETCH_ACCESS.NTA", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHNTA instructions executed.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Number of PREFETCHW instructions executed.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x40", "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHW instructions executed.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Number of PREFETCHT0 instructions executed.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x40", "EventName": "SW_PREFETCH_ACCESS.T0", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHT0 instructions executed.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x40", "EventName": "SW_PREFETCH_ACCESS.T1_T2", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHT1 or PREFETCHT2 instructions executed.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to instruction cache misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ICACHE", + "SampleAfterValue": "1000003", + "UMask": "0x20", + "Unit": "cpu_atom" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/floating-point.json b/tools/perf/pmu-events/arch/x86/alderlake/floating-point.json index 48a4605fc057d..3eb7cab9b431a 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/floating-point.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/floating-point.json @@ -1,165 +1,124 @@ [ - { - "BriefDescription": "Counts the number of floating point operations retired that required microcode assist.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.FP_ASSIST", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of floating point divide uops retired (x87 and SSE, including x87 sqrt).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "UOPS_RETIRED.FPDIV", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "UMask": "0x8", - "Unit": "cpu_atom" - }, { "BriefDescription": "ARITH.FPDIV_ACTIVE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xb0", "EventName": "ARITH.FPDIV_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts all microcode FP assists.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc1", "EventName": "ASSISTS.FP", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all microcode Floating Point assists.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "ASSISTS.SSE_AVX_MIX", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc1", "EventName": "ASSISTS.SSE_AVX_MIX", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "FP_ARITH_DISPATCHED.PORT_0", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb3", "EventName": "FP_ARITH_DISPATCHED.PORT_0", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "FP_ARITH_DISPATCHED.PORT_1", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb3", "EventName": "FP_ARITH_DISPATCHED.PORT_1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "FP_ARITH_DISPATCHED.PORT_5", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb3", "EventName": "FP_ARITH_DISPATCHED.PORT_5", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT RCP FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc7", "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT RCP FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element. The DAZ and FTZ flags in the MXCSR register need to be set when using these events.", "SampleAfterValue": "100003", "UMask": "0x2", "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of floating point operations retired that required microcode assist.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.FP_ASSIST", + "PublicDescription": "Counts the number of floating point operations retired that required microcode assist, which is not a reflection of the number of FP operations, instructions or uops.", + "SampleAfterValue": "20003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of floating point divide uops retired (x87 and SSE, including x87 sqrt).", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.FPDIV", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x8", + "Unit": "cpu_atom" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/frontend.json b/tools/perf/pmu-events/arch/x86/alderlake/frontend.json index da1a7ba0e5681..250cd128b6749 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/frontend.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/frontend.json @@ -1,536 +1,416 @@ [ { "BriefDescription": "Counts the total number of BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0xe6", "EventName": "BACLEARS.ANY", - "PEBScounters": "0,1,2,3,4,5", + "PublicDescription": "Counts the total number of BACLEARS, which occur when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_atom" }, - { - "BriefDescription": "Counts the number of requests to the instruction cache for one or more bytes of a cache line.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x80", - "EventName": "ICACHE.ACCESSES", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x3", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of instruction cache misses.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x80", - "EventName": "ICACHE.MISSES", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, { "BriefDescription": "Stalls caused by changing prefix length of the instruction.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x87", "EventName": "DECODE.LCP", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", "SampleAfterValue": "500009", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles the Microcode Sequencer is busy.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x87", "EventName": "DECODE.MS_BUSY", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "500009", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "DSB-to-MITE switch true penalty cycles.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x61", "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Decode Stream Buffer (DSB) is a Uop-cache that holds translations of previously fetched instructions that were decoded by the legacy x86 decode pipeline (MITE). This event counts fetch penalty cycles when a transition occurs from DSB to MITE.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced DSB miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.ANY_DSB_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x1", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced a critical DSB miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.DSB_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x11", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of retired Instructions that experienced a critical DSB (Decode stream buffer i.e. the decoded instruction-cache) miss. Critical means stalls were exposed to the back-end as a result of the DSB miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced iTLB true miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.ITLB_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x14", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.L1I_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x12", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions who experienced Instruction L1 Cache true miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.L2_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x13", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions who experienced Instruction L2 Cache true miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", "MSRIndex": "0x3F7", "MSRValue": "0x600106", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", "MSRIndex": "0x3F7", "MSRValue": "0x608006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", "MSRIndex": "0x3F7", "MSRValue": "0x601006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions after front-end starvation of at least 2 cycles", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", "MSRIndex": "0x3F7", "MSRValue": "0x600206", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 2 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", "MSRIndex": "0x3F7", "MSRValue": "0x610006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", "MSRIndex": "0x3F7", "MSRValue": "0x100206", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", "MSRIndex": "0x3F7", "MSRValue": "0x602006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", "MSRIndex": "0x3F7", "MSRValue": "0x600406", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", "MSRIndex": "0x3F7", "MSRValue": "0x620006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_64", "MSRIndex": "0x3F7", "MSRValue": "0x604006", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", "MSRIndex": "0x3F7", "MSRValue": "0x600806", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "FRONTEND_RETIRED.MS_FLOWS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.MS_FLOWS", "MSRIndex": "0x3F7", "MSRValue": "0x8", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.STLB_MISS", "MSRIndex": "0x3F7", "MSRValue": "0x15", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "FRONTEND_RETIRED.UNKNOWN_BRANCH", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc6", "EventName": "FRONTEND_RETIRED.UNKNOWN_BRANCH", "MSRIndex": "0x3F7", "MSRValue": "0x17", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of requests to the instruction cache for one or more bytes of a cache line.", + "EventCode": "0x80", + "EventName": "ICACHE.ACCESSES", + "PublicDescription": "Counts the total number of requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line or byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x3", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of instruction cache misses.", + "EventCode": "0x80", + "EventName": "ICACHE.MISSES", + "PublicDescription": "Counts the number of missed requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line and byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, { "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x80", "EventName": "ICACHE_DATA.STALLS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles where a code line fetch is stalled due to an L1 instruction cache miss. The decode pipeline works at a 32 Byte granularity.", "SampleAfterValue": "500009", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x83", "EventName": "ICACHE_TAG.STALLS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles where a code fetch is stalled due to L1 instruction cache tag miss.", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x79", "EventName": "IDQ.DSB_CYCLES_ANY", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Cycles DSB is delivering optimal number of Uops", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "6", "EventCode": "0x79", "EventName": "IDQ.DSB_CYCLES_OK", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x79", "EventName": "IDQ.DSB_UOPS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Cycles MITE is delivering any Uop", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x79", "EventName": "IDQ.MITE_CYCLES_ANY", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles MITE is delivering optimal number of Uops", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "6", "EventCode": "0x79", "EventName": "IDQ.MITE_CYCLES_OK", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x79", "EventName": "IDQ.MITE_UOPS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when uops are being delivered to IDQ while MS is busy", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x79", "EventName": "IDQ.MS_CYCLES_ANY", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Number of switches from DSB or MITE to the MS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EdgeDetect": "1", "EventCode": "0x79", "EventName": "IDQ.MS_SWITCHES", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Uops delivered to IDQ while MS is busy", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x79", "EventName": "IDQ.MS_UOPS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS).", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Uops not delivered by IDQ when backend of the machine is not stalled", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x9c", "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of uops not delivered to by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when no uops are not delivered by the IDQ when backend of the machine is not stalled", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "6", "EventCode": "0x9c", "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of cycles when no uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when optimal number of uops was delivered to the back-end when the back-end is not stalled", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0x9c", "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of cycles when the optimal number of uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" } diff --git a/tools/perf/pmu-events/arch/x86/alderlake/memory.json b/tools/perf/pmu-events/arch/x86/alderlake/memory.json index f894e4a0212b2..7595eb4ab46f0 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/memory.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/memory.json @@ -1,339 +1,234 @@ [ + { + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "CounterMask": "6", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "SampleAfterValue": "1000003", + "UMask": "0x6", + "Unit": "cpu_core" + }, { "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to any number of reasons, including an L1 miss, WCB full, pagewalk, store address block or store data block, on a load that retires.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0x05", "EventName": "LD_HEAD.ANY_AT_RET", - "PEBScounters": "0,1,2,3,4,5", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xff", "Unit": "cpu_atom" }, { "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to a core bound stall including a store address match, a DTLB miss or a page walk that detains the load from retiring.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0x05", "EventName": "LD_HEAD.L1_BOUND_AT_RET", - "PEBScounters": "0,1,2,3,4,5", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xf4", "Unit": "cpu_atom" }, { "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to other block cases.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0x05", "EventName": "LD_HEAD.OTHER_AT_RET", - "PEBScounters": "0,1,2,3,4,5", + "PublicDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to other block cases such as pipeline conflicts, fences, etc.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xc0", "Unit": "cpu_atom" }, { "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a pagewalk.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0x05", "EventName": "LD_HEAD.PGWALK_AT_RET", - "PEBScounters": "0,1,2,3,4,5", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xa0", "Unit": "cpu_atom" }, { "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a store address match.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0x05", "EventName": "LD_HEAD.ST_ADDR_AT_RET", - "PEBScounters": "0,1,2,3,4,5", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x84", "Unit": "cpu_atom" }, { "BriefDescription": "Counts the number of machine clears due to memory ordering caused by a snoop from an external agent. Does not count internally generated machine clears such as those due to memory disambiguation.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", "EventCode": "0xc3", "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", - "PEBScounters": "0,1,2,3,4,5", "SampleAfterValue": "20003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_atom" }, - { - "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84400001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84400001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_RFO.L3_MISS", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84400002", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84400002", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", - "CounterMask": "6", - "EventCode": "0xa3", - "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", - "PEBScounters": "0,1,2,3", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x6", - "Unit": "cpu_core" - }, { "BriefDescription": "Number of machine clears due to memory ordering conflicts.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc3", "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of Machine Clears detected dye to memory ordering. Memory Ordering Machine Clears may apply when a memory read may not conform to the memory ordering rules of the x86 architecture", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "2", "EventCode": "0x47", "EventName": "MEMORY_ACTIVITY.CYCLES_L1D_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "3", "EventCode": "0x47", "EventName": "MEMORY_ACTIVITY.STALLS_L1D_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x3", "Unit": "cpu_core" }, { "BriefDescription": "MEMORY_ACTIVITY.STALLS_L2_MISS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "5", "EventCode": "0x47", "EventName": "MEMORY_ACTIVITY.STALLS_L2_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x5", "Unit": "cpu_core" }, { "BriefDescription": "MEMORY_ACTIVITY.STALLS_L3_MISS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "9", "EventCode": "0x47", "EventName": "MEMORY_ACTIVITY.STALLS_L3_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x9", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", "MSRIndex": "0x3F6", "MSRValue": "0x80", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "1009", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", "MSRIndex": "0x3F6", "MSRValue": "0x10", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "20011", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", "MSRIndex": "0x3F6", "MSRValue": "0x100", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "503", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", "MSRIndex": "0x3F6", "MSRValue": "0x20", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "100007", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", "MSRIndex": "0x3F6", "MSRValue": "0x4", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "100003", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", "MSRIndex": "0x3F6", "MSRValue": "0x200", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "101", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", "MSRIndex": "0x3F6", "MSRValue": "0x40", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "2003", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", - "CollectPEBSRecord": "2", - "Counter": "1,2,3,4,5,6,7", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", "MSRIndex": "0x3F6", "MSRValue": "0x8", "PEBS": "2", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "50021", - "TakenAlone": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Retired memory store access operations. A PDist event for PEBS Store Latency Facility.", - "CollectPEBSRecord": "2", "Data_LA": "1", "EventCode": "0xcd", "EventName": "MEM_TRANS_RETIRED.STORE_SAMPLE", "PEBS": "2", + "PublicDescription": "Counts Retired memory accesses with at least 1 store operation. This PEBS event is the precisely-distributed (PDist) trigger covering all stores uops for sampling by the PEBS Store Latency Facility. The facility is described in Intel SDM Volume 3 section 19.9.8", "SampleAfterValue": "1000003", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", "MSRIndex": "0x1a6,0x1a7", @@ -342,9 +237,28 @@ "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts demand data reads that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400002", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Counts demand read for ownership (RFO) requests and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_RFO.L3_MISS", "MSRIndex": "0x1a6,0x1a7", @@ -352,5 +266,33 @@ "SampleAfterValue": "100003", "UMask": "0x1", "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F84400002", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Demand Data Read requests who miss L3 cache", + "EventCode": "0x21", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "UMask": "0x10", + "Unit": "cpu_core" + }, + { + "BriefDescription": "For every cycle, increments by the number of demand data read requests pending that are known to have missed the L3 cache.", + "EventCode": "0x20", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "For every cycle, increments by the number of demand data read requests pending that are known to have missed the L3 cache. Note that this does not capture all elapsed cycles while requests are outstanding - only cycles from when the requests were known by the requesting core to have missed the L3 cache.", + "SampleAfterValue": "2000003", + "UMask": "0x10", + "Unit": "cpu_core" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/other.json b/tools/perf/pmu-events/arch/x86/alderlake/other.json index c49d8ce273100..329c611d7cf7a 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/other.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/other.json @@ -1,111 +1,66 @@ [ - { - "BriefDescription": "Counts modified writebacks from L1 cache and L2 cache that have any type of response.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.COREWB_M.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10008", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand data reads that have any type of response.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10001", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that have any type of response.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10002", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts streaming stores that have any type of response.", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xB7", - "EventName": "OCR.STREAMING_WR.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10800", - "SampleAfterValue": "100003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, { "BriefDescription": "ASSISTS.HARDWARE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc1", "EventName": "ASSISTS.HARDWARE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "ASSISTS.PAGE_FAULT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc1", "EventName": "ASSISTS.PAGE_FAULT", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "CORE_POWER.LICENSE_1", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x28", "EventName": "CORE_POWER.LICENSE_1", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "CORE_POWER.LICENSE_2", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x28", "EventName": "CORE_POWER.LICENSE_2", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "CORE_POWER.LICENSE_3", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x28", "EventName": "CORE_POWER.LICENSE_3", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "200003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts modified writebacks from L1 cache and L2 cache that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.COREWB_M.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10008", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts demand data reads that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10001", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Counts demand data reads that have any type of response.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", @@ -116,7 +71,6 @@ }, { "BriefDescription": "Counts demand data reads that were supplied by DRAM.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_DATA_RD.DRAM", "MSRIndex": "0x1a6,0x1a7", @@ -125,9 +79,18 @@ "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that have any type of response.", + "EventCode": "0xB7", + "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10002", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Counts demand read for ownership (RFO) requests and software prefetches for exclusive ownership (PREFETCHW) that have any type of response.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x2A,0x2B", "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", @@ -138,7 +101,16 @@ }, { "BriefDescription": "Counts streaming stores that have any type of response.", - "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xB7", + "EventName": "OCR.STREAMING_WR.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10800", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts streaming stores that have any type of response.", "EventCode": "0x2A,0x2B", "EventName": "OCR.STREAMING_WR.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", @@ -149,68 +121,52 @@ }, { "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa5", "EventName": "RS.EMPTY", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for this logical processor. This is usually caused when the front-end pipeline runs into starvation periods (e.g. branch mispredictions or i-cache misses)", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x7", "Unit": "cpu_core" }, { "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EdgeDetect": "1", "EventCode": "0xa5", "EventName": "RS.EMPTY_COUNT", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to closely sample on front-end latency issues (see the FRONTEND_RETIRED event of designated precise events)", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x7", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event RS.EMPTY_COUNT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EdgeDetect": "1", "EventCode": "0xa5", "EventName": "RS_EMPTY.COUNT", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x7", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event RS.EMPTY", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", + "Deprecated": "1", "EventCode": "0xa5", "EventName": "RS_EMPTY.CYCLES", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x7", "Unit": "cpu_core" }, { "BriefDescription": "XQ.FULL_CYCLES", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x2d", "EventName": "XQ.FULL_CYCLES", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" } diff --git a/tools/perf/pmu-events/arch/x86/alderlake/pipeline.json b/tools/perf/pmu-events/arch/x86/alderlake/pipeline.json index 1a137f7f8b7e8..f46fa7ba168ac 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/pipeline.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/pipeline.json @@ -1,2168 +1,1634 @@ [ - { - "BriefDescription": "Counts the total number of branch instructions retired for all branch types.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.ALL_BRANCHES", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_CALL", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xf9", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of retired JCC (Jump on Conditional Code) branch instructions retired, includes both taken and not taken branches.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.COND", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x7e", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of taken JCC (Jump on Conditional Code) branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.COND_TAKEN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of far branch instructions retired, includes far jump, far call and return, and interrupt call and return.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.FAR_BRANCH", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xbf", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of near indirect JMP and near indirect CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.INDIRECT", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xeb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of near indirect CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.INDIRECT_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT_CALL", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.IND_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.JCC", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x7e", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of near CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.NEAR_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xf9", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of near RET branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.NEAR_RETURN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xf7", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.NON_RETURN_IND", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xeb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of near relative CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.REL_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfd", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_RETURN", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.RETURN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xf7", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND_TAKEN", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.TAKEN_JCC", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of mispredicted branch instructions retired for all branch types.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of mispredicted JCC (Jump on Conditional Code) branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.COND", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x7e", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of mispredicted taken JCC (Jump on Conditional Code) branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.COND_TAKEN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of mispredicted near indirect JMP and near indirect CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.INDIRECT", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xeb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of mispredicted near indirect CALL branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.INDIRECT_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT_CALL", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.IND_CALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.JCC", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0x7e", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.NON_RETURN_IND", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xeb", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of mispredicted near RET branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.RETURN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xf7", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND_TAKEN", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc5", - "EventName": "BR_MISP_RETIRED.TAKEN_JCC", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "UMask": "0xfe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.CORE", - "PEBScounters": "33", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted core clock cycles.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x3c", - "EventName": "CPU_CLK_UNHALTED.CORE_P", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Speculative": "1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency. (Fixed event)", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 2", - "EventName": "CPU_CLK_UNHALTED.REF_TSC", - "PEBScounters": "34", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x3", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x3c", - "EventName": "CPU_CLK_UNHALTED.REF_TSC_P", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.THREAD", - "PEBScounters": "33", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of unhalted core clock cycles.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x3c", - "EventName": "CPU_CLK_UNHALTED.THREAD_P", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Speculative": "1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of instructions retired. (Fixed event)", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 0", - "EventName": "INST_RETIRED.ANY", - "PEBS": "1", - "PEBScounters": "32", - "SampleAfterValue": "2000003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc0", - "EventName": "INST_RETIRED.ANY_P", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event LD_BLOCKS.ADDRESS_ALIAS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.4K_ALIAS", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of retired loads that are blocked because it initially appears to be store forward blocked, but subsequently is shown not to be blocked based on 4K alias check.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.ADDRESS_ALIAS", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of retired loads that are blocked because its address exactly matches an older store whose data is not ready.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.DATA_UNKNOWN", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of machine clears due to memory ordering in which an internal load passes an older store within the same CPU.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.DISAMBIGUATION", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x8", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of machines clears due to memory renaming.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.MRN_NUKE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x80", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of machine clears due to a page fault. Counts both I-Side and D-Side (Loads/Stores) page faults. A page fault occurs when either the page is not present, or an access violation occurs.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.PAGE_FAULT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x20", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine with the use of microcode due to SMC, MEMORY_ORDERING, FP_ASSISTS, PAGE_FAULT, DISAMBIGUATION, and FPC_VIRTUAL_TRAP.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.SLOW", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x6f", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of machine clears due to program modifying data (self modifying code) within 1K of a recently fetched code page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.SMC", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "20003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x75", - "EventName": "SERIALIZATION.NON_C01_MS_SCB", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x73", - "EventName": "TOPDOWN_BAD_SPECULATION.ALL", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to fast nukes such as memory ordering and memory disambiguation machine clears.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x73", - "EventName": "TOPDOWN_BAD_SPECULATION.FASTNUKE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a machine clear (nuke) of any kind including memory ordering and memory disambiguation.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x73", - "EventName": "TOPDOWN_BAD_SPECULATION.MACHINE_CLEARS", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x3", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to branch mispredicts.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x73", - "EventName": "TOPDOWN_BAD_SPECULATION.MISPREDICT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to a machine clear (nuke).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x73", - "EventName": "TOPDOWN_BAD_SPECULATION.NUKE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to backend stalls.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.ALL", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to certain allocation restrictions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.ALLOC_RESTRICTIONS", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to memory reservation stalls in which a scheduler is not able to accept uops.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.MEM_SCHEDULER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to IEC or FPC RAT stalls, which can be due to FIQ or IEC reservation stalls in which the integer, floating point or SIMD scheduler is not able to accept uops.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.NON_MEM_SCHEDULER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x8", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the physical register file unable to accept an entry (marble stalls).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.REGISTER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x20", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the reorder buffer being full (ROB stalls).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.REORDER_BUFFER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x40", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to scoreboards from the instruction queue (IQ), jump execution unit (JEU), or microcode sequencer (MS).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x74", - "EventName": "TOPDOWN_BE_BOUND.SERIALIZATION", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x10", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to frontend stalls.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.ALL", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.BRANCH_DETECT", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x2", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.BRANCH_RESTEER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x40", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to the microcode sequencer (MS).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.CISC", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to decode stalls.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.DECODE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x8", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to frontend bandwidth restrictions due to decode, predecode, cisc, and other limitations.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.FRONTEND_BANDWIDTH", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x8d", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to a latency related stalls including BACLEARs, BTCLEARs, ITLB misses, and ICache misses.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.FRONTEND_LATENCY", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x72", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to ITLB misses.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.ITLB", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x10", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to other common frontend stalls not categorized.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.OTHER", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x80", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to wrong predecodes.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x71", - "EventName": "TOPDOWN_FE_BOUND.PREDECODE", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x4", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of consumed retirement slots.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "TOPDOWN_RETIRING.ALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the total number of uops retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "UOPS_RETIRED.ALL", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of integer divide uops retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "UOPS_RETIRED.IDIV", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "UMask": "0x10", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of uops that are from complex flows issued by the micro-sequencer (MS).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "UOPS_RETIRED.MS", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of x87 uops retired, includes those in MS flows.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0xc2", - "EventName": "UOPS_RETIRED.X87", - "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "UMask": "0x2", - "Unit": "cpu_atom" - }, { "BriefDescription": "This event is deprecated. Refer to new event ARITH.DIV_ACTIVE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EventCode": "0xb0", "EventName": "ARITH.DIVIDER_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x9", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xb0", "EventName": "ARITH.DIV_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x9", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event ARITH.FPDIV_ACTIVE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EventCode": "0xb0", "EventName": "ARITH.FP_DIVIDER_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "This event counts the cycles the integer divider is busy.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb0", "EventName": "ARITH.IDIV_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event ARITH.IDIV_ACTIVE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EventCode": "0xb0", "EventName": "ARITH.INT_DIVIDER_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Number of occurrences where a microcode assist is invoked by hardware.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc1", "EventName": "ASSISTS.ANY", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of occurrences where a microcode assist is invoked by hardware. Examples include AD (page Access Dirty), FP and AVX related assists.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1b", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the total number of branch instructions retired for all branch types.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions in which the instruction pointer (IP) of the processor is resteered due to a branch instruction and the branch instruction successfully retires. All branch type instructions are accounted for.", + "SampleAfterValue": "200003", + "Unit": "cpu_atom" + }, { "BriefDescription": "All branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.ALL_BRANCHES", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all branch instructions retired.", "SampleAfterValue": "400009", "Unit": "cpu_core" }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_CALL", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf9", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of retired JCC (Jump on Conditional Code) branch instructions retired, includes both taken and not taken branches.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e", + "Unit": "cpu_atom" + }, { "BriefDescription": "Conditional branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.COND", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts conditional branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x11", "Unit": "cpu_core" }, { "BriefDescription": "Not taken branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.COND_NTAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts not taken branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of taken JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_TAKEN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe", + "Unit": "cpu_atom" + }, { "BriefDescription": "Taken conditional branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.COND_TAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken conditional branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of far branch instructions retired, includes far jump, far call and return, and interrupt call and return.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xbf", + "Unit": "cpu_atom" + }, { "BriefDescription": "Far branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.FAR_BRANCH", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts far branch instructions retired.", "SampleAfterValue": "100007", "UMask": "0x40", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of near indirect JMP and near indirect CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.INDIRECT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb", + "Unit": "cpu_atom" + }, { "BriefDescription": "Indirect near branch instructions retired (excluding returns)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.INDIRECT", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts near indirect branch instructions retired excluding returns. TSX abort is an indirect branch.", "SampleAfterValue": "100003", "UMask": "0x80", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of near indirect CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.INDIRECT_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT_CALL", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.IND_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of near CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf9", + "Unit": "cpu_atom" + }, { "BriefDescription": "Direct and indirect near call instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.NEAR_CALL", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts both direct and indirect near call instructions retired.", "SampleAfterValue": "100007", "UMask": "0x2", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of near RET branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7", + "Unit": "cpu_atom" + }, { "BriefDescription": "Return instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.NEAR_RETURN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts return instructions retired.", "SampleAfterValue": "100007", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Taken branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc4", "EventName": "BR_INST_RETIRED.NEAR_TAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x20", "Unit": "cpu_core" }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NON_RETURN_IND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of near relative CALL branch instructions retired.", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.REL_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfd", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.NEAR_RETURN", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.COND_TAKEN", + "Deprecated": "1", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.TAKEN_JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the total number of mispredicted branch instructions retired for all branch types.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PublicDescription": "Counts the total number of mispredicted branch instructions retired. All branch type instructions are accounted for. Prediction of the branch target address enables the processor to begin executing instructions before the non-speculative execution path is known. The branch prediction unit (BPU) predicts the target address based on the instruction pointer (IP) of the branch and on the execution path through which execution reached this IP. A branch misprediction occurs when the prediction is wrong, and results in discarding all instructions executed in the speculative path and re-fetching from the correct path.", + "SampleAfterValue": "200003", + "Unit": "cpu_atom" + }, { "BriefDescription": "All mispredicted branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", "SampleAfterValue": "400009", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of mispredicted JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e", + "Unit": "cpu_atom" + }, { "BriefDescription": "Mispredicted conditional branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.COND", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts mispredicted conditional branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x11", "Unit": "cpu_core" }, { "BriefDescription": "Mispredicted non-taken conditional branch instructions retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.COND_NTAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of conditional branch instructions retired that were mispredicted and the branch direction was not taken.", "SampleAfterValue": "400009", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of mispredicted taken JCC (Jump on Conditional Code) branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND_TAKEN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe", + "Unit": "cpu_atom" + }, { "BriefDescription": "number of branch instructions retired that were mispredicted and taken.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.COND_TAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken conditional mispredicted branch instructions retired.", "SampleAfterValue": "400009", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of mispredicted near indirect JMP and near indirect CALL branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of mispredicted near indirect CALL branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb", + "Unit": "cpu_atom" + }, { "BriefDescription": "Mispredicted indirect CALL retired.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.INDIRECT_CALL", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired mispredicted indirect (near taken) CALL instructions, including both register and memory indirect.", "SampleAfterValue": "400009", "UMask": "0x2", "Unit": "cpu_core" }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT_CALL", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.IND_CALL", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfb", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0x7e", + "Unit": "cpu_atom" + }, { "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts number of near branch instructions retired that were mispredicted and taken.", "SampleAfterValue": "400009", "UMask": "0x20", "Unit": "cpu_core" }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.INDIRECT", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.NON_RETURN_IND", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xeb", + "Unit": "cpu_atom" + }, { "BriefDescription": "This event counts the number of mispredicted ret instructions retired. Non PEBS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc5", "EventName": "BR_MISP_RETIRED.RET", "PEBS": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts mispredicted return instructions retired.", "SampleAfterValue": "100007", "UMask": "0x8", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of mispredicted near RET branch instructions retired.", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.RETURN", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xf7", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BR_MISP_RETIRED.COND_TAKEN", + "Deprecated": "1", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.TAKEN_JCC", + "PEBS": "1", + "SampleAfterValue": "200003", + "UMask": "0xfe", + "Unit": "cpu_atom" + }, { "BriefDescription": "Core clocks when the thread is in the C0.1 light-weight slower wakeup time but more power saving optimized state.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.C01", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core clocks when the thread is in the C0.1 light-weight slower wakeup time but more power saving optimized state. This state can be entered via the TPAUSE or UMWAIT instructions.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Core clocks when the thread is in the C0.2 light-weight faster wakeup time but less power saving optimized state.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.C02", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core clocks when the thread is in the C0.2 light-weight faster wakeup time but less power saving optimized state. This state can be entered via the TPAUSE or UMWAIT instructions.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Core clocks when the thread is in the C0.1 or C0.2 or running a PAUSE in C0 ACPI state.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.C0_WAIT", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core clocks when the thread is in the C0.1 or C0.2 power saving optimized states (TPAUSE or UMWAIT instructions) or running the PAUSE instruction.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x70", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.CORE", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.CORE_P", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "Unit": "cpu_atom" + }, { "BriefDescription": "Cycle counts are evenly distributed between active threads in the Core.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.DISTRIBUTED", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event distributes cycle counts between active hyperthreads, i.e., those in C0. A hyperthread becomes inactive when it executes the HLT or MWAIT instructions. If all other hyperthreads are inactive (or disabled or do not exist), all counts are attributed to this hyperthread. To obtain the full count when the Core is active, sum the counts from each hyperthread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x3c", "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts Core crystal clock cycles when current thread is unhalted and the other thread is halted.", "SampleAfterValue": "25003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "CPU_CLK_UNHALTED.PAUSE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.PAUSE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "CPU_CLK_UNHALTED.PAUSE_INST", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EdgeDetect": "1", "EventCode": "0xec", "EventName": "CPU_CLK_UNHALTED.PAUSE_INST", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "Core crystal clock cycles. Cycle counts are evenly distributed between active threads in the Core.", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x3c", "EventName": "CPU_CLK_UNHALTED.REF_DISTRIBUTED", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event distributes Core crystal clock cycle counts between active hyperthreads, i.e., those in C0 sleep-state. A hyperthread becomes inactive when it executes the HLT or MWAIT instructions. If one thread is active in a core, all counts are attributed to this hyperthread. To obtain the full count when the Core is active, sum the counts from each hyperthread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses fixed counter 2.", + "SampleAfterValue": "2000003", + "UMask": "0x3", + "Unit": "cpu_atom" + }, { "BriefDescription": "Reference cycles when the core is not in halt state.", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 2", "EventName": "CPU_CLK_UNHALTED.REF_TSC", - "PEBScounters": "34", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. It is counted on a dedicated fixed counter, leaving the eight programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x3", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF_TSC_P", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Reference cycles when the core is not in halt state.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x3c", "EventName": "CPU_CLK_UNHALTED.REF_TSC_P", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, { "BriefDescription": "Core cycles when the thread is not in halt state", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 1", "EventName": "CPU_CLK_UNHALTED.THREAD", - "PEBScounters": "33", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the eight programmable counters available for other events.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles.", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "Unit": "cpu_atom" + }, { "BriefDescription": "Thread cycles when thread is not in halt state", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0x3c", "EventName": "CPU_CLK_UNHALTED.THREAD_P", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", "SampleAfterValue": "2000003", - "Speculative": "1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "8", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles while memory subsystem has an outstanding load.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "16", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "12", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0xc", "Unit": "cpu_core" }, { "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "5", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x5", "Unit": "cpu_core" }, { "BriefDescription": "Total execution stalls.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "4", "EventCode": "0xa3", "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.3_PORTS_UTIL", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "5", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.BOUND_ON_LOADS", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x21", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where the Store Buffer was full and no loads caused an execution stall.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "2", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles where the Store Buffer was full and no loads caused an execution stall.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "Cycles no uop executed while RS was not empty, the SB was not full and there was no outstanding load.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa6", "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of cycles total of 0 uops executed on all ports, Reservation Station (RS) was not empty, the Store Buffer (SB) was not full and there was no outstanding load.", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x80", "Unit": "cpu_core" }, { "BriefDescription": "Instruction decoders utilized in a cycle", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x75", "EventName": "INST_DECODED.DECODERS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of decoders utilized in a cycle when the MITE (legacy decode pipeline) fetches instructions.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the total number of instructions retired. (Fixed event)", + "EventName": "INST_RETIRED.ANY", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses fixed counter 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "Number of instructions retired. Fixed Counter - architectural event", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 0", "EventName": "INST_RETIRED.ANY", "PEBS": "1", - "PEBScounters": "32", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", "SampleAfterValue": "2000003", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the total number of instructions retired.", + "EventCode": "0xc0", + "EventName": "INST_RETIRED.ANY_P", + "PEBS": "1", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "Unit": "cpu_atom" + }, { "BriefDescription": "Number of instructions retired. General Counter - architectural event", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc0", "EventName": "INST_RETIRED.ANY_P", "PEBS": "1", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", "SampleAfterValue": "2000003", "Unit": "cpu_core" }, { "BriefDescription": "INST_RETIRED.MACRO_FUSED", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc0", "EventName": "INST_RETIRED.MACRO_FUSED", - "PEBScounters": "1,2,3,4,5,6,7", "SampleAfterValue": "2000003", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Retired NOP instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc0", "EventName": "INST_RETIRED.NOP", - "PEBScounters": "1,2,3,4,5,6,7", + "PublicDescription": "Counts all retired NOP or ENDBR32/64 instructions", "SampleAfterValue": "2000003", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Precise instruction retired with PEBS precise-distribution", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 0", "EventName": "INST_RETIRED.PREC_DIST", "PEBS": "1", - "PEBScounters": "32", + "PublicDescription": "A version of INST_RETIRED that allows for a precise distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR++) feature to fix bias in how retired instructions get sampled. Use on Fixed Counter 0.", "SampleAfterValue": "2000003", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "INST_RETIRED.REP_ITERATION", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc0", "EventName": "INST_RETIRED.REP_ITERATION", - "PEBScounters": "1,2,3,4,5,6,7", "SampleAfterValue": "2000003", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Counts cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xad", "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path.", "SampleAfterValue": "500009", - "Speculative": "1", "UMask": "0x80", "Unit": "cpu_core" }, { "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xad", "EventName": "INT_MISC.RECOVERY_CYCLES", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core cycles when the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", "SampleAfterValue": "500009", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "INT_MISC.UNKNOWN_BRANCH_CYCLES", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xad", "EventName": "INT_MISC.UNKNOWN_BRANCH_CYCLES", "MSRIndex": "0x3F7", "MSRValue": "0x7", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", - "Speculative": "1", - "TakenAlone": "1", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "TMA slots where uops got dropped", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xad", "EventName": "INT_MISC.UOP_DROPPING", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Estimated number of Top-down Microarchitecture Analysis slots that got dropped due to non front-end reasons", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.128BIT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.128BIT", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x13", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.256BIT", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.256BIT", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0xac", "Unit": "cpu_core" }, { "BriefDescription": "integer ADD, SUB, SAD 128-bit vector instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.ADD_128", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of retired integer ADD/SUB (regular or horizontal), SAD 128-bit vector instructions.", "SampleAfterValue": "1000003", "UMask": "0x3", "Unit": "cpu_core" }, { "BriefDescription": "integer ADD, SUB, SAD 256-bit vector instructions.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.ADD_256", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of retired integer ADD/SUB (regular or horizontal), SAD 256-bit vector instructions.", "SampleAfterValue": "1000003", "UMask": "0xc", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.MUL_256", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.MUL_256", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x80", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.SHUFFLES", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.SHUFFLES", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.VNNI_128", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.VNNI_128", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "INT_VEC_RETIRED.VNNI_256", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe7", "EventName": "INT_VEC_RETIRED.VNNI_256", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x20", "Unit": "cpu_core" }, + { + "BriefDescription": "This event is deprecated. Refer to new event LD_BLOCKS.ADDRESS_ALIAS", + "Deprecated": "1", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.4K_ALIAS", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of retired loads that are blocked because it initially appears to be store forward blocked, but subsequently is shown not to be blocked based on 4K alias check.", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.ADDRESS_ALIAS", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, { "BriefDescription": "False dependencies in MOB due to partial compare on address.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x03", "EventName": "LD_BLOCKS.ADDRESS_ALIAS", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times a load got blocked due to false dependencies in MOB due to partial compare on address.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of retired loads that are blocked because its address exactly matches an older store whose data is not ready.", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.DATA_UNKNOWN", + "PEBS": "1", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x03", "EventName": "LD_BLOCKS.NO_SR", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x88", "Unit": "cpu_core" }, { "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x03", "EventName": "LD_BLOCKS.STORE_FORWARD", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x82", "Unit": "cpu_core" }, { "BriefDescription": "Counts the number of demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x4c", "EventName": "LOAD_HIT_PREFETCH.SWPF", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xa8", "EventName": "LSD.CYCLES_ACTIVE", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles optimal number of Uops delivered by the LSD, but did not come from the decoder.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "6", "EventCode": "0xa8", "EventName": "LSD.CYCLES_OK", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the cycles when optimal number of uops is delivered by the LSD (Loop-stream detector).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { - "BriefDescription": "Number of Uops delivered by the LSD.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", - "EventCode": "0xa8", - "EventName": "LSD.UOPS", - "PEBScounters": "0,1,2,3,4,5,6,7", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_core" + "BriefDescription": "Number of Uops delivered by the LSD.", + "EventCode": "0xa8", + "EventName": "LSD.UOPS", + "PublicDescription": "Counts the number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Number of machine clears (nukes) of any type.", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.COUNT", + "PublicDescription": "Counts the number of machine clears (nukes) of any type.", + "SampleAfterValue": "100003", + "UMask": "0x1", + "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of machine clears due to memory ordering in which an internal load passes an older store within the same CPU.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.DISAMBIGUATION", + "SampleAfterValue": "20003", + "UMask": "0x8", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of machines clears due to memory renaming.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.MRN_NUKE", + "SampleAfterValue": "1000003", + "UMask": "0x80", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of machine clears due to a page fault. Counts both I-Side and D-Side (Loads/Stores) page faults. A page fault occurs when either the page is not present, or an access violation occurs.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.PAGE_FAULT", + "SampleAfterValue": "20003", + "UMask": "0x20", + "Unit": "cpu_atom" }, { - "BriefDescription": "Number of machine clears (nukes) of any type.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", + "BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine with the use of microcode due to SMC, MEMORY_ORDERING, FP_ASSISTS, PAGE_FAULT, DISAMBIGUATION, and FPC_VIRTUAL_TRAP.", "EventCode": "0xc3", - "EventName": "MACHINE_CLEARS.COUNT", - "PEBScounters": "0,1,2,3,4,5,6,7", - "SampleAfterValue": "100003", - "Speculative": "1", + "EventName": "MACHINE_CLEARS.SLOW", + "SampleAfterValue": "20003", + "UMask": "0x6f", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of machine clears due to program modifying data (self modifying code) within 1K of a recently fetched code page.", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.SMC", + "SampleAfterValue": "20003", "UMask": "0x1", - "Unit": "cpu_core" + "Unit": "cpu_atom" }, { "BriefDescription": "Self-modifying code (SMC) detected.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc3", "EventName": "MACHINE_CLEARS.SMC", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "MISC2_RETIRED.LFENCE", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xe0", "EventName": "MISC2_RETIRED.LFENCE", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "400009", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Increments whenever there is an update to the LBR array.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xcc", "EventName": "MISC_RETIRED.LBR_INSERTS", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", "SampleAfterValue": "100003", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa2", "EventName": "RESOURCE_STALLS.SB", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Counts cycles where the pipeline is stalled due to serializing operations.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa2", "EventName": "RESOURCE_STALLS.SCOREBOARD", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires.", + "EventCode": "0x75", + "EventName": "SERIALIZATION.NON_C01_MS_SCB", + "PublicDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires. The most commonly executed instruction with an MS scoreboard is PAUSE.", + "SampleAfterValue": "200003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, { "BriefDescription": "TMA slots where no uops were being issued due to lack of back-end resources.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa4", "EventName": "TOPDOWN.BACKEND_BOUND_SLOTS", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of slots in TMA method where no micro-operations were being issued from front-end to back-end of the machine due to lack of back-end resources.", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "TMA slots wasted due to incorrect speculations.", - "CollectPEBSRecord": "2", "EventCode": "0xa4", "EventName": "TOPDOWN.BAD_SPEC_SLOTS", + "PublicDescription": "Number of slots of TMA method that were wasted due to incorrect speculation. It covers all types of control-flow or data-related mis-speculations.", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "TMA slots wasted due to incorrect speculation by branch mispredictions", - "CollectPEBSRecord": "2", "EventCode": "0xa4", "EventName": "TOPDOWN.BR_MISPREDICT_SLOTS", + "PublicDescription": "Number of TMA slots that were wasted due to incorrect speculation by (any type of) branch mispredictions. This event estimates number of specualtive operations that were issued but not retired as well as the out-of-order engine recovery past a branch misprediction.", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "TOPDOWN.MEMORY_BOUND_SLOTS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa4", "EventName": "TOPDOWN.MEMORY_BOUND_SLOTS", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "TMA slots available for an unhalted logical processor. Fixed counter - architectural event", - "CollectPEBSRecord": "2", - "Counter": "Fixed counter 3", "EventName": "TOPDOWN.SLOTS", - "PEBScounters": "35", + "PublicDescription": "Number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method (TMA). The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core. Software can use this event as the denominator for the top-level metrics of the TMA method. This architectural event is counted on a designated fixed counter (Fixed Counter 3).", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "TMA slots available for an unhalted logical processor. General counter - architectural event", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xa4", "EventName": "TOPDOWN.SLOTS_P", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method. The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core.", "SampleAfterValue": "10000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.ALL", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear. Only issue slots wasted due to fast nukes such as memory ordering nukes are counted. Other nukes are not accounted for. Counts all issue slots blocked during this recovery window including relevant microcode flows and while uops are not yet available in the instruction queue (IQ) even if an FE_bound event occurs during this period. Also includes the issue slots that were consumed by the backend but were thrown away because they were younger than the mispredict or machine clear.", + "SampleAfterValue": "1000003", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to fast nukes such as memory ordering and memory disambiguation machine clears.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.FASTNUKE", + "SampleAfterValue": "1000003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a machine clear (nuke) of any kind including memory ordering and memory disambiguation.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MACHINE_CLEARS", + "SampleAfterValue": "1000003", + "UMask": "0x3", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to branch mispredicts.", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MISPREDICT", + "SampleAfterValue": "1000003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to a machine clear (nuke).", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.NUKE", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to backend stalls.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALL", + "SampleAfterValue": "1000003", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to certain allocation restrictions.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALLOC_RESTRICTIONS", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to memory reservation stalls in which a scheduler is not able to accept uops.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.MEM_SCHEDULER", + "SampleAfterValue": "1000003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to IEC or FPC RAT stalls, which can be due to FIQ or IEC reservation stalls in which the integer, floating point or SIMD scheduler is not able to accept uops.", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.NON_MEM_SCHEDULER", + "SampleAfterValue": "1000003", + "UMask": "0x8", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the physical register file unable to accept an entry (marble stalls).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REGISTER", + "SampleAfterValue": "1000003", + "UMask": "0x20", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the reorder buffer being full (ROB stalls).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REORDER_BUFFER", + "SampleAfterValue": "1000003", + "UMask": "0x40", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to scoreboards from the instruction queue (IQ), jump execution unit (JEU), or microcode sequencer (MS).", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.SERIALIZATION", + "SampleAfterValue": "1000003", + "UMask": "0x10", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to frontend stalls.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ALL", + "SampleAfterValue": "1000003", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_DETECT", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS, which occurs when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "SampleAfterValue": "1000003", + "UMask": "0x2", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_RESTEER", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS, which occurs when the Branch Target Buffer (BTB) predicts a taken branch.", + "SampleAfterValue": "1000003", + "UMask": "0x40", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to the microcode sequencer (MS).", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.CISC", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to decode stalls.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.DECODE", + "SampleAfterValue": "1000003", + "UMask": "0x8", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to frontend bandwidth restrictions due to decode, predecode, cisc, and other limitations.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.FRONTEND_BANDWIDTH", + "SampleAfterValue": "1000003", + "UMask": "0x8d", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to a latency related stalls including BACLEARs, BTCLEARs, ITLB misses, and ICache misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.FRONTEND_LATENCY", + "SampleAfterValue": "1000003", + "UMask": "0x72", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to ITLB misses.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ITLB", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to Instruction Table Lookaside Buffer (ITLB) misses.", + "SampleAfterValue": "1000003", + "UMask": "0x10", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to other common frontend stalls not categorized.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.OTHER", + "SampleAfterValue": "1000003", + "UMask": "0x80", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to wrong predecodes.", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.PREDECODE", + "SampleAfterValue": "1000003", + "UMask": "0x4", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the total number of consumed retirement slots.", + "EventCode": "0xc2", + "EventName": "TOPDOWN_RETIRING.ALL", + "PEBS": "1", + "SampleAfterValue": "1000003", + "Unit": "cpu_atom" + }, { "BriefDescription": "UOPS_DECODED.DEC0_UOPS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x76", "EventName": "UOPS_DECODED.DEC0_UOPS", - "PEBScounters": "0,1,2,3", "SampleAfterValue": "1000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on port 0", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_0", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution port 0.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on port 1", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution port 1.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on ports 2, 3 and 10", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_2_3_10", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution ports 2, 3 and 10", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on ports 4 and 9", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_4_9", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution ports 4 and 9", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on ports 5 and 11", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_5_11", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution ports 5 and 11", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on port 6", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_6", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution port 6.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x40", "Unit": "cpu_core" }, { "BriefDescription": "Uops executed on ports 7 and 8", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb2", "EventName": "UOPS_DISPATCHED.PORT_7_8", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of uops dispatch to execution ports 7 and 8.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x80", "Unit": "cpu_core" }, { "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 1 micro-op is executed from any thread on physical core.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "2", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 2 micro-ops are executed from any thread on physical core.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "3", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 3 micro-ops are executed from any thread on physical core.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "4", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 4 micro-ops are executed from any thread on physical core.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where at least 1 uop was executed per-thread", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CYCLES_GE_1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where at least 2 uops were executed per-thread", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "2", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CYCLES_GE_2", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where at least 3 uops were executed per-thread", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "3", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CYCLES_GE_3", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Cycles where at least 4 uops were executed per-thread", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "4", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.CYCLES_GE_4", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.STALLS", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event UOPS_EXECUTED.STALLS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.STALL_CYCLES", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.THREAD", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, { "BriefDescription": "Counts the number of x87 uops dispatched.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xb1", "EventName": "UOPS_EXECUTED.X87", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of x87 uops executed.", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Uops that RAT issues to RS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xae", "EventName": "UOPS_ISSUED.ANY", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", "SampleAfterValue": "2000003", - "Speculative": "1", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the total number of uops retired.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.ALL", + "PEBS": "1", + "SampleAfterValue": "2000003", + "Unit": "cpu_atom" + }, { "BriefDescription": "Cycles with retired uop(s).", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.CYCLES", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles where at least one uop has retired.", "SampleAfterValue": "1000003", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Retired uops except the last uop of each instruction.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.HEAVY", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of retired micro-operations (uops) except the last uop of each instruction. An instruction that is decoded into less than two uops does not contribute to the count.", "SampleAfterValue": "2000003", "UMask": "0x1", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of integer divide uops retired.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.IDIV", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x10", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of uops that are from complex flows issued by the micro-sequencer (MS).", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.MS", + "PEBS": "1", + "PublicDescription": "Counts the number of uops that are from complex flows issued by the Microcode Sequencer (MS). This includes uops from flows due to complex instructions, faults, assists, and inserted flows.", + "SampleAfterValue": "2000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, { "BriefDescription": "UOPS_RETIRED.MS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.MS", "MSRIndex": "0x3F7", "MSRValue": "0x8", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "2000003", - "TakenAlone": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Retirement slots used.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.SLOTS", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the retirement slots used each cycle.", "SampleAfterValue": "2000003", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Cycles without actually retired uops.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.STALLS", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event counts cycles without actually retired uops.", "SampleAfterValue": "1000003", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "This event is deprecated. Refer to new event UOPS_RETIRED.STALLS", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5,6,7", "CounterMask": "1", + "Deprecated": "1", "EventCode": "0xc2", "EventName": "UOPS_RETIRED.STALL_CYCLES", "Invert": "1", - "PEBScounters": "0,1,2,3,4,5,6,7", "SampleAfterValue": "1000003", "UMask": "0x2", "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of x87 uops retired, includes those in MS flows.", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.X87", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x2", + "Unit": "cpu_atom" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/uncore-memory.json b/tools/perf/pmu-events/arch/x86/alderlake/uncore-memory.json index d82d6f62a6fb4..2ccd9cf96957f 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/uncore-memory.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/uncore-memory.json @@ -1,221 +1,174 @@ [ { - "BriefDescription": "Number of clocks", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x01", - "EventName": "UNC_M_CLOCKTICKS", + "BriefDescription": "Counts every 64B read request entering the Memory Controller 0 to DRAM (sum of all channels).", + "EventName": "UNC_MC0_RDCAS_COUNT_FREERUN", "PerPkg": "1", + "PublicDescription": "Counts every 64B read request entering the Memory Controller 0 to DRAM (sum of all channels).", "Unit": "iMC" }, { - "BriefDescription": "Incoming VC0 read request", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x02", - "EventName": "UNC_M_VC0_REQUESTS_RD", + "BriefDescription": "Counts every 64B write request entering the Memory Controller 0 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM.", + "EventName": "UNC_MC0_WRCAS_COUNT_FREERUN", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Incoming VC0 write request", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x03", - "EventName": "UNC_M_VC0_REQUESTS_WR", + "BriefDescription": "Counts every 64B read request entering the Memory Controller 1 to DRAM (sum of all channels).", + "EventName": "UNC_MC1_RDCAS_COUNT_FREERUN", "PerPkg": "1", + "PublicDescription": "Counts every 64B read entering the Memory Controller 1 to DRAM (sum of all channels).", "Unit": "iMC" }, { - "BriefDescription": "Incoming VC1 read request", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x04", - "EventName": "UNC_M_VC1_REQUESTS_RD", + "BriefDescription": "Counts every 64B write request entering the Memory Controller 1 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM.", + "EventName": "UNC_MC1_WRCAS_COUNT_FREERUN", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Incoming VC1 write request", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x05", - "EventName": "UNC_M_VC1_REQUESTS_WR", + "BriefDescription": "ACT command for a read request sent to DRAM", + "EventCode": "0x24", + "EventName": "UNC_M_ACT_COUNT_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Incoming read prefetch request from IA", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x0A", - "EventName": "UNC_M_PREFETCH_RD", + "BriefDescription": "ACT command sent to DRAM", + "EventCode": "0x26", + "EventName": "UNC_M_ACT_COUNT_TOTAL", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Any Rank at Hot state", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x19", - "EventName": "UNC_M_DRAM_THERMAL_HOT", + "BriefDescription": "ACT command for a write request sent to DRAM", + "EventCode": "0x25", + "EventName": "UNC_M_ACT_COUNT_WR", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Any Rank at Warm state", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x1A", - "EventName": "UNC_M_DRAM_THERMAL_WARM", + "BriefDescription": "Read CAS command sent to DRAM", + "EventCode": "0x22", + "EventName": "UNC_M_CAS_COUNT_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "incoming read request page status is Page Hit", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x1C", - "EventName": "UNC_M_DRAM_PAGE_HIT_RD", + "BriefDescription": "Write CAS command sent to DRAM", + "EventCode": "0x23", + "EventName": "UNC_M_CAS_COUNT_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Number of clocks", + "EventCode": "0x01", + "EventName": "UNC_M_CLOCKTICKS", "PerPkg": "1", "Unit": "iMC" }, { "BriefDescription": "incoming read request page status is Page Empty", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", "EventCode": "0x1D", "EventName": "UNC_M_DRAM_PAGE_EMPTY_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "incoming read request page status is Page Miss", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x1E", - "EventName": "UNC_M_DRAM_PAGE_MISS_RD", + "BriefDescription": "incoming write request page status is Page Empty", + "EventCode": "0x20", + "EventName": "UNC_M_DRAM_PAGE_EMPTY_WR", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "incoming read request page status is Page Hit", + "EventCode": "0x1C", + "EventName": "UNC_M_DRAM_PAGE_HIT_RD", "PerPkg": "1", "Unit": "iMC" }, { "BriefDescription": "incoming write request page status is Page Hit", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", "EventCode": "0x1F", "EventName": "UNC_M_DRAM_PAGE_HIT_WR", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "incoming write request page status is Page Empty", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x20", - "EventName": "UNC_M_DRAM_PAGE_EMPTY_WR", + "BriefDescription": "incoming read request page status is Page Miss", + "EventCode": "0x1E", + "EventName": "UNC_M_DRAM_PAGE_MISS_RD", "PerPkg": "1", "Unit": "iMC" }, { "BriefDescription": "incoming write request page status is Page Miss", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", "EventCode": "0x21", "EventName": "UNC_M_DRAM_PAGE_MISS_WR", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Read CAS command sent to DRAM", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x22", - "EventName": "UNC_M_CAS_COUNT_RD", - "PerPkg": "1", - "Unit": "iMC" - }, - { - "BriefDescription": "Write CAS command sent to DRAM", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x23", - "EventName": "UNC_M_CAS_COUNT_WR", + "BriefDescription": "Any Rank at Hot state", + "EventCode": "0x19", + "EventName": "UNC_M_DRAM_THERMAL_HOT", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "ACT command for a read request sent to DRAM", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x24", - "EventName": "UNC_M_ACT_COUNT_RD", + "BriefDescription": "Any Rank at Warm state", + "EventCode": "0x1A", + "EventName": "UNC_M_DRAM_THERMAL_WARM", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "ACT command for a write request sent to DRAM", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x25", - "EventName": "UNC_M_ACT_COUNT_WR", + "BriefDescription": "Incoming read prefetch request from IA.", + "EventCode": "0x0A", + "EventName": "UNC_M_PREFETCH_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "ACT command sent to DRAM", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x26", - "EventName": "UNC_M_ACT_COUNT_TOTAL", + "BriefDescription": "PRE command sent to DRAM due to page table idle timer expiration", + "EventCode": "0x28", + "EventName": "UNC_M_PRE_COUNT_IDLE", "PerPkg": "1", "Unit": "iMC" }, { "BriefDescription": "PRE command sent to DRAM for a read/write request", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", "EventCode": "0x27", "EventName": "UNC_M_PRE_COUNT_PAGE_MISS", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "PRE command sent to DRAM due to page table idle timer expiration", - "Counter": "0,1,2,3,4", - "CounterType": "PGMABLE", - "EventCode": "0x28", - "EventName": "UNC_M_PRE_COUNT_IDLE", - "PerPkg": "1", - "Unit": "iMC" - }, - { - "BriefDescription": "Counts every 64B read request entering the Memory Controller 0 to DRAM (sum of all channels)", - "CounterType": "FREERUN", - "EventName": "UNC_MC0_RDCAS_COUNT_FREERUN", + "BriefDescription": "Incoming VC0 read request", + "EventCode": "0x02", + "EventName": "UNC_M_VC0_REQUESTS_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Counts every 64B read request entering the Memory Controller 1 to DRAM (sum of all channels)", - "Counter": "3", - "CounterType": "FREERUN", - "EventName": "UNC_MC1_RDCAS_COUNT_FREERUN", + "BriefDescription": "Incoming VC0 write request", + "EventCode": "0x03", + "EventName": "UNC_M_VC0_REQUESTS_WR", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Counts every 64B write request entering the Memory Controller 0 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM", - "Counter": "1", - "CounterType": "FREERUN", - "EventName": "UNC_MC0_WRCAS_COUNT_FREERUN", + "BriefDescription": "Incoming VC1 read request", + "EventCode": "0x04", + "EventName": "UNC_M_VC1_REQUESTS_RD", "PerPkg": "1", "Unit": "iMC" }, { - "BriefDescription": "Counts every 64B write request entering the Memory Controller 1 to DRAM (sum of all channels). Each write request counts as a new request incrementing this counter. However, same cache line write requests (both full and partial) are combined to a single 64 byte data transfer to DRAM", - "Counter": "4", - "CounterType": "FREERUN", - "EventName": "UNC_MC1_WRCAS_COUNT_FREERUN", + "BriefDescription": "Incoming VC1 write request", + "EventCode": "0x05", + "EventName": "UNC_M_VC1_REQUESTS_WR", "PerPkg": "1", "Unit": "iMC" } diff --git a/tools/perf/pmu-events/arch/x86/alderlake/uncore-other.json b/tools/perf/pmu-events/arch/x86/alderlake/uncore-other.json index b1ae349f5f21c..bc5fb6b760658 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/uncore-other.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/uncore-other.json @@ -1,40 +1,73 @@ [ { - "BriefDescription": "This 48-bit fixed counter counts the UCLK cycles", - "Counter": "Fixed", - "CounterType": "PGMABLE", - "EventCode": "0xff", - "EventName": "UNC_CLOCK.SOCKET", + "BriefDescription": "Number of requests allocated in Coherency Tracker.", + "EventCode": "0x84", + "EventName": "UNC_ARB_COH_TRK_REQUESTS.ALL", "PerPkg": "1", - "Unit": "CLOCK" + "UMask": "0x1", + "Unit": "ARB" }, { - "BriefDescription": "Counts the number of coherent and in-coherent requests initiated by IA cores, processor graphic units, or LLC", - "Counter": "0,1", - "CounterType": "PGMABLE", + "BriefDescription": "Each cycle counts number of any coherent request at memory controller that were issued by any core.", + "EventCode": "0x85", + "EventName": "UNC_ARB_DAT_OCCUPANCY.ALL", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "ARB" + }, + { + "BriefDescription": "Each cycle counts number of coherent reads pending on data return from memory controller that were issued by any core.", + "EventCode": "0x85", + "EventName": "UNC_ARB_DAT_OCCUPANCY.RD", + "PerPkg": "1", + "UMask": "0x2", + "Unit": "ARB" + }, + { + "BriefDescription": "Number of coherent read requests sent to memory controller that were issued by any core.", "EventCode": "0x81", - "EventName": "UNC_ARB_TRK_REQUESTS.ALL", + "EventName": "UNC_ARB_DAT_REQUESTS.RD", "PerPkg": "1", - "UMask": "0x01", + "UMask": "0x2", "Unit": "ARB" }, { - "BriefDescription": "Number of requests allocated in Coherency Tracker", - "Counter": "0,1", - "CounterType": "PGMABLE", - "EventCode": "0x84", - "EventName": "UNC_ARB_COH_TRK_REQUESTS.ALL", + "BriefDescription": "This event is deprecated. Refer to new event UNC_ARB_DAT_OCCUPANCY.ALL", + "EventCode": "0x85", + "EventName": "UNC_ARB_IFA_OCCUPANCY.ALL", "PerPkg": "1", - "UMask": "0x01", + "UMask": "0x1", "Unit": "ARB" }, { - "BriefDescription": "Each cycle counts number of all outgoing valid entries in ReqTrk. Such entry is defined as valid from its allocation in ReqTrk till deallocation. Accounts for Coherent and non-coherent traffic", - "CounterType": "PGMABLE", + "BriefDescription": "This event is deprecated. Refer to new event UNC_ARB_DAT_REQUESTS.RD", + "EventCode": "0x81", + "EventName": "UNC_ARB_REQ_TRK_REQUEST.DRD", + "PerPkg": "1", + "UMask": "0x2", + "Unit": "ARB" + }, + { + "BriefDescription": "Each cycle counts number of all outgoing valid entries in ReqTrk. Such entry is defined as valid from its allocation in ReqTrk till deallocation. Accounts for Coherent and non-coherent traffic.", "EventCode": "0x80", "EventName": "UNC_ARB_TRK_OCCUPANCY.ALL", "PerPkg": "1", - "UMask": "0x01", + "UMask": "0x1", "Unit": "ARB" + }, + { + "BriefDescription": "Counts the number of coherent and in-coherent requests initiated by IA cores, processor graphic units, or LLC.", + "EventCode": "0x81", + "EventName": "UNC_ARB_TRK_REQUESTS.ALL", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "ARB" + }, + { + "BriefDescription": "This 48-bit fixed counter counts the UCLK cycles.", + "EventCode": "0xff", + "EventName": "UNC_CLOCK.SOCKET", + "PerPkg": "1", + "Unit": "CLOCK" } ] diff --git a/tools/perf/pmu-events/arch/x86/alderlake/virtual-memory.json b/tools/perf/pmu-events/arch/x86/alderlake/virtual-memory.json index 12baf768ad8d3..3827d292da80a 100644 --- a/tools/perf/pmu-events/arch/x86/alderlake/virtual-memory.json +++ b/tools/perf/pmu-events/arch/x86/alderlake/virtual-memory.json @@ -1,317 +1,236 @@ [ - { - "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to any page size.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0xe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of page walks completed due to store DTLB misses to any page size.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0xe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of page walks initiated by a instruction fetch that missed the first and second level TLBs.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.MISS_CAUSED_WALK", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x1", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of page walks due to an instruction fetch that miss the PDE (Page Directory Entry) cache.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.PDE_CACHE_MISS", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "2000003", - "Speculative": "1", - "UMask": "0x80", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of page walks completed due to instruction fetch misses to any page size.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "200003", - "Speculative": "1", - "UMask": "0xe", - "Unit": "cpu_atom" - }, - { - "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a DTLB miss.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3,4,5", - "EventCode": "0x05", - "EventName": "LD_HEAD.DTLB_MISS_AT_RET", - "PEBScounters": "0,1,2,3,4,5", - "SampleAfterValue": "1000003", - "Speculative": "1", - "UMask": "0x90", - "Unit": "cpu_atom" - }, { "BriefDescription": "Loads that miss the DTLB and hit the STLB.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.STLB_HIT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a demand load.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a demand load.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to any page size.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0xe", + "Unit": "cpu_atom" + }, { "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data loads. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0xe", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data load to a 1G page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data load to a 2M/4M page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data load to a 4K page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Number of page walks outstanding for a demand load in the PMH each cycle.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x12", "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for a demand load in the PMH (Page Miss Handler) each cycle.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, { "BriefDescription": "Stores that miss the DTLB and hit the STLB.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.STLB_HIT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of page walks completed due to store DTLB misses to any page size.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0xe", + "Unit": "cpu_atom" + }, { "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data stores. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0xe", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data store to a 1G page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x8", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data store to a 2M/4M page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Page walks completed due to a demand data store to a 4K page.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Number of page walks outstanding for a store in the PMH each cycle.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x13", "EventName": "DTLB_STORE_MISSES.WALK_PENDING", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for a store in the PMH (Page Miss Handler) each cycle.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of page walks initiated by a instruction fetch that missed the first and second level TLBs.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.MISS_CAUSED_WALK", + "SampleAfterValue": "1000003", + "UMask": "0x1", + "Unit": "cpu_atom" + }, + { + "BriefDescription": "Counts the number of page walks due to an instruction fetch that miss the PDE (Page Directory Entry) cache.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.PDE_CACHE_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x80", + "Unit": "cpu_atom" + }, { "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x11", "EventName": "ITLB_MISSES.STLB_HIT", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts instruction fetch requests that miss the ITLB (Instruction TLB) and hit the STLB (Second-level TLB).", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x20", "Unit": "cpu_core" }, { "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "CounterMask": "1", "EventCode": "0x11", "EventName": "ITLB_MISSES.WALK_ACTIVE", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a code (instruction fetch) request.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" }, + { + "BriefDescription": "Counts the number of page walks completed due to instruction fetch misses to any page size.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts the number of page walks completed due to instruction fetches whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0xe", + "Unit": "cpu_atom" + }, { "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x11", "EventName": "ITLB_MISSES.WALK_COMPLETED", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0xe", "Unit": "cpu_core" }, { "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x11", "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (2M/4M page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x4", "Unit": "cpu_core" }, { "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x11", "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (4K page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x2", "Unit": "cpu_core" }, { "BriefDescription": "Number of page walks outstanding for an outstanding code request in the PMH each cycle.", - "CollectPEBSRecord": "2", - "Counter": "0,1,2,3", "EventCode": "0x11", "EventName": "ITLB_MISSES.WALK_PENDING", - "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for an outstanding code (instruction fetch) request in the PMH (Page Miss Handler) each cycle.", "SampleAfterValue": "100003", - "Speculative": "1", "UMask": "0x10", "Unit": "cpu_core" + }, + { + "BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a DTLB miss.", + "EventCode": "0x05", + "EventName": "LD_HEAD.DTLB_MISS_AT_RET", + "SampleAfterValue": "1000003", + "UMask": "0x90", + "Unit": "cpu_atom" } ] diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 78af105ca2367..df47462a125ff 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -1,5 +1,5 @@ Family-model,Version,Filename,EventType -GenuineIntel-6-(97|9A|B7|BA|BF),v1.15,alderlake,core +GenuineIntel-6-(97|9A|B7|BA|BF),v1.16,alderlake,core GenuineIntel-6-BE,v1.16,alderlaken,core GenuineIntel-6-(1C|26|27|35|36),v4,bonnell,core GenuineIntel-6-(3D|47),v26,broadwell,core -- GitLab From 6f520ce17920b3cdfbd2479b3ccf27f9706219d0 Mon Sep 17 00:00:00 2001 From: Ajay Kaher Date: Wed, 23 Nov 2022 15:48:16 +0530 Subject: [PATCH 1186/1480] perf symbol: correction while adjusting symbol perf doesn't provide proper symbol information for specially crafted .debug files. Sometimes .debug file may not have similar program header as runtime ELF file. For example if we generate .debug file using objcopy --only-keep-debug resulting file will not contain .text, .data and other runtime sections. That means corresponding program headers will have zero FileSiz and modified Offset. Example: program header of text section of libxxx.so: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x00000000003d3000 0x00000000003d3000 0x00000000003d3000 0x000000000055ae80 0x000000000055ae80 R E 0x1000 Same program header after executing: objcopy --only-keep-debug libxxx.so libxxx.so.debug LOAD 0x0000000000001000 0x00000000003d3000 0x00000000003d3000 0x0000000000000000 0x000000000055ae80 R E 0x1000 Offset and FileSiz have been changed. Following formula will not provide correct value, if program header taken from .debug file (syms_ss): sym.st_value -= phdr.p_vaddr - phdr.p_offset; Correct program header information is located inside runtime ELF file (runtime_ss). Fixes: 2d86612aacb7805f ("perf symbol: Correct address for bss symbols") Signed-off-by: Ajay Kaher Cc: Alexander Shishkin Cc: Alexey Makhalov Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Srivatsa S. Bhat Cc: Steven Rostedt (VMware) Cc: Vasavi Sirnapalli Link: http://lore.kernel.org/lkml/1669198696-50547-1-git-send-email-akaher@vmware.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 647b7dff8ef36..80345695b1360 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1303,7 +1303,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, (!used_opd && syms_ss->adjust_symbols)) { GElf_Phdr phdr; - if (elf_read_program_header(syms_ss->elf, + if (elf_read_program_header(runtime_ss->elf, (u64)sym.st_value, &phdr)) { pr_debug4("%s: failed to find program header for " "symbol: %s st_value: %#" PRIx64 "\n", -- GitLab From 1a9c20b45d193ead21dc63b07d1abb40b0a237c2 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 17 Nov 2022 18:46:05 -0800 Subject: [PATCH 1187/1480] perf list: Support newlines in wordwrap Rather than a newline starting from column 0, record a newline was seen and then add the newline and space before the next word. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221118024607.409083-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-list.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 84fa2d050eacb..f3750331e8f6b 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -74,17 +74,19 @@ static void wordwrap(const char *s, int start, int max, int corr) { int column = start; int n; + bool saw_newline = false; while (*s) { - int wlen = strcspn(s, " \t"); + int wlen = strcspn(s, " \t\n"); - if (column + wlen >= max && column > start) { + if ((column + wlen >= max && column > start) || saw_newline) { printf("\n%*s", start, ""); column = start + corr; } n = printf("%s%.*s", column > start ? " " : "", wlen, s); if (n <= 0) break; + saw_newline = s[wlen] == '\n'; s += wlen; column += n; s = skip_spaces(s); @@ -146,7 +148,7 @@ static void default_print_event(void *ps, const char *pmu_name, const char *topi wordwrap(desc, 8, pager_get_columns(), 0); printf("]\n"); } - + long_desc = long_desc ?: desc; if (long_desc && print_state->long_desc) { printf("%*s", 8, "["); wordwrap(long_desc, 8, pager_get_columns(), 0); @@ -154,7 +156,8 @@ static void default_print_event(void *ps, const char *pmu_name, const char *topi } if (print_state->detailed && encoding_desc) { - printf("%*s%s", 8, "", encoding_desc); + printf("%*s", 8, ""); + wordwrap(encoding_desc, 8, pager_get_columns(), 0); if (metric_name) printf(" MetricName: %s", metric_name); if (metric_expr) -- GitLab From 1284ded7d05952f2657f5abeeda5a3f74ca9cffc Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 17 Nov 2022 18:46:06 -0800 Subject: [PATCH 1188/1480] perf list: JSON escape encoding improvements Use strbuf to make the string under construction's length unlimited. Use the format %s to mean a literal string copy and %S to signify a need to escape the string. Add supported for escaping a newline character. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221118024607.409083-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-list.c | 109 +++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index f3750331e8f6b..137d73edb5410 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -17,6 +17,7 @@ #include "util/metricgroup.h" #include "util/string2.h" #include "util/strlist.h" +#include "util/strbuf.h" #include #include #include @@ -250,45 +251,56 @@ static void json_print_end(void *ps) printf("%s]\n", print_state->need_sep ? "\n" : ""); } -static void fix_escape_printf(const char *fmt, ...) +static void fix_escape_printf(struct strbuf *buf, const char *fmt, ...) { va_list args; - char buf[2048]; - size_t buf_pos = 0; va_start(args, fmt); + strbuf_setlen(buf, 0); for (size_t fmt_pos = 0; fmt_pos < strlen(fmt); fmt_pos++) { switch (fmt[fmt_pos]) { - case '%': { - const char *s = va_arg(args, const char*); - + case '%': fmt_pos++; - assert(fmt[fmt_pos] == 's'); - for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) { - switch (s[s_pos]) { - case '\\': - __fallthrough; - case '\"': - buf[buf_pos++] = '\\'; - assert(buf_pos < sizeof(buf)); - __fallthrough; - default: - buf[buf_pos++] = s[s_pos]; - assert(buf_pos < sizeof(buf)); - break; + switch (fmt[fmt_pos]) { + case 's': { + const char *s = va_arg(args, const char*); + + strbuf_addstr(buf, s); + break; + } + case 'S': { + const char *s = va_arg(args, const char*); + + for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) { + switch (s[s_pos]) { + case '\n': + strbuf_addstr(buf, "\\n"); + break; + case '\\': + __fallthrough; + case '\"': + strbuf_addch(buf, '\\'); + __fallthrough; + default: + strbuf_addch(buf, s[s_pos]); + break; + } } + break; + } + default: + pr_err("Unexpected format character '%c'\n", fmt[fmt_pos]); + strbuf_addch(buf, '%'); + strbuf_addch(buf, fmt[fmt_pos]); } break; - } default: - buf[buf_pos++] = fmt[fmt_pos]; - assert(buf_pos < sizeof(buf)); + strbuf_addch(buf, fmt[fmt_pos]); break; } } va_end(args); - buf[buf_pos] = '\0'; - fputs(buf, stdout); + fputs(buf->buf, stdout); } static void json_print_event(void *ps, const char *pmu_name, const char *topic, @@ -301,62 +313,71 @@ static void json_print_event(void *ps, const char *pmu_name, const char *topic, { struct json_print_state *print_state = ps; bool need_sep = false; + struct strbuf buf; + strbuf_init(&buf, 0); printf("%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; if (pmu_name) { - fix_escape_printf("\t\"Unit\": \"%s\"", pmu_name); + fix_escape_printf(&buf, "\t\"Unit\": \"%S\"", pmu_name); need_sep = true; } if (topic) { - fix_escape_printf("%s\t\"Topic\": \"%s\"", need_sep ? ",\n" : "", topic); + fix_escape_printf(&buf, "%s\t\"Topic\": \"%S\"", need_sep ? ",\n" : "", topic); need_sep = true; } if (event_name) { - fix_escape_printf("%s\t\"EventName\": \"%s\"", need_sep ? ",\n" : "", event_name); + fix_escape_printf(&buf, "%s\t\"EventName\": \"%S\"", need_sep ? ",\n" : "", + event_name); need_sep = true; } if (event_alias && strlen(event_alias)) { - fix_escape_printf("%s\t\"EventAlias\": \"%s\"", need_sep ? ",\n" : "", event_alias); + fix_escape_printf(&buf, "%s\t\"EventAlias\": \"%S\"", need_sep ? ",\n" : "", + event_alias); need_sep = true; } if (scale_unit && strlen(scale_unit)) { - fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", + fix_escape_printf(&buf, "%s\t\"ScaleUnit\": \"%S\"", need_sep ? ",\n" : "", scale_unit); need_sep = true; } if (event_type_desc) { - fix_escape_printf("%s\t\"EventType\": \"%s\"", need_sep ? ",\n" : "", + fix_escape_printf(&buf, "%s\t\"EventType\": \"%S\"", need_sep ? ",\n" : "", event_type_desc); need_sep = true; } if (deprecated) { - fix_escape_printf("%s\t\"Deprecated\": \"%s\"", need_sep ? ",\n" : "", + fix_escape_printf(&buf, "%s\t\"Deprecated\": \"%S\"", need_sep ? ",\n" : "", deprecated ? "1" : "0"); need_sep = true; } if (desc) { - fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + fix_escape_printf(&buf, "%s\t\"BriefDescription\": \"%S\"", need_sep ? ",\n" : "", + desc); need_sep = true; } if (long_desc) { - fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + fix_escape_printf(&buf, "%s\t\"PublicDescription\": \"%S\"", need_sep ? ",\n" : "", long_desc); need_sep = true; } if (encoding_desc) { - fix_escape_printf("%s\t\"Encoding\": \"%s\"", need_sep ? ",\n" : "", encoding_desc); + fix_escape_printf(&buf, "%s\t\"Encoding\": \"%S\"", need_sep ? ",\n" : "", + encoding_desc); need_sep = true; } if (metric_name) { - fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", metric_name); + fix_escape_printf(&buf, "%s\t\"MetricName\": \"%S\"", need_sep ? ",\n" : "", + metric_name); need_sep = true; } if (metric_expr) { - fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", metric_expr); + fix_escape_printf(&buf, "%s\t\"MetricExpr\": \"%S\"", need_sep ? ",\n" : "", + metric_expr); need_sep = true; } printf("%s}", need_sep ? "\n" : ""); + strbuf_release(&buf); } static void json_print_metric(void *ps __maybe_unused, const char *group, @@ -366,35 +387,39 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, { struct json_print_state *print_state = ps; bool need_sep = false; + struct strbuf buf; + strbuf_init(&buf, 0); printf("%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; if (group) { - fix_escape_printf("\t\"MetricGroup\": \"%s\"", group); + fix_escape_printf(&buf, "\t\"MetricGroup\": \"%S\"", group); need_sep = true; } if (name) { - fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", name); + fix_escape_printf(&buf, "%s\t\"MetricName\": \"%S\"", need_sep ? ",\n" : "", name); need_sep = true; } if (expr) { - fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", expr); + fix_escape_printf(&buf, "%s\t\"MetricExpr\": \"%S\"", need_sep ? ",\n" : "", expr); need_sep = true; } if (unit) { - fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", unit); + fix_escape_printf(&buf, "%s\t\"ScaleUnit\": \"%S\"", need_sep ? ",\n" : "", unit); need_sep = true; } if (desc) { - fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + fix_escape_printf(&buf, "%s\t\"BriefDescription\": \"%S\"", need_sep ? ",\n" : "", + desc); need_sep = true; } if (long_desc) { - fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + fix_escape_printf(&buf, "%s\t\"PublicDescription\": \"%S\"", need_sep ? ",\n" : "", long_desc); need_sep = true; } printf("%s}", need_sep ? "\n" : ""); + strbuf_release(&buf); } int cmd_list(int argc, const char **argv) -- GitLab From be3392b65f2b989badcadf5f6a353c7924d3ccf4 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 17 Nov 2022 18:46:07 -0800 Subject: [PATCH 1189/1480] perf list: List callback support for libpfm Missed previously, add libpfm support for 'perf list' callbacks and thereby JSON support. Committer notes: Add __maybe_unused to the args of the new print_libpfm_events() in the else HAVE_LIBPFM block. Fixes: e42b0ee61282a2f9 ("perf list: Add JSON output option") Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Caleb Biggers Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Stephane Eranian Cc: Weilin Wang Cc: Xin Gao Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221118024607.409083-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pfm.c | 154 ++++++++++++++++++------------------------ tools/perf/util/pfm.h | 7 +- 2 files changed, 71 insertions(+), 90 deletions(-) diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c index f0bcfcab1a932..ac3227ba769c6 100644 --- a/tools/perf/util/pfm.c +++ b/tools/perf/util/pfm.c @@ -12,6 +12,7 @@ #include "util/parse-events.h" #include "util/pmu.h" #include "util/pfm.h" +#include "util/strbuf.h" #include #include @@ -130,53 +131,36 @@ static const char *srcs[PFM_ATTR_CTRL_MAX] = { }; static void -print_attr_flags(pfm_event_attr_info_t *info) +print_attr_flags(struct strbuf *buf, const pfm_event_attr_info_t *info) { - int n = 0; + if (info->is_dfl) + strbuf_addf(buf, "[default] "); - if (info->is_dfl) { - printf("[default] "); - n++; - } - - if (info->is_precise) { - printf("[precise] "); - n++; - } - - if (!n) - printf("- "); + if (info->is_precise) + strbuf_addf(buf, "[precise] "); } static void -print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc) +print_libpfm_event(const struct print_callbacks *print_cb, void *print_state, + const pfm_pmu_info_t *pinfo, const pfm_event_info_t *info, + struct strbuf *buf) { - pfm_event_attr_info_t ainfo; - const char *src; int j, ret; + char topic[80], name[80]; - ainfo.size = sizeof(ainfo); + strbuf_setlen(buf, 0); + snprintf(topic, sizeof(topic), "pfm %s", pinfo->name); - printf(" %s\n", info->name); - printf(" [%s]\n", info->desc); - if (long_desc) { - if (info->equiv) - printf(" Equiv: %s\n", info->equiv); + snprintf(name, sizeof(name), "%s::%s", pinfo->name, info->name); + strbuf_addf(buf, "Code: 0x%"PRIx64"\n", info->code); - printf(" Code : 0x%"PRIx64"\n", info->code); - } pfm_for_each_event_attr(j, info) { - ret = pfm_get_event_attr_info(info->idx, j, - PFM_OS_PERF_EVENT_EXT, &ainfo); - if (ret != PFM_SUCCESS) - continue; - - if (ainfo.type == PFM_ATTR_UMASK) { - printf(" %s:%s\n", info->name, ainfo.name); - printf(" [%s]\n", ainfo.desc); - } + pfm_event_attr_info_t ainfo; + const char *src; - if (!long_desc) + ainfo.size = sizeof(ainfo); + ret = pfm_get_event_attr_info(info->idx, j, PFM_OS_PERF_EVENT_EXT, &ainfo); + if (ret != PFM_SUCCESS) continue; if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) @@ -184,64 +168,74 @@ print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc) src = srcs[ainfo.ctrl]; switch (ainfo.type) { - case PFM_ATTR_UMASK: - printf(" Umask : 0x%02"PRIx64" : %s: ", - ainfo.code, src); - print_attr_flags(&ainfo); - putchar('\n'); + case PFM_ATTR_UMASK: /* Ignore for now */ break; case PFM_ATTR_MOD_BOOL: - printf(" Modif : %s: [%s] : %s (boolean)\n", src, - ainfo.name, ainfo.desc); + strbuf_addf(buf, " Modif: %s: [%s] : %s (boolean)\n", src, + ainfo.name, ainfo.desc); break; case PFM_ATTR_MOD_INTEGER: - printf(" Modif : %s: [%s] : %s (integer)\n", src, - ainfo.name, ainfo.desc); + strbuf_addf(buf, " Modif: %s: [%s] : %s (integer)\n", src, + ainfo.name, ainfo.desc); break; case PFM_ATTR_NONE: case PFM_ATTR_RAW_UMASK: case PFM_ATTR_MAX: default: - printf(" Attr : %s: [%s] : %s\n", src, - ainfo.name, ainfo.desc); + strbuf_addf(buf, " Attr: %s: [%s] : %s\n", src, + ainfo.name, ainfo.desc); } } -} + print_cb->print_event(print_state, + pinfo->name, + topic, + name, info->equiv, + /*scale_unit=*/NULL, + /*deprecated=*/NULL, "PFM event", + info->desc, /*long_desc=*/NULL, + /*encoding_desc=*/buf->buf, + /*metric_name=*/NULL, /*metric_expr=*/NULL); -/* - * list all pmu::event:umask, pmu::event - * printed events may not be all valid combinations of umask for an event - */ -static void -print_libpfm_events_raw(pfm_pmu_info_t *pinfo, pfm_event_info_t *info) -{ - pfm_event_attr_info_t ainfo; - int j, ret; - bool has_umask = false; + pfm_for_each_event_attr(j, info) { + pfm_event_attr_info_t ainfo; + const char *src; - ainfo.size = sizeof(ainfo); + strbuf_setlen(buf, 0); - pfm_for_each_event_attr(j, info) { - ret = pfm_get_event_attr_info(info->idx, j, - PFM_OS_PERF_EVENT_EXT, &ainfo); + ainfo.size = sizeof(ainfo); + ret = pfm_get_event_attr_info(info->idx, j, PFM_OS_PERF_EVENT_EXT, &ainfo); if (ret != PFM_SUCCESS) continue; - if (ainfo.type != PFM_ATTR_UMASK) - continue; + if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) + ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN; - printf("%s::%s:%s\n", pinfo->name, info->name, ainfo.name); - has_umask = true; + src = srcs[ainfo.ctrl]; + if (ainfo.type == PFM_ATTR_UMASK) { + strbuf_addf(buf, "Umask: 0x%02"PRIx64" : %s: ", + ainfo.code, src); + print_attr_flags(buf, &ainfo); + snprintf(name, sizeof(name), "%s::%s:%s", + pinfo->name, info->name, ainfo.name); + print_cb->print_event(print_state, + pinfo->name, + topic, + name, /*alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/NULL, "PFM event", + ainfo.desc, /*long_desc=*/NULL, + /*encoding_desc=*/buf->buf, + /*metric_name=*/NULL, /*metric_expr=*/NULL); + } } - if (!has_umask) - printf("%s::%s\n", pinfo->name, info->name); } -void print_libpfm_events(bool name_only, bool long_desc) +void print_libpfm_events(const struct print_callbacks *print_cb, void *print_state) { pfm_event_info_t info; pfm_pmu_info_t pinfo; - int i, p, ret; + int p, ret; + struct strbuf storage; libpfm_initialize(); @@ -249,12 +243,9 @@ void print_libpfm_events(bool name_only, bool long_desc) info.size = sizeof(info); pinfo.size = sizeof(pinfo); - if (!name_only) - puts("\nList of pre-defined events (to be used in --pfm-events):\n"); + strbuf_init(&storage, 2048); pfm_for_all_pmus(p) { - bool printed_pmu = false; - ret = pfm_get_pmu_info(p, &pinfo); if (ret != PFM_SUCCESS) continue; @@ -267,25 +258,14 @@ void print_libpfm_events(bool name_only, bool long_desc) if (pinfo.pmu == PFM_PMU_PERF_EVENT) continue; - for (i = pinfo.first_event; i != -1; - i = pfm_get_event_next(i)) { - + for (int i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) { ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT, &info); if (ret != PFM_SUCCESS) continue; - if (!name_only && !printed_pmu) { - printf("%s:\n", pinfo.name); - printed_pmu = true; - } - - if (!name_only) - print_libpfm_events_detailed(&info, long_desc); - else - print_libpfm_events_raw(&pinfo, &info); + print_libpfm_event(print_cb, print_state, &pinfo, &info, &storage); } - if (!name_only && printed_pmu) - putchar('\n'); } + strbuf_release(&storage); } diff --git a/tools/perf/util/pfm.h b/tools/perf/util/pfm.h index 7d70dda870127..fb25c2749d267 100644 --- a/tools/perf/util/pfm.h +++ b/tools/perf/util/pfm.h @@ -7,13 +7,14 @@ #ifndef __PERF_PFM_H #define __PERF_PFM_H +#include "print-events.h" #include #ifdef HAVE_LIBPFM int parse_libpfm_events_option(const struct option *opt, const char *str, int unset); -void print_libpfm_events(bool name_only, bool long_desc); +void print_libpfm_events(const struct print_callbacks *print_cb, void *print_state); #else #include @@ -26,8 +27,8 @@ static inline int parse_libpfm_events_option( return 0; } -static inline void print_libpfm_events(bool name_only __maybe_unused, - bool long_desc __maybe_unused) +static inline void print_libpfm_events(const struct print_callbacks *print_cb __maybe_unused, + void *print_state __maybe_unused) { } -- GitLab From 23680f0b7d7f67a935adb38058110d2d81bbe6ea Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 23 Nov 2022 13:25:19 +0100 Subject: [PATCH 1190/1480] driver core: make struct class.dev_uevent() take a const * The dev_uevent() in struct class should not be modifying the device that is passed into it, so mark it as a const * and propagate the function signature changes out into all relevant subsystems that use this callback. Cc: Jens Axboe Cc: Luis Chamberlain Cc: Russ Weight Cc: Jean Delvare Cc: Johan Hovold Cc: Jason Gunthorpe Cc: Leon Romanovsky Cc: Karsten Keil Cc: Mauro Carvalho Chehab Cc: Keith Busch Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Dominik Brodowski Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Johannes Berg Cc: Wolfram Sang Cc: Raed Salem Cc: Chen Zhongjin Cc: Tetsuo Handa Cc: Avihai Horon Cc: "Matthew Wilcox (Oracle)" Cc: Alan Stern Cc: Colin Ian King Cc: Geert Uytterhoeven Cc: Jakob Koschel Cc: Antoine Tenart Cc: Frederic Weisbecker Cc: Wang Yufen Cc: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: linux-nvme@lists.infradead.org Cc: linux-pm@vger.kernel.org Cc: linux-rdma@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Acked-by: Sebastian Reichel Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221123122523.1332370-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- block/genhd.c | 4 ++-- drivers/base/firmware_loader/sysfs.c | 6 +++--- drivers/base/firmware_loader/sysfs.h | 2 +- drivers/firmware/dmi-id.c | 2 +- drivers/gnss/core.c | 6 +++--- drivers/infiniband/core/device.c | 2 +- drivers/isdn/mISDN/core.c | 4 ++-- drivers/media/dvb-core/dvbdev.c | 4 ++-- drivers/nvme/host/core.c | 4 ++-- drivers/pcmcia/cs.c | 4 ++-- drivers/power/supply/power_supply.h | 2 +- drivers/power/supply/power_supply_sysfs.c | 8 ++++---- drivers/usb/gadget/udc/core.c | 4 ++-- include/linux/device/class.h | 2 +- include/linux/mISDNif.h | 2 +- net/atm/atm_sysfs.c | 4 ++-- net/core/net-sysfs.c | 4 ++-- net/rfkill/core.c | 2 +- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 0f9769db2de83..3f11247134424 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1181,9 +1181,9 @@ static void disk_release(struct device *dev) iput(disk->part0->bd_inode); /* frees the disk */ } -static int block_uevent(struct device *dev, struct kobj_uevent_env *env) +static int block_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct gendisk *disk = dev_to_disk(dev); + const struct gendisk *disk = dev_to_disk(dev); return add_uevent_var(env, "DISKSEQ=%llu", disk->diskseq); } diff --git a/drivers/base/firmware_loader/sysfs.c b/drivers/base/firmware_loader/sysfs.c index 5b66b3d1fa16b..56911d75b90a1 100644 --- a/drivers/base/firmware_loader/sysfs.c +++ b/drivers/base/firmware_loader/sysfs.c @@ -64,7 +64,7 @@ static struct attribute *firmware_class_attrs[] = { }; ATTRIBUTE_GROUPS(firmware_class); -static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) +static int do_firmware_uevent(const struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) { if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name)) return -ENOMEM; @@ -76,9 +76,9 @@ static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env return 0; } -static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) +static int firmware_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); + const struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); int err = 0; mutex_lock(&fw_lock); diff --git a/drivers/base/firmware_loader/sysfs.h b/drivers/base/firmware_loader/sysfs.h index df1d5add698f1..fd0b4ad9bdbb6 100644 --- a/drivers/base/firmware_loader/sysfs.h +++ b/drivers/base/firmware_loader/sysfs.h @@ -81,7 +81,7 @@ struct fw_sysfs { void *fw_upload_priv; }; -static inline struct fw_sysfs *to_fw_sysfs(struct device *dev) +static inline struct fw_sysfs *to_fw_sysfs(const struct device *dev) { return container_of(dev, struct fw_sysfs, dev); } diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 940ddf916202a..5f3a3e913d28f 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -155,7 +155,7 @@ static const struct attribute_group* sys_dmi_attribute_groups[] = { NULL }; -static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) +static int dmi_dev_uevent(const struct device *dev, struct kobj_uevent_env *env) { ssize_t len; diff --git a/drivers/gnss/core.c b/drivers/gnss/core.c index 1e82b7967570a..77a4b280c552a 100644 --- a/drivers/gnss/core.c +++ b/drivers/gnss/core.c @@ -337,7 +337,7 @@ static const char * const gnss_type_names[GNSS_TYPE_COUNT] = { [GNSS_TYPE_MTK] = "MTK", }; -static const char *gnss_type_name(struct gnss_device *gdev) +static const char *gnss_type_name(const struct gnss_device *gdev) { const char *name = NULL; @@ -365,9 +365,9 @@ static struct attribute *gnss_attrs[] = { }; ATTRIBUTE_GROUPS(gnss); -static int gnss_uevent(struct device *dev, struct kobj_uevent_env *env) +static int gnss_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct gnss_device *gdev = to_gnss_device(dev); + const struct gnss_device *gdev = to_gnss_device(dev); int ret; ret = add_uevent_var(env, "GNSS_TYPE=%s", gnss_type_name(gdev)); diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index fa65c5d3d395c..4186dbf9377f0 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -511,7 +511,7 @@ static void ib_device_release(struct device *device) kfree_rcu(dev, rcu_head); } -static int ib_device_uevent(struct device *device, +static int ib_device_uevent(const struct device *device, struct kobj_uevent_env *env) { if (add_uevent_var(env, "NAME=%s", dev_name(device))) diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index 90ee56d07a6e9..9120be5903258 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c @@ -139,9 +139,9 @@ static struct attribute *mISDN_attrs[] = { }; ATTRIBUTE_GROUPS(mISDN); -static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env) +static int mISDN_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct mISDNdevice *mdev = dev_to_mISDN(dev); + const struct mISDNdevice *mdev = dev_to_mISDN(dev); if (!mdev) return 0; diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 675d877a67b25..6ef18bab9648b 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -1008,9 +1008,9 @@ void dvb_module_release(struct i2c_client *client) EXPORT_SYMBOL_GPL(dvb_module_release); #endif -static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) +static int dvb_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct dvb_device *dvbdev = dev_get_drvdata(dev); + const struct dvb_device *dvbdev = dev_get_drvdata(dev); add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index da55ce45ac701..b4778b970dd43 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4580,9 +4580,9 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) } EXPORT_SYMBOL_GPL(nvme_remove_namespaces); -static int nvme_class_uevent(struct device *dev, struct kobj_uevent_env *env) +static int nvme_class_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct nvme_ctrl *ctrl = + const struct nvme_ctrl *ctrl = container_of(dev, struct nvme_ctrl, ctrl_device); struct nvmf_ctrl_options *opts = ctrl->opts; int ret; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index f70197154a362..e3224e49c43fd 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -810,10 +810,10 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) EXPORT_SYMBOL(pcmcia_reset_card); -static int pcmcia_socket_uevent(struct device *dev, +static int pcmcia_socket_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); + const struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); if (add_uevent_var(env, "SOCKET_NO=%u", s->sock)) return -ENOMEM; diff --git a/drivers/power/supply/power_supply.h b/drivers/power/supply/power_supply.h index c310d4f36c105..645eee4d6b6ae 100644 --- a/drivers/power/supply/power_supply.h +++ b/drivers/power/supply/power_supply.h @@ -16,7 +16,7 @@ struct power_supply; #ifdef CONFIG_SYSFS extern void power_supply_init_attrs(struct device_type *dev_type); -extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env); +extern int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env); #else diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 5369abaceb5cc..6ca7d3985a406 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -427,7 +427,7 @@ void power_supply_init_attrs(struct device_type *dev_type) } } -static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env, +static int add_prop_uevent(const struct device *dev, struct kobj_uevent_env *env, enum power_supply_property prop, char *prop_buf) { int ret = 0; @@ -438,7 +438,7 @@ static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env, pwr_attr = &power_supply_attrs[prop]; dev_attr = &pwr_attr->dev_attr; - ret = power_supply_show_property(dev, dev_attr, prop_buf); + ret = power_supply_show_property((struct device *)dev, dev_attr, prop_buf); if (ret == -ENODEV || ret == -ENODATA) { /* * When a battery is absent, we expect -ENODEV. Don't abort; @@ -458,9 +458,9 @@ static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env, pwr_attr->prop_name, prop_buf); } -int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) +int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct power_supply *psy = dev_get_drvdata(dev); + const struct power_supply *psy = dev_get_drvdata(dev); int ret = 0, j; char *prop_buf; diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index c63c0c2cf649d..b5994a0604f68 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1723,9 +1723,9 @@ static const struct attribute_group *usb_udc_attr_groups[] = { NULL, }; -static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env) +static int usb_udc_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + const struct usb_udc *udc = container_of(dev, struct usb_udc, dev); int ret; ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name); diff --git a/include/linux/device/class.h b/include/linux/device/class.h index 20103e0b03c34..94b1107258e50 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -59,7 +59,7 @@ struct class { const struct attribute_group **dev_groups; struct kobject *dev_kobj; - int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); + int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env); char *(*devnode)(struct device *dev, umode_t *mode); void (*class_release)(struct class *class); diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h index 7dd1f01ec4f9f..7aab4a7697369 100644 --- a/include/linux/mISDNif.h +++ b/include/linux/mISDNif.h @@ -586,7 +586,7 @@ extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *, void *); extern void mISDN_unregister_clock(struct mISDNclock *); -static inline struct mISDNdevice *dev_to_mISDN(struct device *dev) +static inline struct mISDNdevice *dev_to_mISDN(const struct device *dev) { if (dev) return dev_get_drvdata(dev); diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c index 0fdbdfd194746..466353b3dde45 100644 --- a/net/atm/atm_sysfs.c +++ b/net/atm/atm_sysfs.c @@ -108,9 +108,9 @@ static struct device_attribute *atm_attrs[] = { }; -static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env) +static int atm_uevent(const struct device *cdev, struct kobj_uevent_env *env) { - struct atm_dev *adev; + const struct atm_dev *adev; if (!cdev) return -ENODEV; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 9cfc80b8ed25f..03a61d1dffbd4 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1873,9 +1873,9 @@ const struct kobj_ns_type_operations net_ns_type_operations = { }; EXPORT_SYMBOL_GPL(net_ns_type_operations); -static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) +static int netdev_uevent(const struct device *d, struct kobj_uevent_env *env) { - struct net_device *dev = to_net_dev(d); + const struct net_device *dev = to_net_dev(d); int retval; /* pass interface to uevent. */ diff --git a/net/rfkill/core.c b/net/rfkill/core.c index dac4fdc7488a3..b390ff245d5e8 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -832,7 +832,7 @@ static void rfkill_release(struct device *dev) kfree(rfkill); } -static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env) +static int rfkill_dev_uevent(const struct device *dev, struct kobj_uevent_env *env) { struct rfkill *rfkill = to_rfkill(dev); unsigned long flags; -- GitLab From ff62b8e6588fb07bedda7423622c140c4edd66a7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 23 Nov 2022 13:25:20 +0100 Subject: [PATCH 1191/1480] driver core: make struct class.devnode() take a const * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The devnode() in struct class should not be modifying the device that is passed into it, so mark it as a const * and propagate the function signature changes out into all relevant subsystems that use this callback. Cc: Fenghua Yu Cc: Reinette Chatre Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" Cc: FUJITA Tomonori Cc: Jens Axboe Cc: Justin Sanders Cc: Arnd Bergmann Cc: Sumit Semwal Cc: Benjamin Gaignard Cc: Liam Mark Cc: Laura Abbott Cc: Brian Starkey Cc: John Stultz Cc: "Christian König" Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: Jason Gunthorpe Cc: Leon Romanovsky Cc: Dennis Dalessandro Cc: Dmitry Torokhov Cc: Mauro Carvalho Chehab Cc: Sean Young Cc: Frank Haverkamp Cc: Jiri Slaby Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: Alex Williamson Cc: Cornelia Huck Cc: Kees Cook Cc: Anton Vorontsov Cc: Colin Cross Cc: Tony Luck Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Hans Verkuil Cc: Christophe JAILLET Cc: Xie Yongji Cc: Gautam Dawar Cc: Dan Carpenter Cc: Eli Cohen Cc: Parav Pandit Cc: Maxime Coquelin Cc: alsa-devel@alsa-project.org Cc: dri-devel@lists.freedesktop.org Cc: kvm@vger.kernel.org Cc: linaro-mm-sig@lists.linaro.org Cc: linux-block@vger.kernel.org Cc: linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: linux-rdma@vger.kernel.org Cc: linux-scsi@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Link: https://lore.kernel.org/r/20221123122523.1332370-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 4 ++-- arch/x86/kernel/cpuid.c | 2 +- arch/x86/kernel/msr.c | 2 +- block/bsg.c | 2 +- drivers/block/aoe/aoechr.c | 2 +- drivers/char/mem.c | 2 +- drivers/char/misc.c | 4 ++-- drivers/dma-buf/dma-heap.c | 2 +- drivers/gpu/drm/drm_sysfs.c | 2 +- drivers/infiniband/core/user_mad.c | 2 +- drivers/infiniband/core/uverbs_main.c | 2 +- drivers/infiniband/hw/hfi1/device.c | 4 ++-- drivers/input/input.c | 2 +- drivers/media/dvb-core/dvbdev.c | 4 ++-- drivers/media/pci/ddbridge/ddbridge-core.c | 4 ++-- drivers/media/rc/rc-main.c | 2 +- drivers/misc/genwqe/card_base.c | 2 +- drivers/tty/tty_io.c | 2 +- drivers/usb/core/file.c | 2 +- drivers/vdpa/vdpa_user/vduse_dev.c | 2 +- drivers/vfio/vfio_main.c | 2 +- fs/pstore/pmsg.c | 2 +- include/linux/device/class.h | 2 +- sound/sound_core.c | 2 +- 24 files changed, 29 insertions(+), 29 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c index d961ae3ed96e7..4e4231a58f383 100644 --- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -1560,9 +1560,9 @@ static const struct file_operations pseudo_lock_dev_fops = { .mmap = pseudo_lock_dev_mmap, }; -static char *pseudo_lock_devnode(struct device *dev, umode_t *mode) +static char *pseudo_lock_devnode(const struct device *dev, umode_t *mode) { - struct rdtgroup *rdtgrp; + const struct rdtgroup *rdtgrp; rdtgrp = dev_get_drvdata(dev); if (mode) diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 6f7b8cc1bc9fa..621ba9c0f17a9 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -139,7 +139,7 @@ static int cpuid_device_destroy(unsigned int cpu) return 0; } -static char *cpuid_devnode(struct device *dev, umode_t *mode) +static char *cpuid_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt)); } diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index ed8ac6bcbafb2..7087513117861 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -250,7 +250,7 @@ static int msr_device_destroy(unsigned int cpu) return 0; } -static char *msr_devnode(struct device *dev, umode_t *mode) +static char *msr_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt)); } diff --git a/block/bsg.c b/block/bsg.c index 2ab1351eb0823..08046bd9207d8 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -232,7 +232,7 @@ out_put_device: } EXPORT_SYMBOL_GPL(bsg_register_queue); -static char *bsg_devnode(struct device *dev, umode_t *mode) +static char *bsg_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev)); } diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 8eea2529da20a..7a368c90467d1 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -273,7 +273,7 @@ static const struct file_operations aoe_fops = { .llseek = noop_llseek, }; -static char *aoe_devnode(struct device *dev, umode_t *mode) +static char *aoe_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev)); } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5611d127363e4..83bf2a4dcb57e 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -746,7 +746,7 @@ static const struct file_operations memory_fops = { .llseek = noop_llseek, }; -static char *mem_devnode(struct device *dev, umode_t *mode) +static char *mem_devnode(const struct device *dev, umode_t *mode) { if (mode && devlist[MINOR(dev->devt)].mode) *mode = devlist[MINOR(dev->devt)].mode; diff --git a/drivers/char/misc.c b/drivers/char/misc.c index cba19bfdc44dd..88c6995b9a3d1 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -254,9 +254,9 @@ void misc_deregister(struct miscdevice *misc) } EXPORT_SYMBOL(misc_deregister); -static char *misc_devnode(struct device *dev, umode_t *mode) +static char *misc_devnode(const struct device *dev, umode_t *mode) { - struct miscdevice *c = dev_get_drvdata(dev); + const struct miscdevice *c = dev_get_drvdata(dev); if (mode && c->mode) *mode = c->mode; diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 8f5848aa144fe..4d7150791315a 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -299,7 +299,7 @@ err0: return err_ret; } -static char *dma_heap_devnode(struct device *dev, umode_t *mode) +static char *dma_heap_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev)); } diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 430e00b16eeca..14bf156b3f1ba 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -90,7 +90,7 @@ static void drm_sysfs_acpi_register(void) { } static void drm_sysfs_acpi_unregister(void) { } #endif -static char *drm_devnode(struct device *dev, umode_t *mode) +static char *drm_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); } diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 98cb594cd9a69..f83954180a338 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -1224,7 +1224,7 @@ static struct attribute *umad_class_dev_attrs[] = { }; ATTRIBUTE_GROUPS(umad_class_dev); -static char *umad_devnode(struct device *dev, umode_t *mode) +static char *umad_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev)); } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index d544340887277..bdb179a09d77c 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -1237,7 +1237,7 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data) put_device(&uverbs_dev->dev); } -static char *uverbs_devnode(struct device *dev, umode_t *mode) +static char *uverbs_devnode(const struct device *dev, umode_t *mode) { if (mode) *mode = 0666; diff --git a/drivers/infiniband/hw/hfi1/device.c b/drivers/infiniband/hw/hfi1/device.c index 8ceff7141bafe..1f44960321704 100644 --- a/drivers/infiniband/hw/hfi1/device.c +++ b/drivers/infiniband/hw/hfi1/device.c @@ -72,7 +72,7 @@ const char *class_name(void) return hfi1_class_name; } -static char *hfi1_devnode(struct device *dev, umode_t *mode) +static char *hfi1_devnode(const struct device *dev, umode_t *mode) { if (mode) *mode = 0600; @@ -85,7 +85,7 @@ static const char *class_name_user(void) return hfi1_class_name_user; } -static char *hfi1_user_devnode(struct device *dev, umode_t *mode) +static char *hfi1_user_devnode(const struct device *dev, umode_t *mode) { if (mode) *mode = 0666; diff --git a/drivers/input/input.c b/drivers/input/input.c index ebb2b7f0f8ff4..50597165dc54f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1913,7 +1913,7 @@ static const struct device_type input_dev_type = { #endif }; -static char *input_devnode(struct device *dev, umode_t *mode) +static char *input_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev)); } diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 6ef18bab9648b..e73f5240cc2cc 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -1018,9 +1018,9 @@ static int dvb_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -static char *dvb_devnode(struct device *dev, umode_t *mode) +static char *dvb_devnode(const struct device *dev, umode_t *mode) { - struct dvb_device *dvbdev = dev_get_drvdata(dev); + const struct dvb_device *dvbdev = dev_get_drvdata(dev); return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d", dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index fe833f39698af..ee8087f29b2c4 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2716,9 +2716,9 @@ static const struct file_operations ddb_fops = { .release = ddb_release, }; -static char *ddb_devnode(struct device *device, umode_t *mode) +static char *ddb_devnode(const struct device *device, umode_t *mode) { - struct ddb *dev = dev_get_drvdata(device); + const struct ddb *dev = dev_get_drvdata(device); return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); } diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index eba0cd30e314d..527d9324742bb 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1017,7 +1017,7 @@ static void ir_close(struct input_dev *idev) } /* class for /sys/class/rc */ -static char *rc_devnode(struct device *dev, umode_t *mode) +static char *rc_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); } diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 693981891870c..0f00687f72d43 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1349,7 +1349,7 @@ static struct pci_driver genwqe_driver = { * Default mode should be rw for everybody. Do not change default * device name. */ -static char *genwqe_devnode(struct device *dev, umode_t *mode) +static char *genwqe_devnode(const struct device *dev, umode_t *mode) { if (mode) *mode = 0666; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index de06c3c2ff70a..aad8171f6c214 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3494,7 +3494,7 @@ void tty_default_fops(struct file_operations *fops) *fops = tty_fops; } -static char *tty_devnode(struct device *dev, umode_t *mode) +static char *tty_devnode(const struct device *dev, umode_t *mode) { if (!mode) return NULL; diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 558890ada0e5b..da7d88e069e6c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -62,7 +62,7 @@ static struct usb_class { struct class *class; } *usb_class; -static char *usb_devnode(struct device *dev, umode_t *mode) +static char *usb_devnode(const struct device *dev, umode_t *mode) { struct usb_class_driver *drv; diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index 35dceee3ed560..0dd3c1f291da3 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1656,7 +1656,7 @@ static const struct file_operations vduse_ctrl_fops = { .llseek = noop_llseek, }; -static char *vduse_devnode(struct device *dev, umode_t *mode) +static char *vduse_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev)); } diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 6e8804fe00953..5bf4b34549189 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1812,7 +1812,7 @@ EXPORT_SYMBOL(vfio_set_irqs_validate_and_prepare); /* * Module/class support */ -static char *vfio_devnode(struct device *dev, umode_t *mode) +static char *vfio_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev)); } diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index d8542ec2f38c6..b31c9c72d90b4 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -46,7 +46,7 @@ static int pmsg_major; #undef pr_fmt #define pr_fmt(fmt) PMSG_NAME ": " fmt -static char *pmsg_devnode(struct device *dev, umode_t *mode) +static char *pmsg_devnode(const struct device *dev, umode_t *mode) { if (mode) *mode = 0220; diff --git a/include/linux/device/class.h b/include/linux/device/class.h index 94b1107258e50..42cc3fb44a846 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -60,7 +60,7 @@ struct class { struct kobject *dev_kobj; int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env); - char *(*devnode)(struct device *dev, umode_t *mode); + char *(*devnode)(const struct device *dev, umode_t *mode); void (*class_release)(struct class *class); void (*dev_release)(struct device *dev); diff --git a/sound/sound_core.c b/sound/sound_core.c index 3332fe321737e..3e7dd6fcb7cf9 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -30,7 +30,7 @@ MODULE_DESCRIPTION("Core sound module"); MODULE_AUTHOR("Alan Cox"); MODULE_LICENSE("GPL"); -static char *sound_devnode(struct device *dev, umode_t *mode) +static char *sound_devnode(const struct device *dev, umode_t *mode) { if (MAJOR(dev->devt) == SOUND_MAJOR) return NULL; -- GitLab From 3a042fda8813dcb1012347665a69572adbaef1f1 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 24 Nov 2022 09:49:27 +0100 Subject: [PATCH 1192/1480] iio: imu: st_lsm6dsx: add support to ISM330IS Add support to STM ISM330IS (accelerometer and gyroscope) Mems sensor. The ISM330IS sensor can use LSM6DSO16IS as fallback device since it implements all the ISM330IS features currently implemented in st_lsm6dsx. Datasheet: https://www.st.com/resource/en/datasheet/ism330is.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/4cd1614060e06f49cd92f5930d8fd40117c07920.1669279604.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 4 ++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 8 ++++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 +++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 +++++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 0096035728cd4..f6660847fb58d 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,8 +13,8 @@ config IIO_ST_LSM6DSX sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx, - lsm6dsv, lsm6dsv16x, lsm6dso16is, the accelerometer/gyroscope - of lsm9ds1 and lsm6dst. + lsm6dsv, lsm6dsv16x, lsm6dso16is, ism330is, lsm6dst and the + accelerometer/gyroscope of lsm9ds1. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index abf14a2ce0e95..5b6f195748fc6 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -36,6 +36,7 @@ #define ST_LSM6DSV_DEV_NAME "lsm6dsv" #define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" #define ST_LSM6DSO16IS_DEV_NAME "lsm6dso16is" +#define ST_ISM330IS_DEV_NAME "ism330is" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -59,6 +60,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSV_ID, ST_LSM6DSV16X_ID, ST_LSM6DSO16IS_ID, + ST_ISM330IS_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 57a79bf35bbaa..3f6060c64f32b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX/LSM6DSO16IS: + * LSM6DSTX/LSM6DSO16IS/ISM330IS: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -1393,7 +1393,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .hw_id = ST_LSM6DSO16IS_ID, .name = ST_LSM6DSO16IS_DEV_NAME, .wai = 0x22, - }, + }, { + .hw_id = ST_ISM330IS_ID, + .name = ST_ISM330IS_DEV_NAME, + .wai = 0x22, + } }, .channels = { [ST_LSM6DSX_ID_ACC] = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index c34ccc85e4c71..df5f609252600 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -121,6 +121,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dso16is", .data = (void *)ST_LSM6DSO16IS_ID, }, + { + .compatible = "st,ism330is", + .data = (void *)ST_ISM330IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -147,6 +151,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, + { ST_ISM330IS_DEV_NAME, ST_ISM330IS_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 24d5e51a8662e..974584bda875e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -121,6 +121,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dso16is", .data = (void *)ST_LSM6DSO16IS_ID, }, + { + .compatible = "st,ism330is", + .data = (void *)ST_ISM330IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -147,6 +151,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, + { ST_ISM330IS_DEV_NAME, ST_ISM330IS_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- GitLab From 91f46207056d6af2052495f911901a5ff337e364 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 24 Nov 2022 09:49:28 +0100 Subject: [PATCH 1193/1480] dt-bindings: iio: imu: st_lsm6dsx: add ism330is Add device bindings for ism330is IMU sensor. Use lsm6dso16is as fallback device for ism330is since it implements all the features currently supported by ism330is. Signed-off-by: Lorenzo Bianconi Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/a7a8a00037952928364269615ee8b6da4547795b.1669279604.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index 07d5aee7e4421..68b481c633188 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -43,6 +43,9 @@ properties: - items: - const: st,lsm6dsv16x - const: st,lsm6dsv + - items: + - const: st,ism330is + - const: st,lsm6dso16is reg: maxItems: 1 -- GitLab From f1e24342401a69da0519b289f0942fcd69e7db55 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 24 Nov 2022 17:25:59 +0200 Subject: [PATCH 1194/1480] iio: addac: ad74115: remove unused ad74115_dac_slew_rate_hz_tbl This table was supposed to be used for handling the DAC rate, but it ended up being unused. Remove it. Signed-off-by: Cosmin Tanislav Reported-by: kernel test robot Link: https://lore.kernel.org/r/20221124152559.7895-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74115.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c index 383b92e7b6826..e6bc5eb3788df 100644 --- a/drivers/iio/addac/ad74115.c +++ b/drivers/iio/addac/ad74115.c @@ -317,10 +317,6 @@ static const unsigned int ad74115_dac_rate_step_tbl[][3] = { { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_240KHZ }, }; -static const unsigned int ad74115_dac_slew_rate_hz_tbl[] = { - 4000, 64000, 150000, 240000 -}; - static const unsigned int ad74115_rtd_excitation_current_ua_tbl[] = { 250, 500, 750, 1000 }; -- GitLab From f84eec02b7248b6ae3bd8ef18a66f6f64eeab971 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 24 Nov 2022 17:30:49 +0200 Subject: [PATCH 1195/1480] iio: addac: ad74413r: fix blank line after declaration warning Checkpatch wants a blank line after all declarations. Add it now, even though the patch has already been submitted. Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221124153049.8851-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 61030053cbeaa..f32c8c2fb26d2 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -1315,6 +1315,7 @@ static int ad74413r_probe(struct spi_device *spi) st->chip_info = device_get_match_data(&spi->dev); if (!st->chip_info) { const struct spi_device_id *id = spi_get_device_id(spi); + if (id) st->chip_info = (struct ad74413r_chip_info *)id->driver_data; -- GitLab From f0052d7a1edb3d8921b4e154aa8c46c4845b3714 Mon Sep 17 00:00:00 2001 From: Duke Xin Date: Sat, 19 Nov 2022 17:44:47 +0800 Subject: [PATCH 1196/1480] USB: serial: option: add Quectel EM05-G modem The EM05-G modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "RMNET" : AT + DIAG + NMEA + Modem + QMI "MBIM" : MBIM + AT + DIAG + NMEA + Modem The detailed description of the USB configuration for each mode as follows: RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 21 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0311 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0311 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c3b7f1d98e781..dee79c7d82d5c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -255,6 +255,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EP06 0x0306 #define QUECTEL_PRODUCT_EM05G 0x030a #define QUECTEL_PRODUCT_EM060K 0x030b +#define QUECTEL_PRODUCT_EM05G_SG 0x0311 #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 #define QUECTEL_PRODUCT_RM520N 0x0801 @@ -1160,6 +1161,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), .driver_info = RSVD(6) | ZLP }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, -- GitLab From 70aa0a5551f6a752f3a071529fffde903f1a2637 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:13:56 +0000 Subject: [PATCH 1197/1480] dt-bindings: misc: qcom,fastrpc: increase allowed iommus entries The fastrpc components on the SM8550 SoC can require up to 3 IOMMU entries, this bumps the maxItems to 3 for this purpose. Signed-off-by: Abel Vesa Signed-off-by: Neil Armstrong Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml index d7576f8ac94b4..1ab9588cdd896 100644 --- a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml +++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml @@ -79,7 +79,7 @@ patternProperties: iommus: minItems: 1 - maxItems: 2 + maxItems: 3 qcom,nsessions: $ref: /schemas/types.yaml#/definitions/uint32 -- GitLab From 1959ab9edccd3de4bc8a876f97ce269bb9beeb31 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:13:57 +0000 Subject: [PATCH 1198/1480] misc: fastrpc: Rename audio protection domain to root The AUDIO_PD will be done via static pd, so the proper name here is actually ROOT_PD. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-3-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 7ff0b63c25e37..f2bda08adca77 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -83,7 +83,7 @@ #define FASTRPC_RMID_INIT_MEM_UNMAP 11 /* Protection Domain(PD) ids */ -#define AUDIO_PD (0) /* also GUEST_OS PD? */ +#define ROOT_PD (0) #define USER_PD (1) #define SENSORS_PD (2) @@ -1886,7 +1886,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, err = fastrpc_invoke(fl, argp); break; case FASTRPC_IOCTL_INIT_ATTACH: - err = fastrpc_init_attach(fl, AUDIO_PD); + err = fastrpc_init_attach(fl, ROOT_PD); break; case FASTRPC_IOCTL_INIT_ATTACH_SNS: err = fastrpc_init_attach(fl, SENSORS_PD); -- GitLab From 1ce91d45ba77a4f6bf9209d142d5c89c42cf877a Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:13:58 +0000 Subject: [PATCH 1199/1480] misc: fastrpc: Add reserved mem support The reserved mem support is needed for CMA heap support, which will be used by AUDIOPD. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index f2bda08adca77..3d5809622a6bd 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -2065,6 +2066,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) return -EINVAL; } + if (of_reserved_mem_device_init_by_idx(rdev, rdev->of_node, 0)) + dev_info(rdev, "no reserved DMA memory for FASTRPC\n"); + vmcount = of_property_read_variable_u32_array(rdev->of_node, "qcom,vmids", &vmids[0], 0, FASTRPC_MAX_VMIDS); if (vmcount < 0) -- GitLab From 6f18c7e845346f365e08613fdc47a60fc201aedb Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:13:59 +0000 Subject: [PATCH 1200/1480] misc: fastrpc: Add fastrpc_remote_heap_alloc Split fastrpc_buf_alloc in such a way it allows allocation of remote heap too and add fastrpc_remote_heap_alloc to do so. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 3d5809622a6bd..8b43fe5207fb6 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -369,7 +369,7 @@ static void fastrpc_buf_free(struct fastrpc_buf *buf) kfree(buf); } -static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, +static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, u64 size, struct fastrpc_buf **obuf) { struct fastrpc_buf *buf; @@ -397,14 +397,37 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, return -ENOMEM; } + *obuf = buf; + + return 0; +} + +static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, + u64 size, struct fastrpc_buf **obuf) +{ + int ret; + struct fastrpc_buf *buf; + + ret = __fastrpc_buf_alloc(fl, dev, size, obuf); + if (ret) + return ret; + + buf = *obuf; + if (fl->sctx && fl->sctx->sid) buf->phys += ((u64)fl->sctx->sid << 32); - *obuf = buf; - return 0; } +static int fastrpc_remote_heap_alloc(struct fastrpc_user *fl, struct device *dev, + u64 size, struct fastrpc_buf **obuf) +{ + struct device *rdev = &fl->cctx->rpdev->dev; + + return __fastrpc_buf_alloc(fl, rdev, size, obuf); +} + static void fastrpc_channel_ctx_free(struct kref *ref) { struct fastrpc_channel_ctx *cctx; -- GitLab From 334f1a1cbe032d85fd58e771629e3a3b373b96d5 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:00 +0000 Subject: [PATCH 1201/1480] misc: fastrpc: Use fastrpc_map_put in fastrpc_map_create on fail Move the kref_init right after the allocation so that we can use fastrpc_map_put on any following error case. Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-6-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 8b43fe5207fb6..332626df5d395 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -735,6 +735,8 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, return -ENOMEM; INIT_LIST_HEAD(&map->node); + kref_init(&map->refcount); + map->fl = fl; map->fd = fd; map->buf = dma_buf_get(fd); @@ -761,7 +763,6 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, map->size = len; map->va = sg_virt(map->table->sgl); map->len = len; - kref_init(&map->refcount); if (attr & FASTRPC_ATTR_SECUREMAP) { /* @@ -791,7 +792,7 @@ map_err: attach_err: dma_buf_put(map->buf); get_err: - kfree(map); + fastrpc_map_put(map); return err; } -- GitLab From 72fa6f7820c4cf96c5f7aabc4e54bdf52d1e2ac2 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:01 +0000 Subject: [PATCH 1202/1480] misc: fastrpc: Rework fastrpc_req_munmap Move the lookup of the munmap request to the fastrpc_req_munmap and pass on only the buf to the lower level fastrpc_req_munmap_impl. That way we can use the lower level fastrpc_req_munmap_impl on error path in fastrpc_req_mmap to free the buf without searching for the munmap request it belongs to. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-7-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 332626df5d395..4590a11f7316f 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1627,30 +1627,14 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) return 0; } -static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, - struct fastrpc_req_munmap *req) +static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf) { struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; - struct fastrpc_buf *buf = NULL, *iter, *b; struct fastrpc_munmap_req_msg req_msg; struct device *dev = fl->sctx->dev; int err; u32 sc; - spin_lock(&fl->lock); - list_for_each_entry_safe(iter, b, &fl->mmaps, node) { - if ((iter->raddr == req->vaddrout) && (iter->size == req->size)) { - buf = iter; - break; - } - } - spin_unlock(&fl->lock); - - if (!buf) { - dev_err(dev, "mmap not in list\n"); - return -EINVAL; - } - req_msg.pgid = fl->tgid; req_msg.size = buf->size; req_msg.vaddr = buf->raddr; @@ -1676,12 +1660,29 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) { + struct fastrpc_buf *buf = NULL, *iter, *b; struct fastrpc_req_munmap req; + struct device *dev = fl->sctx->dev; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; - return fastrpc_req_munmap_impl(fl, &req); + spin_lock(&fl->lock); + list_for_each_entry_safe(iter, b, &fl->mmaps, node) { + if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) { + buf = iter; + break; + } + } + spin_unlock(&fl->lock); + + if (!buf) { + dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n", + req.vaddrout, req.size); + return -EINVAL; + } + + return fastrpc_req_munmap_impl(fl, buf); } static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) @@ -1690,7 +1691,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) struct fastrpc_buf *buf = NULL; struct fastrpc_mmap_req_msg req_msg; struct fastrpc_mmap_rsp_msg rsp_msg; - struct fastrpc_req_munmap req_unmap; struct fastrpc_phy_page pages; struct fastrpc_req_mmap req; struct device *dev = fl->sctx->dev; @@ -1752,11 +1752,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) spin_unlock(&fl->lock); if (copy_to_user((void __user *)argp, &req, sizeof(req))) { - /* unmap the memory and release the buffer */ - req_unmap.vaddrout = buf->raddr; - req_unmap.size = buf->size; - fastrpc_req_munmap_impl(fl, &req_unmap); - return -EFAULT; + err = -EFAULT; + goto err_assign; } dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n", @@ -1764,6 +1761,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) return 0; +err_assign: + fastrpc_req_munmap_impl(fl, buf); err_invoke: fastrpc_buf_free(buf); -- GitLab From 0871561055e666da421d779397efcc1e5e964cab Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:02 +0000 Subject: [PATCH 1203/1480] misc: fastrpc: Add support for audiopd In order to be able to start the adsp listener for audiopd using adsprpcd, we need to add the corresponding ioctl for creating a static process. On that ioctl call we need to allocate the heap. Allocating the heap needs to be happening only once and needs to be kept between different device open calls, so attach it to the channel context to make sure that remains until the RPMSG driver is removed. Then, if there are any VMIDs associated with the static ADSP process, do a call to SCM to assign it. And then, send all the necessary info related to heap to the DSP. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-8-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 135 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 7 ++ 2 files changed, 142 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 4590a11f7316f..adc44ba0eff65 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -37,8 +37,20 @@ #define FASTRPC_DSP_UTILITIES_HANDLE 2 #define FASTRPC_CTXID_MASK (0xFF0) #define INIT_FILELEN_MAX (2 * 1024 * 1024) +#define INIT_FILE_NAMELEN_MAX (128) #define FASTRPC_DEVICE_NAME "fastrpc" + +/* Add memory to static PD pool, protection thru XPU */ +#define ADSP_MMAP_HEAP_ADDR 4 +/* MAP static DMA buffer on DSP User PD */ +#define ADSP_MMAP_DMA_BUFFER 6 +/* Add memory to static PD pool protection thru hypervisor */ +#define ADSP_MMAP_REMOTE_HEAP_ADDR 8 +/* Add memory to userPD pool, for user heap */ #define ADSP_MMAP_ADD_PAGES 0x1000 +/* Add memory to userPD pool, for LLC heap */ +#define ADSP_MMAP_ADD_PAGES_LLC 0x3000, + #define DSP_UNSUPPORTED_API (0x80000414) /* MAX NUMBER of DSP ATTRIBUTES SUPPORTED */ #define FASTRPC_MAX_DSP_ATTRIBUTES (256) @@ -72,6 +84,7 @@ FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0) #define FASTRPC_CREATE_PROCESS_NARGS 6 +#define FASTRPC_CREATE_STATIC_PROCESS_NARGS 3 /* Remote Method id table */ #define FASTRPC_RMID_INIT_ATTACH 0 #define FASTRPC_RMID_INIT_RELEASE 1 @@ -261,6 +274,7 @@ struct fastrpc_channel_ctx { u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; + struct fastrpc_buf *remote_heap; bool secure; bool unsigned_support; }; @@ -1157,6 +1171,7 @@ bail: spin_unlock(&fl->lock); fastrpc_context_put(ctx); } + if (err) dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err); @@ -1181,6 +1196,120 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques return false; } +static int fastrpc_init_create_static_process(struct fastrpc_user *fl, + char __user *argp) +{ + struct fastrpc_init_create_static init; + struct fastrpc_invoke_args *args; + struct fastrpc_phy_page pages[1]; + char *name; + int err; + struct { + int pgid; + u32 namelen; + u32 pageslen; + } inbuf; + u32 sc; + + args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + if (copy_from_user(&init, argp, sizeof(init))) { + err = -EFAULT; + goto err; + } + + if (init.namelen > INIT_FILE_NAMELEN_MAX) { + err = -EINVAL; + goto err; + } + + name = kzalloc(init.namelen, GFP_KERNEL); + if (!name) { + err = -ENOMEM; + goto err; + } + + if (copy_from_user(name, (void __user *)(uintptr_t)init.name, init.namelen)) { + err = -EFAULT; + goto err_name; + } + + if (!fl->cctx->remote_heap) { + err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, + &fl->cctx->remote_heap); + if (err) + goto err_name; + + /* Map if we have any heap VMIDs associated with this ADSP Static Process. */ + if (fl->cctx->vmcount) { + unsigned int perms = BIT(QCOM_SCM_VMID_HLOS); + + err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, + (u64)fl->cctx->remote_heap->size, &perms, + fl->cctx->vmperms, fl->cctx->vmcount); + if (err) { + dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", + fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + goto err_map; + } + } + } + + inbuf.pgid = fl->tgid; + inbuf.namelen = init.namelen; + inbuf.pageslen = 0; + fl->pd = USER_PD; + + args[0].ptr = (u64)(uintptr_t)&inbuf; + args[0].length = sizeof(inbuf); + args[0].fd = -1; + + args[1].ptr = (u64)(uintptr_t)name; + args[1].length = inbuf.namelen; + args[1].fd = -1; + + pages[0].addr = fl->cctx->remote_heap->phys; + pages[0].size = fl->cctx->remote_heap->size; + + args[2].ptr = (u64)(uintptr_t) pages; + args[2].length = sizeof(*pages); + args[2].fd = -1; + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0); + + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, + sc, args); + if (err) + goto err_invoke; + + kfree(args); + + return 0; +err_invoke: + if (fl->cctx->vmcount) { + struct qcom_scm_vmperm perm; + + perm.vmid = QCOM_SCM_VMID_HLOS; + perm.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, + (u64)fl->cctx->remote_heap->size, + &(fl->cctx->vmperms[0].vmid), &perm, 1); + if (err) + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", + fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + } +err_map: + fastrpc_buf_free(fl->cctx->remote_heap); +err_name: + kfree(name); +err: + kfree(args); + + return err; +} + static int fastrpc_init_create_process(struct fastrpc_user *fl, char __user *argp) { @@ -1915,6 +2044,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INIT_ATTACH_SNS: err = fastrpc_init_attach(fl, SENSORS_PD); break; + case FASTRPC_IOCTL_INIT_CREATE_STATIC: + err = fastrpc_init_create_static_process(fl, argp); + break; case FASTRPC_IOCTL_INIT_CREATE: err = fastrpc_init_create_process(fl, argp); break; @@ -2184,6 +2316,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) if (cctx->secure_fdevice) misc_deregister(&cctx->secure_fdevice->miscdev); + if (cctx->remote_heap) + fastrpc_buf_free(cctx->remote_heap); + of_platform_depopulate(&rpdev->dev); cctx->rpdev = NULL; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 5e29f2cfa42d6..f33d914d8f469 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -13,6 +13,7 @@ #define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap) #define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap) #define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8) +#define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static) #define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map) #define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap) #define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability) @@ -87,6 +88,12 @@ struct fastrpc_init_create { __u64 file; /* pointer to elf file */ }; +struct fastrpc_init_create_static { + __u32 namelen; /* length of pd process name */ + __u32 memlen; + __u64 name; /* pd process name */ +}; + struct fastrpc_alloc_dma_buf { __s32 fd; /* fd */ __u32 flags; /* flags to map with */ -- GitLab From 76e8e4ace1ed2c97dba3b1370e0e105e07c572bc Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:03 +0000 Subject: [PATCH 1204/1480] misc: fastrpc: Safekeep mmaps on interrupted invoke If the userspace daemon is killed in the middle of an invoke (e.g. audiopd listerner invoke), we need to skip the unmapping on device release, otherwise the DSP will crash. So lets safekeep all the maps only if there is in invoke interrupted, by attaching them to the channel context (which is resident until RPMSG driver is removed), and free them on RPMSG driver remove. Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-9-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index adc44ba0eff65..d7a98396ee945 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -275,6 +275,7 @@ struct fastrpc_channel_ctx { struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; struct fastrpc_buf *remote_heap; + struct list_head invoke_interrupted_mmaps; bool secure; bool unsigned_support; }; @@ -1109,6 +1110,8 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, struct fastrpc_invoke_args *args) { struct fastrpc_invoke_ctx *ctx = NULL; + struct fastrpc_buf *buf, *b; + int err = 0; if (!fl->sctx) @@ -1172,6 +1175,13 @@ bail: fastrpc_context_put(ctx); } + if (err == -ERESTARTSYS) { + list_for_each_entry_safe(buf, b, &fl->mmaps, node) { + list_del(&buf->node); + list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps); + } + } + if (err) dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err); @@ -2278,6 +2288,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) dev_set_drvdata(&rpdev->dev, data); dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); + INIT_LIST_HEAD(&data->invoke_interrupted_mmaps); spin_lock_init(&data->lock); idr_init(&data->ctx_idr); data->domain_id = domain_id; @@ -2302,6 +2313,7 @@ static void fastrpc_notify_users(struct fastrpc_user *user) static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); + struct fastrpc_buf *buf, *b; struct fastrpc_user *user; unsigned long flags; @@ -2316,6 +2328,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) if (cctx->secure_fdevice) misc_deregister(&cctx->secure_fdevice->miscdev); + list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node) + list_del(&buf->node); + if (cctx->remote_heap) fastrpc_buf_free(cctx->remote_heap); -- GitLab From 532ad70c6d449029cfa3eac8408f427e31334f33 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:04 +0000 Subject: [PATCH 1205/1480] misc: fastrpc: Add mmap request assigning for static PD pool If the mmap request is to add pages and thre are VMIDs associated with that context, do a call to SCM to reassign that memory. Do not do this for remote heap allocation, that is done on init create static process only. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-10-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index d7a98396ee945..2e49bf1c31ef7 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1839,8 +1839,9 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; - if (req.flags != ADSP_MMAP_ADD_PAGES) { + if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) { dev_err(dev, "flag not supported 0x%x\n", req.flags); + return -EINVAL; } @@ -1886,6 +1887,22 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) /* let the client know the address to use */ req.vaddrout = rsp_msg.vaddr; + /* Add memory to static PD pool, protection thru hypervisor */ + if (req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { + struct qcom_scm_vmperm perm; + int err = 0; + + perm.vmid = QCOM_SCM_VMID_HLOS; + perm.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(buf->phys, buf->size, + &(fl->cctx->vmperms[0].vmid), &perm, 1); + if (err) { + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", + buf->phys, buf->size, err); + goto err_assign; + } + } + spin_lock(&fl->lock); list_add_tail(&buf->node, &fl->mmaps); spin_unlock(&fl->lock); -- GitLab From 9bde43a0e2f469961e18d0a3496a9a74379c22bf Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 25 Nov 2022 07:14:05 +0000 Subject: [PATCH 1206/1480] misc: fastrpc: Add dma_mask to fastrpc_channel_ctx dma_set_mask_and_coherent only updates the mask to which the device dma_mask pointer points to. Add a dma_mask to the channel ctx and set the device dma_mask to point to that, otherwise the dma_set_mask will return an error and the dma_set_coherent_mask will be skipped too. Co-developed-by: Srinivas Kandagatla Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221125071405.148786-11-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 2e49bf1c31ef7..278ab6ca1a5ac 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -278,6 +278,7 @@ struct fastrpc_channel_ctx { struct list_head invoke_interrupted_mmaps; bool secure; bool unsigned_support; + u64 dma_mask; }; struct fastrpc_device { @@ -2303,6 +2304,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) kref_init(&data->refcount); dev_set_drvdata(&rpdev->dev, data); + rdev->dma_mask = &data->dma_mask; dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); INIT_LIST_HEAD(&data->invoke_interrupted_mmaps); -- GitLab From fd5ac974fc25feed084c2d1599d0dddb4e0556bc Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 23 Nov 2022 14:36:09 +0100 Subject: [PATCH 1207/1480] counter: stm32-lptimer-cnt: fix the check on arr and cmp registers update The ARR (auto reload register) and CMP (compare) registers are successively written. The status bits to check the update of these registers are polled together with regmap_read_poll_timeout(). The condition to end the loop may become true, even if one of the register isn't correctly updated. So ensure both status bits are set before clearing them. Fixes: d8958824cf07 ("iio: counter: Add support for STM32 LPTimer") Signed-off-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221123133609.465614-1-fabrice.gasnier@foss.st.com/ Signed-off-by: William Breathitt Gray --- drivers/counter/stm32-lptimer-cnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c index d6b80b6dfc287..8439755559b21 100644 --- a/drivers/counter/stm32-lptimer-cnt.c +++ b/drivers/counter/stm32-lptimer-cnt.c @@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv, /* ensure CMP & ARR registers are properly written */ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, - (val & STM32_LPTIM_CMPOK_ARROK), + (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 100, 1000); if (ret) return ret; -- GitLab From e88906b169ebcb8046e8f0ad76edd09ab41cfdfe Mon Sep 17 00:00:00 2001 From: Bruno Thomsen Date: Sun, 27 Nov 2022 18:08:11 +0100 Subject: [PATCH 1208/1480] USB: serial: cp210x: add Kamstrup RF sniffer PIDs The RF sniffers are based on cp210x where the RF frontends are based on a different USB stack. RF sniffers can analyze packets meta data including power level and perform packet injection. Can be used to perform RF frontend self-test when connected to a concentrator, ex. arch/arm/boot/dts/imx7d-flex-concentrator.dts Signed-off-by: Bruno Thomsen Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 3bcec419f4632..f6fb23620e87a 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -195,6 +195,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */ { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */ + { USB_DEVICE(0x17A8, 0x0011) }, /* Kamstrup 444 MHz RF sniffer */ + { USB_DEVICE(0x17A8, 0x0013) }, /* Kamstrup 870 MHz RF sniffer */ { USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */ { USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ -- GitLab From 20ee8c223f792947378196307d8e707c9cdc2d61 Mon Sep 17 00:00:00 2001 From: Yang Shen Date: Tue, 22 Nov 2022 17:03:55 +0800 Subject: [PATCH 1209/1480] coresight: trbe: remove cpuhp instance node before remove cpuhp state cpuhp_state_add_instance() and cpuhp_state_remove_instance() should be used in pairs. Or there will lead to the warn on cpuhp_remove_multi_state() since the cpuhp_step list is not empty. The following is the error log with 'rmmod coresight-trbe': Error: Removing state 215 which has instances left. Call trace: __cpuhp_remove_state_cpuslocked+0x144/0x160 __cpuhp_remove_state+0xac/0x100 arm_trbe_device_remove+0x2c/0x60 [coresight_trbe] platform_remove+0x34/0x70 device_remove+0x54/0x90 device_release_driver_internal+0x1e4/0x250 driver_detach+0x5c/0xb0 bus_remove_driver+0x64/0xc0 driver_unregister+0x3c/0x70 platform_driver_unregister+0x20/0x30 arm_trbe_exit+0x1c/0x658 [coresight_trbe] __arm64_sys_delete_module+0x1ac/0x24c invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x58/0x1a0 do_el0_svc+0x38/0xd0 el0_svc+0x2c/0xc0 el0t_64_sync_handler+0x1ac/0x1b0 el0t_64_sync+0x19c/0x1a0 ---[ end trace 0000000000000000 ]--- Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") Reviewed-by: Anshuman Khandual Signed-off-by: Yang Shen Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20221122090355.23533-1-shenyang39@huawei.com --- drivers/hwtracing/coresight/coresight-trbe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 2b386bb848f8d..1fc4fd79a1c69 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -1434,6 +1434,7 @@ static int arm_trbe_probe_cpuhp(struct trbe_drvdata *drvdata) static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata) { + cpuhp_state_remove_instance(drvdata->trbe_online, &drvdata->hotplug_node); cpuhp_remove_multi_state(drvdata->trbe_online); } -- GitLab From 3dc228b35387803d9c43ed1b098aabb1d3ae9c7d Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Wed, 23 Nov 2022 19:38:18 +0000 Subject: [PATCH 1210/1480] coresight: cti: Fix null pointer error on CTI init before ETM When CTI is discovered first then the function coresight_set_assoc_ectdev_mutex() is called to set the association between CTI and ETM device. Recent lockdep fix passes a null pointer. This patch passes the correct pointer. Before patch: log of boot oops sequence with CTI discovered first: [ 12.424091] cs_system_cfg: CoreSight Configuration manager initialised [ 12.483474] coresight cti_sys0: CTI initialized [ 12.488109] coresight cti_sys1: CTI initialized [ 12.503594] coresight cti_cpu0: CTI initialized [ 12.517877] coresight-cpu-debug 850000.debug: Coresight debug-CPU0 initialized [ 12.523479] coresight-cpu-debug 852000.debug: Coresight debug-CPU1 initialized [ 12.529926] coresight-cpu-debug 854000.debug: Coresight debug-CPU2 initialized [ 12.541808] coresight stm0: STM32 initialized [ 12.544421] coresight-cpu-debug 856000.debug: Coresight debug-CPU3 initialized [ 12.585639] coresight cti_cpu1: CTI initialized [ 12.614028] coresight cti_cpu2: CTI initialized [ 12.631679] CSCFG registered etm0 [ 12.633920] coresight etm0: CPU0: etm v4.0 initialized [ 12.656392] coresight cti_cpu3: CTI initialized ... [ 12.708383] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000348 ... [ 12.755094] Internal error: Oops: 0000000096000044 [#1] SMP [ 12.761817] Modules linked in: coresight_etm4x(+) coresight_tmc coresight_cpu_debug coresight_replicator coresight_funnel coresight_cti coresight_tpiu coresight_stm coresight [ 12.767210] CPU: 3 PID: 1346 Comm: systemd-udevd Not tainted 6.1.0-rc3tid-v6tid-v6-235166-gf7f7d7a2204a-dirty #498 [ 12.782827] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT) [ 12.793154] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 12.800010] pc : coresight_set_assoc_ectdev_mutex+0x30/0x50 [coresight] [ 12.806694] lr : coresight_set_assoc_ectdev_mutex+0x30/0x50 [coresight] ... [ 12.885064] Call trace: [ 12.892352] coresight_set_assoc_ectdev_mutex+0x30/0x50 [coresight] [ 12.894693] cti_add_assoc_to_csdev+0x144/0x1b0 [coresight_cti] [ 12.900943] coresight_register+0x2c8/0x320 [coresight] [ 12.906844] etm4_add_coresight_dev.isra.27+0x148/0x280 [coresight_etm4x] [ 12.912056] etm4_probe+0x144/0x1c0 [coresight_etm4x] [ 12.918998] etm4_probe_amba+0x40/0x78 [coresight_etm4x] [ 12.924032] amba_probe+0x11c/0x1f0 After patch: similar log [ 12.444467] cs_system_cfg: CoreSight Configuration manager initialised [ 12.456329] coresight-cpu-debug 850000.debug: Coresight debug-CPU0 initialized [ 12.456754] coresight-cpu-debug 852000.debug: Coresight debug-CPU1 initialized [ 12.469672] coresight-cpu-debug 854000.debug: Coresight debug-CPU2 initialized [ 12.476098] coresight-cpu-debug 856000.debug: Coresight debug-CPU3 initialized [ 12.532409] coresight stm0: STM32 initialized [ 12.533708] coresight cti_sys0: CTI initialized [ 12.539478] coresight cti_sys1: CTI initialized [ 12.550106] coresight cti_cpu0: CTI initialized [ 12.633931] coresight cti_cpu1: CTI initialized [ 12.634664] coresight cti_cpu2: CTI initialized [ 12.638090] coresight cti_cpu3: CTI initialized [ 12.721136] CSCFG registered etm0 ... [ 12.762643] CSCFG registered etm1 [ 12.762666] coresight etm1: CPU1: etm v4.0 initialized [ 12.776258] CSCFG registered etm2 [ 12.776282] coresight etm2: CPU2: etm v4.0 initialized [ 12.784357] CSCFG registered etm3 [ 12.785455] coresight etm3: CPU3: etm v4.0 initialized Error can also be triggered by manually starting the modules using modprobe in the following order: root@linaro-developer:/home/linaro/cs-mods# modprobe coresight root@linaro-developer:/home/linaro/cs-mods# modprobe coresight-cti root@linaro-developer:/home/linaro/cs-mods# modprobe coresight-etm4x Tested on Dragonboard DB410c Applies to coresight/next Fixes: 23722fb46725 ("coresight: Fix possible deadlock with lock dependency") Signed-off-by: Mike Leach Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20221123193818.6253-1-mike.leach@linaro.org --- drivers/hwtracing/coresight/coresight-cti-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index c6e8c6542f24b..d2cf4f4848e1b 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -564,7 +564,7 @@ static void cti_add_assoc_to_csdev(struct coresight_device *csdev) * if we found a matching csdev then update the ECT * association pointer for the device with this CTI. */ - coresight_set_assoc_ectdev_mutex(csdev->ect_dev, + coresight_set_assoc_ectdev_mutex(csdev, ect_item->csdev); break; } -- GitLab From c767c34740132ffc478226864a7461493cdc2413 Mon Sep 17 00:00:00 2001 From: Jilin Yuan Date: Wed, 19 Oct 2022 20:49:53 +0800 Subject: [PATCH 1211/1480] coresight: etm4x: fix repeated words in comments Delete the redundant word 'the'. Signed-off-by: Jilin Yuan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20221019124953.45885-1-yuanjilin@cdjrlc.com --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 9dc0d7f57565a..1cc052979e016 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1481,7 +1481,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, /* * If filters::ssstatus == 1, trace acquisition was * started but the process was yanked away before the - * the stop address was hit. As such the start/stop + * stop address was hit. As such the start/stop * logic needs to be re-started so that tracing can * resume where it left. * -- GitLab From 4bded7af8b9af6e97514b0521004f90267905aef Mon Sep 17 00:00:00 2001 From: Beau Belgrave Date: Wed, 23 Nov 2022 10:32:48 -0800 Subject: [PATCH 1212/1480] tracing/user_events: Fix call print_fmt leak If user_event_trace_register() fails within user_event_parse() the call's print_fmt member is not freed. Add kfree call to fix this. Link: https://lkml.kernel.org/r/20221123183248.554-1-beaub@linux.microsoft.com Fixes: aa3b2b4c6692 ("user_events: Add print_fmt generation support for basic types") Signed-off-by: Beau Belgrave Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index 539b08ae70207..9cb53182bb31c 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -1359,6 +1359,7 @@ put_user_lock: put_user: user_event_destroy_fields(user); user_event_destroy_validators(user); + kfree(user->call.print_fmt); kfree(user); return ret; } -- GitLab From 46a5cd8c8dcacc58912b4bf04ca4d84d2977bbbc Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Mon, 17 Oct 2022 14:05:13 -0400 Subject: [PATCH 1213/1480] tracing: Update MAINTAINERS file for new patchwork and mailing list The tracing subsystem now has its own mailing list (although patches should also be sent to LKML) as well as a new patchwork entry for kernel related tracing patches. Update the MAINTAINERS file to reflect the changes. Link: https://lore.kernel.org/linux-trace-kernel/20221017140513.14b9ce2e@gandalf.local.home Signed-off-by: Steven Rostedt (Google) --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2585e7edc3358..d12576150a706 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8461,6 +8461,9 @@ FUNCTION HOOKS (FTRACE) M: Steven Rostedt M: Masami Hiramatsu R: Mark Rutland +L: linux-kernel@vger.kernel.org +L: linux-trace-kernel@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git F: Documentation/trace/ftrace* @@ -11483,6 +11486,9 @@ M: Naveen N. Rao M: Anil S Keshavamurthy M: "David S. Miller" M: Masami Hiramatsu +L: linux-kernel@vger.kernel.org +L: linux-trace-kernel@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git F: Documentation/trace/kprobes.rst @@ -20862,6 +20868,9 @@ F: drivers/hwmon/pmbus/tps546d24.c TRACING M: Steven Rostedt M: Masami Hiramatsu +L: linux-kernel@vger.kernel.org +L: linux-trace-kernel@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git F: Documentation/trace/* -- GitLab From 1ab30c610630da5391a373cddb8a065bf4c4bc01 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 22 Nov 2022 19:12:26 +0800 Subject: [PATCH 1214/1480] usb: roles: fix of node refcount leak in usb_role_switch_is_parent() I got the following report while doing device(mt6370-tcpc) load test with CONFIG_OF_UNITTEST and CONFIG_OF_DYNAMIC enabled: OF: ERROR: memory leak, expected refcount 1 instead of 2, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node /i2c/pmic@34 The 'parent' returned by fwnode_get_parent() with refcount incremented. it needs be put after using. Fixes: 6fadd72943b8 ("usb: roles: get usb-role-switch from parent") Reviewed-by: Heikki Krogerus Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221122111226.251588-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/roles/class.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index dfaed7eee94fc..32e6d19f7011a 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -106,10 +106,13 @@ usb_role_switch_is_parent(struct fwnode_handle *fwnode) struct fwnode_handle *parent = fwnode_get_parent(fwnode); struct device *dev; - if (!parent || !fwnode_property_present(parent, "usb-role-switch")) + if (!fwnode_property_present(parent, "usb-role-switch")) { + fwnode_handle_put(parent); return NULL; + } dev = class_find_device_by_fwnode(role_class, parent); + fwnode_handle_put(parent); return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); } -- GitLab From e0dced9c7d4763fd97c86a13902d135f03cc42eb Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 23 Nov 2022 11:30:21 +0200 Subject: [PATCH 1215/1480] usb: typec: ucsi: Resume in separate work It can take more than one second to check each connector when the system is resumed. So if you have, say, eight connectors, it may take eight seconds for ucsi_resume() to finish. That's a bit too much. This will modify ucsi_resume() so that it schedules a work where the interface is actually resumed instead of checking the connectors directly. The connections will also be checked in separate tasks which are queued for each connector separately. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216706 Fixes: 99f6d4361113 ("usb: typec: ucsi: Check the connection on resume") Cc: Reported-by: Todd Brandt Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20221123093021.25981-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.c | 17 +++++++++++++---- drivers/usb/typec/ucsi/ucsi.h | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index a7987fc764cc6..eabe519013e78 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1270,8 +1270,9 @@ err: return ret; } -int ucsi_resume(struct ucsi *ucsi) +static void ucsi_resume_work(struct work_struct *work) { + struct ucsi *ucsi = container_of(work, struct ucsi, resume_work); struct ucsi_connector *con; u64 command; int ret; @@ -1279,15 +1280,21 @@ int ucsi_resume(struct ucsi *ucsi) /* Restore UCSI notification enable mask after system resume */ command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; ret = ucsi_send_command(ucsi, command, NULL, 0); - if (ret < 0) - return ret; + if (ret < 0) { + dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret); + return; + } for (con = ucsi->connector; con->port; con++) { mutex_lock(&con->lock); - ucsi_check_connection(con); + ucsi_partner_task(con, ucsi_check_connection, 1, 0); mutex_unlock(&con->lock); } +} +int ucsi_resume(struct ucsi *ucsi) +{ + queue_work(system_long_wq, &ucsi->resume_work); return 0; } EXPORT_SYMBOL_GPL(ucsi_resume); @@ -1347,6 +1354,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops) if (!ucsi) return ERR_PTR(-ENOMEM); + INIT_WORK(&ucsi->resume_work, ucsi_resume_work); INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work); mutex_init(&ucsi->ppm_lock); ucsi->dev = dev; @@ -1401,6 +1409,7 @@ void ucsi_unregister(struct ucsi *ucsi) /* Make sure that we are not in the middle of driver initialization */ cancel_delayed_work_sync(&ucsi->work); + cancel_work_sync(&ucsi->resume_work); /* Disable notifications */ ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 8eb391e3e592c..c968474ee5473 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -287,6 +287,7 @@ struct ucsi { struct ucsi_capability cap; struct ucsi_connector *connector; + struct work_struct resume_work; struct delayed_work work; int work_count; #define UCSI_ROLE_SWITCH_RETRY_PER_HZ 10 -- GitLab From 57b7b733b1a7aeab25bc2670afff608214284863 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 23 Nov 2022 12:07:46 +0100 Subject: [PATCH 1216/1480] usb: gadget: function: Simplify diagnostic messaging in printer Don't issue messages which can be easily achieved with ftrace. In case of printer_open() the return code is propagated to other layers so the user will know about -EBUSY anyway. Signed-off-by: Andrzej Pietrasiewicz Link: https://lore.kernel.org/r/20221123110746.59611-1-andrzej.p@collabora.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_printer.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index a881c69b1f2bf..4903d761a8724 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -364,7 +364,7 @@ printer_open(struct inode *inode, struct file *fd) spin_unlock_irqrestore(&dev->lock, flags); kref_get(&dev->kref); - DBG(dev, "printer_open returned %x\n", ret); + return ret; } @@ -382,7 +382,6 @@ printer_close(struct inode *inode, struct file *fd) spin_unlock_irqrestore(&dev->lock, flags); kref_put(&dev->kref, printer_dev_free); - DBG(dev, "printer_close\n"); return 0; } @@ -848,8 +847,6 @@ static void printer_reset_interface(struct printer_dev *dev) if (dev->interface < 0) return; - DBG(dev, "%s\n", __func__); - if (dev->in_ep->desc) usb_ep_disable(dev->in_ep); @@ -887,8 +884,6 @@ static void printer_soft_reset(struct printer_dev *dev) { struct usb_request *req; - INFO(dev, "Received Printer Reset Request\n"); - if (usb_ep_disable(dev->in_ep)) DBG(dev, "Failed to disable USB in_ep\n"); if (usb_ep_disable(dev->out_ep)) @@ -1185,8 +1180,6 @@ static void printer_func_disable(struct usb_function *f) { struct printer_dev *dev = func_to_printer(f); - DBG(dev, "%s\n", __func__); - printer_reset_interface(dev); } -- GitLab From 3c347cdafa3db43337870006e5c2d7b78a8dae20 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 25 Nov 2022 14:41:20 +0800 Subject: [PATCH 1217/1480] usb: core: hcd: Fix return value check in usb_hcd_setup_local_mem() If dmam_alloc_attrs() fails, it returns NULL pointer and never return ERR_PTR(), so repleace IS_ERR() with IS_ERR_OR_NULL() and if it's NULL, returns -ENOMEM. Fixes: 9ba26f5cecd8 ("ARM: sa1100/assabet: move dmabounce hack to ohci driver") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221125064120.2842452-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index faeaace0d197d..8300baedafd20 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -3133,8 +3133,12 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); - if (IS_ERR(local_mem)) + if (IS_ERR_OR_NULL(local_mem)) { + if (!local_mem) + return -ENOMEM; + return PTR_ERR(local_mem); + } /* * Here we pass a dma_addr_t but the arg type is a phys_addr_t. -- GitLab From f05f80f217bf52443a2582bca19fd78188333f25 Mon Sep 17 00:00:00 2001 From: Shruthi Sanil Date: Fri, 25 Nov 2022 16:23:27 +0530 Subject: [PATCH 1218/1480] usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system for Raptor Lake The device ID 0xa70e is defined for the USB3 device controller in the CPU sub-system of Raptor Lake platform. Hence updating the ID accordingly. Fixes: bad0d1d726ac ("usb: dwc3: pci: Add support for Intel Raptor Lake") Cc: stable Reviewed-by: Heikki Krogerus Signed-off-by: Shruthi Sanil Link: https://lore.kernel.org/r/20221125105327.27945-1-shruthi.sanil@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index fb14511b1e10f..89c9ab2b19f85 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -45,7 +45,7 @@ #define PCI_DEVICE_ID_INTEL_ADLN 0x465e #define PCI_DEVICE_ID_INTEL_ADLN_PCH 0x54ee #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 -#define PCI_DEVICE_ID_INTEL_RPL 0x460e +#define PCI_DEVICE_ID_INTEL_RPL 0xa70e #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e -- GitLab From 01792c6036af577e4cb1aa7b9ffce7a4882c86b5 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Mon, 28 Nov 2022 16:13:06 +0800 Subject: [PATCH 1219/1480] usb: host: fix a typo in ehci.h Change "ehci_hq" to "ehci_qh" in this comment. Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20221128081306.2772729-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ad3f13a3eaf1b..c5c7f87825493 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -471,7 +471,7 @@ struct ehci_iso_sched { * acts like a qh would, if EHCI had them for ISO. */ struct ehci_iso_stream { - /* first field matches ehci_hq, but is NULL */ + /* first field matches ehci_qh, but is NULL */ struct ehci_qh_hw *hw; u8 bEndpointAddress; -- GitLab From 27ef17849779edd5600aa27d1a246ad424761971 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Mon, 28 Nov 2022 19:29:54 +0900 Subject: [PATCH 1220/1480] usb: add usb_set_intfdata() documentation USB drivers do not need to call usb_set_intfdata(intf, NULL) in their usb_driver::disconnect callback because the core already does it in [1]. However, this fact is widely unknown, c.f.: $ git grep "usb_set_intfdata(.*NULL)" | wc -l 215 Especially, setting the interface to NULL before all action completed can result in a NULL pointer dereference. Not calling usb_set_intfdata() at all in disconnect() is the safest method. Add documentation to usb_set_intfdata() to clarify this point. Also remove the call in usb-skeletion's disconnect() not to confuse the new comers. [1] function usb_unbind_interface() from drivers/usb/core/driver.c Link: https://elixir.bootlin.com/linux/v6.0/source/drivers/usb/core/driver.c#L497 Signed-off-by: Vincent Mailhol Link: https://lore.kernel.org/r/20221128102954.3615579-1-mailhol.vincent@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usb-skeleton.c | 1 - include/linux/usb.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index d87deee3e26e1..900a64ad25e4f 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -564,7 +564,6 @@ static void skel_disconnect(struct usb_interface *interface) int minor = interface->minor; dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); /* give back our minor */ usb_deregister_dev(interface, &skel_class); diff --git a/include/linux/usb.h b/include/linux/usb.h index 9ff1ad4dfad12..d4afeeec1e1af 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -265,6 +265,18 @@ static inline void *usb_get_intfdata(struct usb_interface *intf) return dev_get_drvdata(&intf->dev); } +/** + * usb_set_intfdata() - associate driver-specific data with the interface + * @intf: the usb interface + * @data: pointer to the device priv structure or %NULL + * + * Drivers should use this function in their probe() to associate their + * driver-specific data with the usb interface. + * + * When disconnecting, the core will take care of setting @intf back to %NULL, + * so no actions are needed on the driver side. The interface should not be set + * to %NULL before all actions completed (e.g. no outsanding URB remaining). + */ static inline void usb_set_intfdata(struct usb_interface *intf, void *data) { dev_set_drvdata(&intf->dev, data); -- GitLab From 03a88b0bafbe3f548729d970d8366f48718c9b19 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Mon, 28 Nov 2022 14:33:37 +0800 Subject: [PATCH 1221/1480] usb: xhci-mtk: fix leakage of shared hcd when fail to set wakeup irq Can not set the @shared_hcd to NULL before decrease the usage count by usb_put_hcd(), this will cause the shared hcd not released. Fixes: 04284eb74e0c ("usb: xhci-mtk: add support runtime PM") Cc: Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20221128063337.18124-1-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index cff3c4aea0362..f7cbb08fc5068 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -646,7 +646,6 @@ static int xhci_mtk_probe(struct platform_device *pdev) dealloc_usb3_hcd: usb_remove_hcd(xhci->shared_hcd); - xhci->shared_hcd = NULL; put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); -- GitLab From 032399819dd5f135e6ffe446c8e97ab54eec3464 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Tue, 22 Nov 2022 22:05:36 +0000 Subject: [PATCH 1222/1480] usb: typec: Add partner PD object wrapper Some port drivers may want to set a Type-C partner as a parent for a USB Power Delivery object, but the Type-C partner struct isn't exposed outside of the Type-C class driver. Add a wrapper to usb_power_delivery_register() which sets the provided Type-C partner as a parent to the USB PD object. This helps to avoid exposing the Type-C partner's device struct unnecessarily. Cc: Benson Leung Suggested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Prashant Malani Link: https://lore.kernel.org/r/20221122220538.2991775-2-pmalani@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/class.c | 19 +++++++++++++++++++ include/linux/usb/typec.h | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index bd5e5dd704313..5897905cb4f08 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -821,6 +821,25 @@ void typec_partner_set_svdm_version(struct typec_partner *partner, } EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version); +/** + * typec_partner_usb_power_delivery_register - Register Type-C partner USB Power Delivery Support + * @partner: Type-C partner device. + * @desc: Description of the USB PD contract. + * + * This routine is a wrapper around usb_power_delivery_register(). It registers + * USB Power Delivery Capabilities for a Type-C partner device. Specifically, + * it sets the Type-C partner device as a parent for the resulting USB Power Delivery object. + * + * Returns handle to struct usb_power_delivery or ERR_PTR. + */ +struct usb_power_delivery * +typec_partner_usb_power_delivery_register(struct typec_partner *partner, + struct usb_power_delivery_desc *desc) +{ + return usb_power_delivery_register(&partner->dev, desc); +} +EXPORT_SYMBOL_GPL(typec_partner_usb_power_delivery_register); + /** * typec_register_partner - Register a USB Type-C Partner * @port: The USB Type-C Port the partner is connected to diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 7751bedcae5dd..8fa781207970a 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -23,6 +23,7 @@ struct fwnode_handle; struct device; struct usb_power_delivery; +struct usb_power_delivery_desc; enum typec_port_type { TYPEC_PORT_SRC, @@ -327,6 +328,9 @@ void typec_partner_set_svdm_version(struct typec_partner *partner, enum usb_pd_svdm_ver svdm_version); int typec_get_negotiated_svdm_version(struct typec_port *port); +struct usb_power_delivery *typec_partner_usb_power_delivery_register(struct typec_partner *partner, + struct usb_power_delivery_desc *desc); + int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_delivery *pd); int typec_partner_set_usb_power_delivery(struct typec_partner *partner, struct usb_power_delivery *pd); -- GitLab From ab3593eeef606816bcc28b12690c51379c3d12eb Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Tue, 22 Nov 2022 22:05:37 +0000 Subject: [PATCH 1223/1480] platform/chrome: cros_ec_typec: Set parent of partner PD object In order to tell what Type-C device a PD object belongs to, its parent needs to be set. Use the Type-C partner USB PD registration wrapper to set the parent appropriately for PD objects which are created for connected Type-C partners. Cc: Benson Leung Cc: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Prashant Malani Link: https://lore.kernel.org/r/20221122220538.2991775-3-pmalani@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/platform/chrome/cros_ec_typec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 2a7ff14dc37e9..d5bc4021aca2f 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -968,7 +968,7 @@ static void cros_typec_register_partner_pdos(struct cros_typec_data *typec, if (!resp->source_cap_count && !resp->sink_cap_count) return; - port->partner_pd = usb_power_delivery_register(NULL, &desc); + port->partner_pd = typec_partner_usb_power_delivery_register(port->partner, &desc); if (IS_ERR(port->partner_pd)) { dev_warn(typec->dev, "Failed to register partner PD device, port: %d\n", port_num); return; -- GitLab From 57f8e00d8a82073ab7893ab8ae4055580ef9552f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 25 Nov 2022 10:55:06 +0200 Subject: [PATCH 1224/1480] usb: musb: Drop old unused am35x glue layer The am35x glue layer is no longer in use and can be dropped. There are no longer any SoCs passing platform data for it as they are booting using devicetree. In general, the am35x SoCs are similar to am335x and ti81xx and can use the musb_dsps glue layer as long as there is a proper phy driver available. Cc: Arnd Bergmann Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20221125085506.38127-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/Kconfig | 5 - drivers/usb/musb/Makefile | 1 - drivers/usb/musb/am35x.c | 610 -------------------------------------- 3 files changed, 616 deletions(-) delete mode 100644 drivers/usb/musb/am35x.c diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 290df4d5d5ce8..3a1f4bcea80c0 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -88,11 +88,6 @@ config USB_MUSB_OMAP2PLUS depends on OMAP_CONTROL_PHY || !OMAP_CONTROL_PHY select GENERIC_PHY -config USB_MUSB_AM35X - tristate "AM35x" - depends on ARCH_OMAP - depends on NOP_USB_XCEIV - config USB_MUSB_DSPS tristate "TI DSPS platforms" depends on ARCH_OMAP2PLUS || COMPILE_TEST diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 44a9e27b2157a..5dccf0e453e1b 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -16,7 +16,6 @@ musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o # Hardware Glue Layer obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o -obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o obj-$(CONFIG_USB_MUSB_TUSB6010) += tusb6010.o obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c deleted file mode 100644 index bf2c0fa6cb320..0000000000000 --- a/drivers/usb/musb/am35x.c +++ /dev/null @@ -1,610 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/* - * Texas Instruments AM35x "glue layer" - * - * Copyright (c) 2010, by Texas Instruments - * - * Based on the DA8xx "glue layer" code. - * Copyright (c) 2008-2009, MontaVista Software, Inc. - * - * This file is part of the Inventra Controller Driver for Linux. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "musb_core.h" - -/* - * AM35x specific definitions - */ -/* USB 2.0 OTG module registers */ -#define USB_REVISION_REG 0x00 -#define USB_CTRL_REG 0x04 -#define USB_STAT_REG 0x08 -#define USB_EMULATION_REG 0x0c -/* 0x10 Reserved */ -#define USB_AUTOREQ_REG 0x14 -#define USB_SRP_FIX_TIME_REG 0x18 -#define USB_TEARDOWN_REG 0x1c -#define EP_INTR_SRC_REG 0x20 -#define EP_INTR_SRC_SET_REG 0x24 -#define EP_INTR_SRC_CLEAR_REG 0x28 -#define EP_INTR_MASK_REG 0x2c -#define EP_INTR_MASK_SET_REG 0x30 -#define EP_INTR_MASK_CLEAR_REG 0x34 -#define EP_INTR_SRC_MASKED_REG 0x38 -#define CORE_INTR_SRC_REG 0x40 -#define CORE_INTR_SRC_SET_REG 0x44 -#define CORE_INTR_SRC_CLEAR_REG 0x48 -#define CORE_INTR_MASK_REG 0x4c -#define CORE_INTR_MASK_SET_REG 0x50 -#define CORE_INTR_MASK_CLEAR_REG 0x54 -#define CORE_INTR_SRC_MASKED_REG 0x58 -/* 0x5c Reserved */ -#define USB_END_OF_INTR_REG 0x60 - -/* Control register bits */ -#define AM35X_SOFT_RESET_MASK 1 - -/* USB interrupt register bits */ -#define AM35X_INTR_USB_SHIFT 16 -#define AM35X_INTR_USB_MASK (0x1ff << AM35X_INTR_USB_SHIFT) -#define AM35X_INTR_DRVVBUS 0x100 -#define AM35X_INTR_RX_SHIFT 16 -#define AM35X_INTR_TX_SHIFT 0 -#define AM35X_TX_EP_MASK 0xffff /* EP0 + 15 Tx EPs */ -#define AM35X_RX_EP_MASK 0xfffe /* 15 Rx EPs */ -#define AM35X_TX_INTR_MASK (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT) -#define AM35X_RX_INTR_MASK (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT) - -#define USB_MENTOR_CORE_OFFSET 0x400 - -struct am35x_glue { - struct device *dev; - struct platform_device *musb; - struct platform_device *phy; - struct clk *phy_clk; - struct clk *clk; -}; - -/* - * am35x_musb_enable - enable interrupts - */ -static void am35x_musb_enable(struct musb *musb) -{ - void __iomem *reg_base = musb->ctrl_base; - u32 epmask; - - /* Workaround: setup IRQs through both register sets. */ - epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) | - ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT); - - musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask); - musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK); - - /* Force the DRVVBUS IRQ so we can start polling for ID change. */ - musb_writel(reg_base, CORE_INTR_SRC_SET_REG, - AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT); -} - -/* - * am35x_musb_disable - disable HDRC and flush interrupts - */ -static void am35x_musb_disable(struct musb *musb) -{ - void __iomem *reg_base = musb->ctrl_base; - - musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK); - musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG, - AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK); - musb_writel(reg_base, USB_END_OF_INTR_REG, 0); -} - -#define portstate(stmt) stmt - -static void am35x_musb_set_vbus(struct musb *musb, int is_on) -{ - WARN_ON(is_on && is_peripheral_active(musb)); -} - -#define POLL_SECONDS 2 - -static void otg_timer(struct timer_list *t) -{ - struct musb *musb = from_timer(musb, t, dev_timer); - void __iomem *mregs = musb->mregs; - u8 devctl; - unsigned long flags; - - /* - * We poll because AM35x's won't expose several OTG-critical - * status change events (from the transceiver) otherwise. - */ - devctl = musb_readb(mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->otg->state)); - - spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->otg->state) { - case OTG_STATE_A_WAIT_BCON: - devctl &= ~MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } else { - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - } - break; - case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG, - MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT); - break; - case OTG_STATE_B_IDLE: - devctl = musb_readb(mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - else - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - break; - default: - break; - } - spin_unlock_irqrestore(&musb->lock, flags); -} - -static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) -{ - static unsigned long last_timer; - - if (timeout == 0) - timeout = jiffies + msecs_to_jiffies(3); - - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || (musb->a_wait_bcon == 0 && - musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { - dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->otg->state)); - del_timer(&musb->dev_timer); - last_timer = jiffies; - return; - } - - if (time_after(last_timer, timeout) && timer_pending(&musb->dev_timer)) { - dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n"); - return; - } - last_timer = timeout; - - dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - usb_otg_state_string(musb->xceiv->otg->state), - jiffies_to_msecs(timeout - jiffies)); - mod_timer(&musb->dev_timer, timeout); -} - -static irqreturn_t am35x_musb_interrupt(int irq, void *hci) -{ - struct musb *musb = hci; - void __iomem *reg_base = musb->ctrl_base; - struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - unsigned long flags; - irqreturn_t ret = IRQ_NONE; - u32 epintr, usbintr; - - spin_lock_irqsave(&musb->lock, flags); - - /* Get endpoint interrupts */ - epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG); - - if (epintr) { - musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr); - - musb->int_rx = - (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT; - musb->int_tx = - (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT; - } - - /* Get usb core interrupts */ - usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG); - if (!usbintr && !epintr) - goto eoi; - - if (usbintr) { - musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr); - - musb->int_usb = - (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT; - } - /* - * DRVVBUS IRQs are the only proxy we have (a very poor one!) for - * AM35x's missing ID change IRQ. We need an ID change IRQ to - * switch appropriately between halves of the OTG state machine. - * Managing DEVCTL.SESSION per Mentor docs requires that we know its - * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. - * Also, DRVVBUS pulses for SRP (but not at 5V) ... - */ - if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) { - int drvvbus = musb_readl(reg_base, USB_STAT_REG); - void __iomem *mregs = musb->mregs; - u8 devctl = musb_readb(mregs, MUSB_DEVCTL); - int err; - - err = musb->int_usb & MUSB_INTR_VBUSERROR; - if (err) { - /* - * The Mentor core doesn't debounce VBUS as needed - * to cope with device connect current spikes. This - * means it's not uncommon for bus-powered devices - * to get VBUS errors during enumeration. - * - * This is a workaround, but newer RTL from Mentor - * seems to allow a better one: "re"-starting sessions - * without waiting for VBUS to stop registering in - * devctl. - */ - musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - WARNING("VBUS error workaround (delay coming)\n"); - } else if (drvvbus) { - MUSB_HST_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - portstate(musb->port1_status |= USB_PORT_STAT_POWER); - del_timer(&musb->dev_timer); - } else { - musb->is_active = 0; - MUSB_DEV_MODE(musb); - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); - } - - /* NOTE: this must complete power-on within 100 ms. */ - dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", - drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->otg->state), - err ? " ERROR" : "", - devctl); - ret = IRQ_HANDLED; - } - - /* Drop spurious RX and TX if device is disconnected */ - if (musb->int_usb & MUSB_INTR_DISCONNECT) { - musb->int_tx = 0; - musb->int_rx = 0; - } - - if (musb->int_tx || musb->int_rx || musb->int_usb) - ret |= musb_interrupt(musb); - -eoi: - /* EOI needs to be written for the IRQ to be re-asserted. */ - if (ret == IRQ_HANDLED || epintr || usbintr) { - /* clear level interrupt */ - if (data->clear_irq) - data->clear_irq(); - /* write EOI */ - musb_writel(reg_base, USB_END_OF_INTR_REG, 0); - } - - /* Poll for ID change */ - if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) - mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ); - - spin_unlock_irqrestore(&musb->lock, flags); - - return ret; -} - -static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode) -{ - struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - int retval = 0; - - if (data->set_mode) - data->set_mode(musb_mode); - else - retval = -EIO; - - return retval; -} - -static int am35x_musb_init(struct musb *musb) -{ - struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - void __iomem *reg_base = musb->ctrl_base; - u32 rev; - - musb->mregs += USB_MENTOR_CORE_OFFSET; - - /* Returns zero if e.g. not clocked */ - rev = musb_readl(reg_base, USB_REVISION_REG); - if (!rev) - return -ENODEV; - - musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(musb->xceiv)) - return -EPROBE_DEFER; - - timer_setup(&musb->dev_timer, otg_timer, 0); - - /* Reset the musb */ - if (data->reset) - data->reset(); - - /* Reset the controller */ - musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); - - /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(1); - - msleep(5); - - musb->isr = am35x_musb_interrupt; - - /* clear level interrupt */ - if (data->clear_irq) - data->clear_irq(); - - return 0; -} - -static int am35x_musb_exit(struct musb *musb) -{ - struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - - del_timer_sync(&musb->dev_timer); - - /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(0); - - usb_put_phy(musb->xceiv); - - return 0; -} - -/* AM35x supports only 32bit read operation */ -static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) -{ - void __iomem *fifo = hw_ep->fifo; - u32 val; - int i; - - /* Read for 32bit-aligned destination address */ - if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) { - readsl(fifo, dst, len >> 2); - dst += len & ~0x03; - len &= 0x03; - } - /* - * Now read the remaining 1 to 3 byte or complete length if - * unaligned address. - */ - if (len > 4) { - for (i = 0; i < (len >> 2); i++) { - *(u32 *) dst = musb_readl(fifo, 0); - dst += 4; - } - len &= 0x03; - } - if (len > 0) { - val = musb_readl(fifo, 0); - memcpy(dst, &val, len); - } -} - -static const struct musb_platform_ops am35x_ops = { - .quirks = MUSB_DMA_INVENTRA | MUSB_INDEXED_EP, - .init = am35x_musb_init, - .exit = am35x_musb_exit, - - .read_fifo = am35x_read_fifo, -#ifdef CONFIG_USB_INVENTRA_DMA - .dma_init = musbhs_dma_controller_create, - .dma_exit = musbhs_dma_controller_destroy, -#endif - .enable = am35x_musb_enable, - .disable = am35x_musb_disable, - - .set_mode = am35x_musb_set_mode, - .try_idle = am35x_musb_try_idle, - - .set_vbus = am35x_musb_set_vbus, -}; - -static const struct platform_device_info am35x_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; - -static int am35x_probe(struct platform_device *pdev) -{ - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct am35x_glue *glue; - struct platform_device_info pinfo; - struct clk *phy_clk; - struct clk *clk; - - int ret = -ENOMEM; - - glue = kzalloc(sizeof(*glue), GFP_KERNEL); - if (!glue) - goto err0; - - phy_clk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(phy_clk)) { - dev_err(&pdev->dev, "failed to get PHY clock\n"); - ret = PTR_ERR(phy_clk); - goto err3; - } - - clk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); - ret = PTR_ERR(clk); - goto err4; - } - - ret = clk_enable(phy_clk); - if (ret) { - dev_err(&pdev->dev, "failed to enable PHY clock\n"); - goto err5; - } - - ret = clk_enable(clk); - if (ret) { - dev_err(&pdev->dev, "failed to enable clock\n"); - goto err6; - } - - glue->dev = &pdev->dev; - glue->phy_clk = phy_clk; - glue->clk = clk; - - pdata->platform_ops = &am35x_ops; - - glue->phy = usb_phy_generic_register(); - if (IS_ERR(glue->phy)) { - ret = PTR_ERR(glue->phy); - goto err7; - } - platform_set_drvdata(pdev, glue); - - pinfo = am35x_dev_info; - pinfo.parent = &pdev->dev; - pinfo.res = pdev->resource; - pinfo.num_res = pdev->num_resources; - pinfo.data = pdata; - pinfo.size_data = sizeof(*pdata); - pinfo.fwnode = of_fwnode_handle(pdev->dev.of_node); - pinfo.of_node_reused = true; - - glue->musb = musb = platform_device_register_full(&pinfo); - if (IS_ERR(musb)) { - ret = PTR_ERR(musb); - dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err8; - } - - return 0; - -err8: - usb_phy_generic_unregister(glue->phy); - -err7: - clk_disable(clk); - -err6: - clk_disable(phy_clk); - -err5: - clk_put(clk); - -err4: - clk_put(phy_clk); - -err3: - kfree(glue); - -err0: - return ret; -} - -static int am35x_remove(struct platform_device *pdev) -{ - struct am35x_glue *glue = platform_get_drvdata(pdev); - - platform_device_unregister(glue->musb); - usb_phy_generic_unregister(glue->phy); - clk_disable(glue->clk); - clk_disable(glue->phy_clk); - clk_put(glue->clk); - clk_put(glue->phy_clk); - kfree(glue); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int am35x_suspend(struct device *dev) -{ - struct am35x_glue *glue = dev_get_drvdata(dev); - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - - /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(0); - - clk_disable(glue->phy_clk); - clk_disable(glue->clk); - - return 0; -} - -static int am35x_resume(struct device *dev) -{ - struct am35x_glue *glue = dev_get_drvdata(dev); - struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); - struct omap_musb_board_data *data = plat->board_data; - int ret; - - /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(1); - - ret = clk_enable(glue->phy_clk); - if (ret) { - dev_err(dev, "failed to enable PHY clock\n"); - return ret; - } - - ret = clk_enable(glue->clk); - if (ret) { - dev_err(dev, "failed to enable clock\n"); - return ret; - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume); - -static struct platform_driver am35x_driver = { - .probe = am35x_probe, - .remove = am35x_remove, - .driver = { - .name = "musb-am35x", - .pm = &am35x_pm_ops, - }, -}; - -MODULE_DESCRIPTION("AM35x MUSB Glue Layer"); -MODULE_AUTHOR("Ajay Kumar Gupta "); -MODULE_LICENSE("GPL v2"); -module_platform_driver(am35x_driver); -- GitLab From ae423ef5d095e09970f52c08020fdbf7f9d87c22 Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Tue, 22 Nov 2022 03:51:38 -0500 Subject: [PATCH 1225/1480] usb: cdnsp: fix lack of ZLP for ep0 Patch implements the handling of ZLP for control transfer. To send the ZLP driver must prepare the extra TRB in TD with length set to zero and TRB type to TRB_NORMAL. The first TRB must have set TRB_CHAIN flag, TD_SIZE = 1 and TRB type to TRB_DATA. Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") cc: Reviewed-by: Peter Chen Signed-off-by: Pawel Laszczak Link: https://lore.kernel.org/r/20221122085138.332434-1-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdnsp-ring.c | 42 ++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c index 2f29431f612e0..b23e543b3a3d5 100644 --- a/drivers/usb/cdns3/cdnsp-ring.c +++ b/drivers/usb/cdns3/cdnsp-ring.c @@ -2006,10 +2006,11 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) { - u32 field, length_field, remainder; + u32 field, length_field, zlp = 0; struct cdnsp_ep *pep = preq->pep; struct cdnsp_ring *ep_ring; int num_trbs; + u32 maxp; int ret; ep_ring = cdnsp_request_to_transfer_ring(pdev, preq); @@ -2019,26 +2020,33 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) /* 1 TRB for data, 1 for status */ num_trbs = (pdev->three_stage_setup) ? 2 : 1; + maxp = usb_endpoint_maxp(pep->endpoint.desc); + + if (preq->request.zero && preq->request.length && + (preq->request.length % maxp == 0)) { + num_trbs++; + zlp = 1; + } + ret = cdnsp_prepare_transfer(pdev, preq, num_trbs); if (ret) return ret; /* If there's data, queue data TRBs */ - if (pdev->ep0_expect_in) - field = TRB_TYPE(TRB_DATA) | TRB_IOC; - else - field = TRB_ISP | TRB_TYPE(TRB_DATA) | TRB_IOC; - if (preq->request.length > 0) { - remainder = cdnsp_td_remainder(pdev, 0, preq->request.length, - preq->request.length, preq, 1, 0); + field = TRB_TYPE(TRB_DATA); - length_field = TRB_LEN(preq->request.length) | - TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0); + if (zlp) + field |= TRB_CHAIN; + else + field |= TRB_IOC | (pdev->ep0_expect_in ? 0 : TRB_ISP); if (pdev->ep0_expect_in) field |= TRB_DIR_IN; + length_field = TRB_LEN(preq->request.length) | + TRB_TD_SIZE(zlp) | TRB_INTR_TARGET(0); + cdnsp_queue_trb(pdev, ep_ring, true, lower_32_bits(preq->request.dma), upper_32_bits(preq->request.dma), length_field, @@ -2046,6 +2054,20 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) TRB_SETUPID(pdev->setup_id) | pdev->setup_speed); + if (zlp) { + field = TRB_TYPE(TRB_NORMAL) | TRB_IOC; + + if (!pdev->ep0_expect_in) + field = TRB_ISP; + + cdnsp_queue_trb(pdev, ep_ring, true, + lower_32_bits(preq->request.dma), + upper_32_bits(preq->request.dma), 0, + field | ep_ring->cycle_state | + TRB_SETUPID(pdev->setup_id) | + pdev->setup_speed); + } + pdev->ep0_stage = CDNSP_DATA_STAGE; } -- GitLab From 22683e480b370ad1b3a34cfa461028d1f51da12d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 27 Nov 2022 15:52:30 +0100 Subject: [PATCH 1226/1480] usb: misc: onboard_usb_hub: Drop obsolete dependency on COMPILE_TEST Since commit 0166dc11be91 ("of: make CONFIG_OF user selectable"), it is possible to test-build any driver which depends on OF on any architecture by explicitly selecting OF. Therefore depending on COMPILE_TEST as an alternative is no longer needed. It is actually better to always build such drivers with OF enabled, so that the test builds are closer to how each driver will actually be built on its intended target. Building them without OF may not test much as the compiler will optimize out potentially large parts of the code. In the worst case, this could even pop false positive warnings. Dropping COMPILE_TEST here improves the quality of our testing and avoids wasting time on non-existent issues. Cc: Matthias Kaehlcke Cc: Greg Kroah-Hartman Signed-off-by: Jean Delvare Link: https://lore.kernel.org/r/20221127155230.144886b7@endymion.delvare Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 9367c12c7e6f8..a5f7652db7da1 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -298,7 +298,7 @@ config BRCM_USB_PINMAP config USB_ONBOARD_HUB tristate "Onboard USB hub support" - depends on OF || COMPILE_TEST + depends on OF help Say Y here if you want to support discrete onboard USB hubs that don't require an additional control bus for initialization, but -- GitLab From 49b42475dd8a9fddbb2f3dc17ff6e4b115c80bfb Mon Sep 17 00:00:00 2001 From: Allen-KH Cheng Date: Wed, 23 Nov 2022 21:55:27 +0800 Subject: [PATCH 1227/1480] dt-bindings: usb: mtu3: add compatible for mt8186 Add a new compatible for mt8186 SoC. Signed-off-by: Allen-KH Cheng Link: https://lore.kernel.org/r/20221123135531.23221-2-allen-kh.cheng@mediatek.com Acked-by: Krzysztof Kozlowski Reviewed-by: Matthias Brugger Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml index 80750b0f458a8..7168110e2f9de 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.yaml @@ -24,6 +24,7 @@ properties: - mediatek,mt2712-mtu3 - mediatek,mt8173-mtu3 - mediatek,mt8183-mtu3 + - mediatek,mt8186-mtu3 - mediatek,mt8188-mtu3 - mediatek,mt8192-mtu3 - mediatek,mt8195-mtu3 -- GitLab From 89ff3dfac604614287ad5aad9370c3f984ea3f4b Mon Sep 17 00:00:00 2001 From: John Keeping Date: Tue, 22 Nov 2022 12:35:21 +0000 Subject: [PATCH 1228/1480] usb: gadget: f_hid: fix f_hidg lifetime vs cdev The embedded struct cdev does not have its lifetime correctly tied to the enclosing struct f_hidg, so there is a use-after-free if /dev/hidgN is held open while the gadget is deleted. This can readily be replicated with libusbgx's example programs (for conciseness - operating directly via configfs is equivalent): gadget-hid exec 3<> /dev/hidg0 gadget-vid-pid-remove exec 3<&- Pull the existing device up in to struct f_hidg and make use of the cdev_device_{add,del}() helpers. This changes the lifetime of the device object to match struct f_hidg, but note that it is still added and deleted at the same time. Fixes: 71adf1189469 ("USB: gadget: add HID gadget driver") Tested-by: Lee Jones Reviewed-by: Andrzej Pietrasiewicz Reviewed-by: Lee Jones Signed-off-by: John Keeping Link: https://lore.kernel.org/r/20221122123523.3068034-2-john@metanate.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_hid.c | 52 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index ca0a7d9eaa34e..8b8bbeaa27cb8 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -71,7 +71,7 @@ struct f_hidg { wait_queue_head_t write_queue; struct usb_request *req; - int minor; + struct device dev; struct cdev cdev; struct usb_function func; @@ -84,6 +84,14 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f) return container_of(f, struct f_hidg, func); } +static void hidg_release(struct device *dev) +{ + struct f_hidg *hidg = container_of(dev, struct f_hidg, dev); + + kfree(hidg->set_report_buf); + kfree(hidg); +} + /*-------------------------------------------------------------------------*/ /* Static descriptors */ @@ -904,9 +912,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) struct usb_ep *ep; struct f_hidg *hidg = func_to_hidg(f); struct usb_string *us; - struct device *device; int status; - dev_t dev; /* maybe allocate device-global string IDs, and patch descriptors */ us = usb_gstrings_attach(c->cdev, ct_func_strings, @@ -999,21 +1005,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) /* create char device */ cdev_init(&hidg->cdev, &f_hidg_fops); - dev = MKDEV(major, hidg->minor); - status = cdev_add(&hidg->cdev, dev, 1); + status = cdev_device_add(&hidg->cdev, &hidg->dev); if (status) goto fail_free_descs; - device = device_create(hidg_class, NULL, dev, NULL, - "%s%d", "hidg", hidg->minor); - if (IS_ERR(device)) { - status = PTR_ERR(device); - goto del; - } - return 0; -del: - cdev_del(&hidg->cdev); fail_free_descs: usb_free_all_descriptors(f); fail: @@ -1244,9 +1240,7 @@ static void hidg_free(struct usb_function *f) hidg = func_to_hidg(f); opts = container_of(f->fi, struct f_hid_opts, func_inst); - kfree(hidg->report_desc); - kfree(hidg->set_report_buf); - kfree(hidg); + put_device(&hidg->dev); mutex_lock(&opts->lock); --opts->refcnt; mutex_unlock(&opts->lock); @@ -1256,8 +1250,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_hidg *hidg = func_to_hidg(f); - device_destroy(hidg_class, MKDEV(major, hidg->minor)); - cdev_del(&hidg->cdev); + cdev_device_del(&hidg->cdev, &hidg->dev); usb_free_all_descriptors(f); } @@ -1266,6 +1259,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) { struct f_hidg *hidg; struct f_hid_opts *opts; + int ret; /* allocate and initialize one new instance */ hidg = kzalloc(sizeof(*hidg), GFP_KERNEL); @@ -1277,17 +1271,27 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) mutex_lock(&opts->lock); ++opts->refcnt; - hidg->minor = opts->minor; + device_initialize(&hidg->dev); + hidg->dev.release = hidg_release; + hidg->dev.class = hidg_class; + hidg->dev.devt = MKDEV(major, opts->minor); + ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor); + if (ret) { + --opts->refcnt; + mutex_unlock(&opts->lock); + return ERR_PTR(ret); + } + hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol; hidg->report_length = opts->report_length; hidg->report_desc_length = opts->report_desc_length; if (opts->report_desc) { - hidg->report_desc = kmemdup(opts->report_desc, - opts->report_desc_length, - GFP_KERNEL); + hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc, + opts->report_desc_length, + GFP_KERNEL); if (!hidg->report_desc) { - kfree(hidg); + put_device(&hidg->dev); mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); } -- GitLab From 70a3288a7586526315105c699b687d78cd32559a Mon Sep 17 00:00:00 2001 From: John Keeping Date: Tue, 22 Nov 2022 12:35:22 +0000 Subject: [PATCH 1229/1480] usb: gadget: f_hid: fix refcount leak on error path When failing to allocate report_desc, opts->refcnt has already been incremented so it needs to be decremented to avoid leaving the options structure permanently locked. Fixes: 21a9476a7ba8 ("usb: gadget: hid: add configfs support") Tested-by: Lee Jones Reviewed-by: Andrzej Pietrasiewicz Reviewed-by: Lee Jones Signed-off-by: John Keeping Link: https://lore.kernel.org/r/20221122123523.3068034-3-john@metanate.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_hid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 8b8bbeaa27cb8..6be6009f911e1 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -1292,6 +1292,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) GFP_KERNEL); if (!hidg->report_desc) { put_device(&hidg->dev); + --opts->refcnt; mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); } -- GitLab From 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Tue, 22 Nov 2022 12:35:23 +0000 Subject: [PATCH 1230/1480] usb: gadget: f_hid: tidy error handling in hidg_alloc Unify error handling at the end of the function, reducing the risk of missing something on one of the error paths. Moving the increment of opts->refcnt later means there is no need to decrement it on the error path and is safe as this is guarded by opts->lock which is held for this entire section. Tested-by: Lee Jones Reviewed-by: Andrzej Pietrasiewicz Reviewed-by: Lee Jones Signed-off-by: John Keeping Link: https://lore.kernel.org/r/20221122123523.3068034-4-john@metanate.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_hid.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6be6009f911e1..a8da3b4a2855a 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -1269,18 +1269,14 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_hid_opts, func_inst); mutex_lock(&opts->lock); - ++opts->refcnt; device_initialize(&hidg->dev); hidg->dev.release = hidg_release; hidg->dev.class = hidg_class; hidg->dev.devt = MKDEV(major, opts->minor); ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor); - if (ret) { - --opts->refcnt; - mutex_unlock(&opts->lock); - return ERR_PTR(ret); - } + if (ret) + goto err_unlock; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol; @@ -1291,14 +1287,13 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts->report_desc_length, GFP_KERNEL); if (!hidg->report_desc) { - put_device(&hidg->dev); - --opts->refcnt; - mutex_unlock(&opts->lock); - return ERR_PTR(-ENOMEM); + ret = -ENOMEM; + goto err_put_device; } } hidg->use_out_ep = !opts->no_out_endpoint; + ++opts->refcnt; mutex_unlock(&opts->lock); hidg->func.name = "hid"; @@ -1313,6 +1308,12 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) hidg->qlen = 4; return &hidg->func; + +err_put_device: + put_device(&hidg->dev); +err_unlock: + mutex_unlock(&opts->lock); + return ERR_PTR(ret); } DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc); -- GitLab From a9efc04cfd05690e91279f41c2325c46335c43ef Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 23 Nov 2022 16:48:58 +0200 Subject: [PATCH 1231/1480] i915: Move list_count() to list.h for broader use Some of the existing users, and definitely will be new ones, want to count existing nodes in the list. Provide a generic API for that by moving code from i915 to list.h. Reviewed-by: Lucas De Marchi Acked-by: Jani Nikula Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221123144901.40493-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 13 +------------ include/linux/list.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 1f7188129cd1f..47734c4ebfa01 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -2004,17 +2004,6 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq) } } -static unsigned long list_count(struct list_head *list) -{ - struct list_head *pos; - unsigned long count = 0; - - list_for_each(pos, list) - count++; - - return count; -} - static unsigned long read_ul(void *p, size_t x) { return *(unsigned long *)(p + x); @@ -2189,7 +2178,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, spin_lock_irqsave(&engine->sched_engine->lock, flags); engine_dump_active_requests(engine, m); - drm_printf(m, "\tOn hold?: %lu\n", + drm_printf(m, "\tOn hold?: %zu\n", list_count(&engine->sched_engine->hold)); spin_unlock_irqrestore(&engine->sched_engine->lock, flags); diff --git a/include/linux/list.h b/include/linux/list.h index 61762054b4be9..632a298c7018c 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -655,6 +655,21 @@ static inline void list_splice_tail_init(struct list_head *list, !list_is_head(pos, (head)); \ pos = n, n = pos->prev) +/** + * list_count - count nodes in the list + * @head: the head for your list. + */ +static inline size_t list_count(struct list_head *head) +{ + struct list_head *pos; + size_t count = 0; + + list_for_each(pos, head) + count++; + + return count; +} + /** * list_entry_is_head - test if the entry points to the head of the list * @pos: the type * to cursor -- GitLab From 33f00f41d963c86176dba2f9faff9b428a542e60 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 23 Nov 2022 16:48:59 +0200 Subject: [PATCH 1232/1480] usb: gadget: hid: Convert to use list_count() The list API now provides the list_count() to help with counting existing nodes in the list. Utilise it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221123144901.40493-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/hid.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 1187ee4f316ab..6196c3456e0be 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -133,14 +133,11 @@ static struct usb_configuration config_driver = { static int hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; - struct list_head *tmp; struct hidg_func_node *n = NULL, *m, *iter_n; struct f_hid_opts *hid_opts; - int status, funcs = 0; - - list_for_each(tmp, &hidg_func_list) - funcs++; + int status, funcs; + funcs = list_count(&hidg_func_list); if (!funcs) return -ENODEV; -- GitLab From c2d9d02f7bf3c641f9b8e6c9f5de1e564cdeca69 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 23 Nov 2022 16:49:00 +0200 Subject: [PATCH 1233/1480] usb: gadget: udc: bcm63xx: Convert to use list_count() The list API now provides the list_count() to help with counting existing nodes in the list. Utilise it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221123144901.40493-3-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/bcm63xx_udc.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 2cdb07905bdeb..0762e49e85f85 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2172,7 +2172,6 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) for (ch_idx = 0; ch_idx < BCM63XX_NUM_IUDMA; ch_idx++) { struct iudma_ch *iudma = &udc->iudma[ch_idx]; - struct list_head *pos; seq_printf(s, "IUDMA channel %d -- ", ch_idx); switch (iudma_defaults[ch_idx].ep_type) { @@ -2205,14 +2204,10 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, iudma->n_bds); - if (iudma->bep) { - i = 0; - list_for_each(pos, &iudma->bep->queue) - i++; - seq_printf(s, "; %d queued\n", i); - } else { + if (iudma->bep) + seq_printf(s, "; %zu queued\n", list_count(&iudma->bep->queue)); + else seq_printf(s, "\n"); - } for (i = 0; i < iudma->n_bds; i++) { struct bcm_enet_desc *d = &iudma->bd_ring[i]; -- GitLab From b47ec9727f47d1dce4e8cbc9aef01c80b2332535 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 23 Nov 2022 16:49:01 +0200 Subject: [PATCH 1234/1480] xhci: Convert to use list_count() The list API now provides the list_count() to help with counting existing nodes in the list. Utilise it. Acked-by: Mathias Nyman Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221123144901.40493-4-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index ad81e9a508b14..817c31e3b0c8b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2532,7 +2532,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, union xhci_trb *ep_trb; int status = -EINPROGRESS; struct xhci_ep_ctx *ep_ctx; - struct list_head *tmp; u32 trb_comp_code; int td_num = 0; bool handling_skipped_tds = false; @@ -2580,10 +2579,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, } /* Count current td numbers if ep->skip is set */ - if (ep->skip) { - list_for_each(tmp, &ep_ring->td_list) - td_num++; - } + if (ep->skip) + td_num += list_count(&ep_ring->td_list); /* Look for common error cases */ switch (trb_comp_code) { -- GitLab From fb12940f51d96ead10f9c0fd578e69b8de10ca81 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 28 Nov 2022 18:35:39 +0100 Subject: [PATCH 1235/1480] driver core: fix up some missing class.devnode() conversions. In commit ff62b8e6588f ("driver core: make struct class.devnode() take a const *") the ->devnode callback changed the pointer to be const, but a few instances of PowerPC drivers were not caught for some reason. Fix this up by changing the pointers to be const. Fixes: ff62b8e6588f ("driver core: make struct class.devnode() take a const *") Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Frederic Barrat Cc: Andrew Donnellan Cc: Arnd Bergmann Cc: linuxppc-dev@lists.ozlabs.org Reported-by: Stephen Rothwell Link: https://lore.kernel.org/r/20221128173539.3112234-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/book3s/vas-api.c | 2 +- drivers/misc/cxl/file.c | 2 +- drivers/misc/ocxl/file.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c index 40f5ae5e1238d..eb5bed3337503 100644 --- a/arch/powerpc/platforms/book3s/vas-api.c +++ b/arch/powerpc/platforms/book3s/vas-api.c @@ -53,7 +53,7 @@ struct coproc_instance { struct vas_window *txwin; }; -static char *coproc_devnode(struct device *dev, umode_t *mode) +static char *coproc_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "crypto/%s", dev_name(dev)); } diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 3dbdce96fae0d..5878329b011a0 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -546,7 +546,7 @@ static const struct file_operations afu_master_fops = { }; -static char *cxl_devnode(struct device *dev, umode_t *mode) +static char *cxl_devnode(const struct device *dev, umode_t *mode) { if (cpu_has_feature(CPU_FTR_HVMODE) && CXL_DEVT_IS_CARD(dev->devt)) { diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index d46dba2df5a10..d96be36405a03 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -581,7 +581,7 @@ void ocxl_file_unregister_afu(struct ocxl_afu *afu) device_unregister(&info->dev); } -static char *ocxl_devnode(struct device *dev, umode_t *mode) +static char *ocxl_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "ocxl/%s", dev_name(dev)); } -- GitLab From 62c73bfea048e66168df09da6d3e4510ecda40bb Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 28 Nov 2022 17:15:26 +0100 Subject: [PATCH 1236/1480] usb: dwc3: Fix race between dwc3_set_mode and __dwc3_set_mode dwc->desired_dr_role is changed by dwc3_set_mode inside a spinlock but then read by __dwc3_set_mode outside of that lock. This can lead to a race condition when very quick successive role switch events happen: CPU A dwc3_set_mode(DWC3_GCTL_PRTCAP_HOST) // first role switch event spin_lock_irqsave(&dwc->lock, flags); dwc->desired_dr_role = mode; // DWC3_GCTL_PRTCAP_HOST spin_unlock_irqrestore(&dwc->lock, flags); queue_work(system_freezable_wq, &dwc->drd_work); CPU B __dwc3_set_mode // .... spin_lock_irqsave(&dwc->lock, flags); // desired_dr_role is DWC3_GCTL_PRTCAP_HOST dwc3_set_prtcap(dwc, dwc->desired_dr_role); spin_unlock_irqrestore(&dwc->lock, flags); CPU A dwc3_set_mode(DWC3_GCTL_PRTCAP_DEVICE) // second event spin_lock_irqsave(&dwc->lock, flags); dwc->desired_dr_role = mode; // DWC3_GCTL_PRTCAP_DEVICE spin_unlock_irqrestore(&dwc->lock, flags); CPU B (continues running __dwc3_set_mode) switch (dwc->desired_dr_role) { // DWC3_GCTL_PRTCAP_DEVICE // .... case DWC3_GCTL_PRTCAP_DEVICE: // .... ret = dwc3_gadget_init(dwc); We then have DWC3_GCTL.DWC3_GCTL_PRTCAPDIR = DWC3_GCTL_PRTCAP_HOST and dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST but initialized the controller in device mode. It's also possible to get into a state where both host and device are intialized at the same time. Fix this race by creating a local copy of desired_dr_role inside __dwc3_set_mode while holding dwc->lock. Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") Cc: stable Acked-by: Thinh Nguyen Signed-off-by: Sven Peter Link: https://lore.kernel.org/r/20221128161526.79730-1-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1f348bc867c22..fc38a8b13efa6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -122,21 +122,25 @@ static void __dwc3_set_mode(struct work_struct *work) unsigned long flags; int ret; u32 reg; + u32 desired_dr_role; mutex_lock(&dwc->mutex); + spin_lock_irqsave(&dwc->lock, flags); + desired_dr_role = dwc->desired_dr_role; + spin_unlock_irqrestore(&dwc->lock, flags); pm_runtime_get_sync(dwc->dev); if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) dwc3_otg_update(dwc, 0); - if (!dwc->desired_dr_role) + if (!desired_dr_role) goto out; - if (dwc->desired_dr_role == dwc->current_dr_role) + if (desired_dr_role == dwc->current_dr_role) goto out; - if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) + if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) goto out; switch (dwc->current_dr_role) { @@ -164,7 +168,7 @@ static void __dwc3_set_mode(struct work_struct *work) */ if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && - dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { + desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); @@ -184,11 +188,11 @@ static void __dwc3_set_mode(struct work_struct *work) spin_lock_irqsave(&dwc->lock, flags); - dwc3_set_prtcap(dwc, dwc->desired_dr_role); + dwc3_set_prtcap(dwc, desired_dr_role); spin_unlock_irqrestore(&dwc->lock, flags); - switch (dwc->desired_dr_role) { + switch (desired_dr_role) { case DWC3_GCTL_PRTCAP_HOST: ret = dwc3_host_init(dwc); if (ret) { -- GitLab From d03a6d4e2beaa358b6c4e16fe106e813a57e927a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Nov 2022 15:15:39 +0100 Subject: [PATCH 1237/1480] USB: serial: cp210x: add support for B0 hangup A request to set the line speed to B0 is used to hang up a modem connection by deasserting the modem control lines. Note that there is no need reconfigure the line speed in hardware when B0 is requested (even if some drivers do set it to an arbitrary value for implementation or protocol reasons). Reviewed-by: Alex Henrie Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f6fb23620e87a..67372acc23529 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1049,11 +1049,12 @@ static void cp210x_change_speed(struct tty_struct *tty, struct cp210x_serial_private *priv = usb_get_serial_data(serial); u32 baud; + if (tty->termios.c_ospeed == 0) + return; + /* * This maps the requested rate to the actual rate, a valid rate on * cp2102 or cp2103, or to an arbitrary rate in [1M, max_speed]. - * - * NOTE: B0 is not implemented. */ baud = clamp(tty->termios.c_ospeed, priv->min_speed, priv->max_speed); @@ -1146,7 +1147,8 @@ static void cp210x_set_flow_control(struct tty_struct *tty, tty->termios.c_iflag &= ~(IXON | IXOFF); } - if (old_termios && + if (tty->termios.c_ospeed != 0 && + old_termios && old_termios->c_ospeed != 0 && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) && I_IXON(tty) == (old_termios->c_iflag & IXON) && I_IXOFF(tty) == (old_termios->c_iflag & IXOFF) && @@ -1171,6 +1173,14 @@ static void cp210x_set_flow_control(struct tty_struct *tty, mutex_lock(&port_priv->mutex); + if (tty->termios.c_ospeed == 0) { + port_priv->dtr = false; + port_priv->rts = false; + } else if (old_termios && old_termios->c_ospeed == 0) { + port_priv->dtr = true; + port_priv->rts = true; + } + ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, sizeof(flow_ctl)); if (ret) @@ -1243,7 +1253,8 @@ static void cp210x_set_termios(struct tty_struct *tty, u16 bits; int ret; - if (old_termios && !cp210x_termios_change(&tty->termios, old_termios)) + if (old_termios && !cp210x_termios_change(&tty->termios, old_termios) && + tty->termios.c_ospeed != 0) return; if (!old_termios || tty->termios.c_ospeed != old_termios->c_ospeed) -- GitLab From 33379c054211a5144ffae84e9e3c80e2e62416a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 30 Nov 2022 12:02:11 +0100 Subject: [PATCH 1238/1480] Revert "xhci: Convert to use list_count()" This reverts commit b47ec9727f47d1dce4e8cbc9aef01c80b2332535 as it breaks the build. Link: https://lore.kernel.org/r/20221130131854.35b58b16@canb.auug.org.au Link: https://lore.kernel.org/r/202211301628.iwMjPVMp-lkp@intel.com Cc: Mathias Nyman Cc: Andy Shevchenko Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 817c31e3b0c8b..ad81e9a508b14 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2532,6 +2532,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, union xhci_trb *ep_trb; int status = -EINPROGRESS; struct xhci_ep_ctx *ep_ctx; + struct list_head *tmp; u32 trb_comp_code; int td_num = 0; bool handling_skipped_tds = false; @@ -2579,8 +2580,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, } /* Count current td numbers if ep->skip is set */ - if (ep->skip) - td_num += list_count(&ep_ring->td_list); + if (ep->skip) { + list_for_each(tmp, &ep_ring->td_list) + td_num++; + } /* Look for common error cases */ switch (trb_comp_code) { -- GitLab From acebf61919199771b5d7b92c68c5b515dfcbf800 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 30 Nov 2022 12:02:12 +0100 Subject: [PATCH 1239/1480] Revert "usb: gadget: udc: bcm63xx: Convert to use list_count()" This reverts commit c2d9d02f7bf3c641f9b8e6c9f5de1e564cdeca69 as it breaks the build. Link: https://lore.kernel.org/r/20221130131854.35b58b16@canb.auug.org.au Link: https://lore.kernel.org/r/202211301628.iwMjPVMp-lkp@intel.com Cc: Andy Shevchenko Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/bcm63xx_udc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 0762e49e85f85..2cdb07905bdeb 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2172,6 +2172,7 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) for (ch_idx = 0; ch_idx < BCM63XX_NUM_IUDMA; ch_idx++) { struct iudma_ch *iudma = &udc->iudma[ch_idx]; + struct list_head *pos; seq_printf(s, "IUDMA channel %d -- ", ch_idx); switch (iudma_defaults[ch_idx].ep_type) { @@ -2204,10 +2205,14 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, iudma->n_bds); - if (iudma->bep) - seq_printf(s, "; %zu queued\n", list_count(&iudma->bep->queue)); - else + if (iudma->bep) { + i = 0; + list_for_each(pos, &iudma->bep->queue) + i++; + seq_printf(s, "; %d queued\n", i); + } else { seq_printf(s, "\n"); + } for (i = 0; i < iudma->n_bds; i++) { struct bcm_enet_desc *d = &iudma->bd_ring[i]; -- GitLab From 54aa8af53905e39a825773883914810033f4d3d3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 30 Nov 2022 12:02:13 +0100 Subject: [PATCH 1240/1480] Revert "usb: gadget: hid: Convert to use list_count()" This reverts commit 33f00f41d963c86176dba2f9faff9b428a542e60 as it breaks the build. Link: https://lore.kernel.org/r/20221130131854.35b58b16@canb.auug.org.au Link: https://lore.kernel.org/r/202211301628.iwMjPVMp-lkp@intel.com Cc: Andy Shevchenko Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/hid.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 6196c3456e0be..1187ee4f316ab 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -133,11 +133,14 @@ static struct usb_configuration config_driver = { static int hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; + struct list_head *tmp; struct hidg_func_node *n = NULL, *m, *iter_n; struct f_hid_opts *hid_opts; - int status, funcs; + int status, funcs = 0; + + list_for_each(tmp, &hidg_func_list) + funcs++; - funcs = list_count(&hidg_func_list); if (!funcs) return -ENODEV; -- GitLab From 51daa42d6b86efa366320b99e7bbe29a490ed348 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 30 Nov 2022 12:02:13 +0100 Subject: [PATCH 1241/1480] Revert "i915: Move list_count() to list.h for broader use" This reverts commit a9efc04cfd05690e91279f41c2325c46335c43ef as it breaks the build. Link: https://lore.kernel.org/r/20221130131854.35b58b16@canb.auug.org.au Link: https://lore.kernel.org/r/202211301628.iwMjPVMp-lkp@intel.com Cc: Lucas De Marchi Cc: Jani Nikula Cc: Andy Shevchenko Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 13 ++++++++++++- include/linux/list.h | 15 --------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 47734c4ebfa01..1f7188129cd1f 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -2004,6 +2004,17 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq) } } +static unsigned long list_count(struct list_head *list) +{ + struct list_head *pos; + unsigned long count = 0; + + list_for_each(pos, list) + count++; + + return count; +} + static unsigned long read_ul(void *p, size_t x) { return *(unsigned long *)(p + x); @@ -2178,7 +2189,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, spin_lock_irqsave(&engine->sched_engine->lock, flags); engine_dump_active_requests(engine, m); - drm_printf(m, "\tOn hold?: %zu\n", + drm_printf(m, "\tOn hold?: %lu\n", list_count(&engine->sched_engine->hold)); spin_unlock_irqrestore(&engine->sched_engine->lock, flags); diff --git a/include/linux/list.h b/include/linux/list.h index 632a298c7018c..61762054b4be9 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -655,21 +655,6 @@ static inline void list_splice_tail_init(struct list_head *list, !list_is_head(pos, (head)); \ pos = n, n = pos->prev) -/** - * list_count - count nodes in the list - * @head: the head for your list. - */ -static inline size_t list_count(struct list_head *head) -{ - struct list_head *pos; - size_t count = 0; - - list_for_each(pos, head) - count++; - - return count; -} - /** * list_entry_is_head - test if the entry points to the head of the list * @pos: the type * to cursor -- GitLab From 2a25e66d676dfb9b018abd503deed3d38a892dec Mon Sep 17 00:00:00 2001 From: Longfang Liu Date: Wed, 30 Nov 2022 11:19:39 +0200 Subject: [PATCH 1242/1480] xhci: print warning when HCE was set When HCE(Host Controller Error) is set, it means that the xhci hardware controller has an error at this time, but the current xhci driver software does not log this event. By adding an HCE event detection in the xhci interrupt processing interface, a warning log is output to the system, which is convenient for system device status tracking. Signed-off-by: Longfang Liu Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index ad81e9a508b14..f6af479188e8f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3031,6 +3031,11 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) if (!(status & STS_EINT)) goto out; + if (status & STS_HCE) { + xhci_warn(xhci, "WARNING: Host Controller Error\n"); + goto out; + } + if (status & STS_FATAL) { xhci_warn(xhci, "WARNING: Host System Error\n"); xhci_halt(xhci); -- GitLab From fed70b61ef2c0aed54456db3d485b215f6cc3209 Mon Sep 17 00:00:00 2001 From: Reka Norman Date: Wed, 30 Nov 2022 11:19:40 +0200 Subject: [PATCH 1243/1480] xhci: Apply XHCI_RESET_TO_DEFAULT quirk to ADL-N ADL-N systems have the same issue as ADL-P, where a large boot firmware delay is seen if USB ports are left in U3 at shutdown. So apply the XHCI_RESET_TO_DEFAULT quirk to ADL-N as well. This patch depends on commit 34cd2db408d5 ("xhci: Add quirk to reset host back to default state at shutdown"). The issue it fixes is a ~20s boot time delay when booting from S5. It affects ADL-N devices, and ADL-N support was added starting from v5.16. Cc: stable@vger.kernel.org Signed-off-by: Reka Norman Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index a29b681b562e4..1fb773ed37279 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -59,6 +59,7 @@ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed +#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 @@ -246,7 +247,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_MISSING_CAS; if (pdev->vendor == PCI_VENDOR_ID_INTEL && - pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI) + (pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI)) xhci->quirks |= XHCI_RESET_TO_DEFAULT; if (pdev->vendor == PCI_VENDOR_ID_INTEL && -- GitLab From 705c333a7ad2003ad99d96c19a31619b19ad14b9 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 30 Nov 2022 11:19:41 +0200 Subject: [PATCH 1244/1480] xhci: export two xhci_hub functions for xhci-pci module usage some Intel Alder Lake xHC hosts on ChromeOS platforms need special workarounds touching port registers at xHC pci host hibernate. Export xhci_port_state_to_neutral() and xhci_find_slot_id_by_port() so they can be called from xhci-pci.c and thus the xhci-pci module. Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4619d5e89d5be..94c94db3faf6d 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -426,24 +426,37 @@ static unsigned int xhci_port_speed(unsigned int port_status) */ #define XHCI_PORT_RZ ((1<<2) | (1<<24) | (0xf<<28)) -/* +/** + * xhci_port_state_to_neutral() - Clean up read portsc value back into writeable + * @state: u32 port value read from portsc register to be cleanup up + * * Given a port state, this function returns a value that would result in the * port being in the same state, if the value was written to the port status * control register. * Save Read Only (RO) bits and save read/write bits where * writing a 0 clears the bit and writing a 1 sets the bit (RWS). * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect. + * + * Return: u32 value that can be written back to portsc register without + * changing port state. */ + u32 xhci_port_state_to_neutral(u32 state) { /* Save read-only status and port state */ return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); } +EXPORT_SYMBOL_GPL(xhci_port_state_to_neutral); -/* - * find slot id based on port number. - * @port: The one-based port number from one of the two split roothubs. +/** + * xhci_find_slot_id_by_port() - Find slot id of a usb device on a roothub port + * @hcd: pointer to hcd of the roothub + * @xhci: pointer to xhci structure + * @port: one-based port number of the port in this roothub. + * + * Return: Slot id of the usb device connected to the root port, 0 if not found */ + int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, u16 port) { @@ -465,6 +478,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, return slot_id; } +EXPORT_SYMBOL_GPL(xhci_find_slot_id_by_port); /* * Stop device -- GitLab From c3bbacd61baace2f4fbab17012c3d149df2d50f1 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 30 Nov 2022 11:19:42 +0200 Subject: [PATCH 1245/1480] xhci: disable U3 suspended ports in S4 hibernate poweroff_late stage Disable U3 suspended ports in hibernate S4 poweroff_late for systems with XHCI_RESET_TO_DEFAULT quirk, if wakeup is not enabled. This reduces the number of self-powered usb devices from surviving in U3 suspended state into next reboot. Bootloader/firmware on these systems can't handle usb ports in U3, and will timeout, causing extra delay during reboot/restore from S4. Add pci_poweroff_late() callback to struct usb_hcd to get this done at the correct stage in hibernate. Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-5-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 13 ++++++++++ drivers/usb/host/xhci-pci.c | 52 +++++++++++++++++++++++++++++++++++++ include/linux/usb/hcd.h | 3 +++ 3 files changed, 68 insertions(+) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 9b77f49b3560c..ab2f3737764e4 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -558,6 +558,17 @@ static int hcd_pci_suspend_noirq(struct device *dev) return retval; } +static int hcd_pci_poweroff_late(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct usb_hcd *hcd = pci_get_drvdata(pci_dev); + + if (hcd->driver->pci_poweroff_late && !HCD_DEAD(hcd)) + return hcd->driver->pci_poweroff_late(hcd, device_may_wakeup(dev)); + + return 0; +} + static int hcd_pci_resume_noirq(struct device *dev) { powermac_set_asic(to_pci_dev(dev), 1); @@ -578,6 +589,7 @@ static int hcd_pci_restore(struct device *dev) #define hcd_pci_suspend NULL #define hcd_pci_suspend_noirq NULL +#define hcd_pci_poweroff_late NULL #define hcd_pci_resume_noirq NULL #define hcd_pci_resume NULL #define hcd_pci_restore NULL @@ -615,6 +627,7 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .thaw_noirq = NULL, .thaw = hcd_pci_resume, .poweroff = hcd_pci_suspend, + .poweroff_late = hcd_pci_poweroff_late, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq, .restore = hcd_pci_restore, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 1fb773ed37279..79d679b3e0760 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -622,6 +622,57 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) return retval; } +static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_port *port; + struct usb_device *udev; + unsigned int slot_id; + u32 portsc; + int i; + + /* + * Systems with XHCI_RESET_TO_DEFAULT quirk have boot firmware that + * cause significant boot delay if usb ports are in suspended U3 state + * during boot. Some USB devices survive in U3 state over S4 hibernate + * + * Disable ports that are in U3 if remote wake is not enabled for either + * host controller or connected device + */ + + if (!(xhci->quirks & XHCI_RESET_TO_DEFAULT)) + return 0; + + for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { + port = &xhci->hw_ports[i]; + portsc = readl(port->addr); + + if ((portsc & PORT_PLS_MASK) != XDEV_U3) + continue; + + slot_id = xhci_find_slot_id_by_port(port->rhub->hcd, xhci, + port->hcd_portnum + 1); + if (!slot_id || !xhci->devs[slot_id]) { + xhci_err(xhci, "No dev for slot_id %d for port %d-%d in U3\n", + slot_id, port->rhub->hcd->self.busnum, port->hcd_portnum + 1); + continue; + } + + udev = xhci->devs[slot_id]->udev; + + /* if wakeup is enabled then don't disable the port */ + if (udev->do_remote_wakeup && do_wakeup) + continue; + + xhci_dbg(xhci, "port %d-%d in U3 without wakeup, disable it\n", + port->rhub->hcd->self.busnum, port->hcd_portnum + 1); + portsc = xhci_port_state_to_neutral(portsc); + writel(portsc | PORT_PE, port->addr); + } + + return 0; +} + static void xhci_pci_shutdown(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); @@ -689,6 +740,7 @@ static int __init xhci_pci_init(void) #ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; + xhci_pci_hc_driver.pci_poweroff_late = xhci_pci_poweroff_late; xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; #endif return pci_register_driver(&xhci_pci_driver); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 78cd566ee2380..b51c07111729b 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -269,6 +269,9 @@ struct hc_driver { /* called after entering D0 (etc), before resuming the hub */ int (*pci_resume)(struct usb_hcd *hcd, bool hibernated); + /* called just before hibernate final D3 state, allows host to poweroff parts */ + int (*pci_poweroff_late)(struct usb_hcd *hcd, bool do_wakeup); + /* cleanly make HCD stop writing memory and doing I/O */ void (*stop) (struct usb_hcd *hcd); -- GitLab From a1575120972ecd7baa6af6a69e4e7ea9213bde7c Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 30 Nov 2022 11:19:43 +0200 Subject: [PATCH 1246/1480] xhci: Prevent infinite loop in transaction errors recovery for streams Make sure to also limit the amount of soft reset retries for transaction errors on streams in cases where the transaction error event doesn't point to any specific TRB. In these cases we don't know the TRB or stream ring, but we do know which endpoint had the error. To keep error counting simple and functional, move the current err_count from ring structure to endpoint structure. Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-6-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 14 ++++++++++---- drivers/usb/host/xhci.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f6af479188e8f..039ec9734fcdd 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2458,7 +2458,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, switch (trb_comp_code) { case COMP_SUCCESS: - ep_ring->err_count = 0; + ep->err_count = 0; /* handle success with untransferred data as short packet */ if (ep_trb != td->last_trb || remaining) { xhci_warn(xhci, "WARN Successful completion on short TX\n"); @@ -2484,7 +2484,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, break; case COMP_USB_TRANSACTION_ERROR: if (xhci->quirks & XHCI_NO_SOFT_RETRY || - (ep_ring->err_count++ > MAX_SOFT_RETRY) || + (ep->err_count++ > MAX_SOFT_RETRY) || le32_to_cpu(slot_ctx->tt_info) & TT_SLOT) break; @@ -2565,8 +2565,14 @@ static int handle_tx_event(struct xhci_hcd *xhci, case COMP_USB_TRANSACTION_ERROR: case COMP_INVALID_STREAM_TYPE_ERROR: case COMP_INVALID_STREAM_ID_ERROR: - xhci_handle_halted_endpoint(xhci, ep, 0, NULL, - EP_SOFT_RESET); + xhci_dbg(xhci, "Stream transaction error ep %u no id\n", + ep_index); + if (ep->err_count++ > MAX_SOFT_RETRY) + xhci_handle_halted_endpoint(xhci, ep, 0, NULL, + EP_HARD_RESET); + else + xhci_handle_halted_endpoint(xhci, ep, 0, NULL, + EP_SOFT_RESET); goto cleanup; case COMP_RING_UNDERRUN: case COMP_RING_OVERRUN: diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index cc084d9505cdf..c9f06c5e4e9d2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -933,6 +933,7 @@ struct xhci_virt_ep { * have to restore the device state to the previous state */ struct xhci_ring *new_ring; + unsigned int err_count; unsigned int ep_state; #define SET_DEQ_PENDING (1 << 0) #define EP_HALTED (1 << 1) /* For stall handling */ @@ -1627,7 +1628,6 @@ struct xhci_ring { * if we own the TRB (if we are the consumer). See section 4.9.1. */ u32 cycle_state; - unsigned int err_count; unsigned int stream_id; unsigned int num_segs; unsigned int num_trbs_free; -- GitLab From 7428a253315cefa34e6092a0119c56cb3a1c0c12 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 30 Nov 2022 11:19:44 +0200 Subject: [PATCH 1247/1480] xhci: remove unused stream_id parameter from xhci_handle_halted_endpoint() The stream_id parameter is no longer used when handling halted endpoints. Remove it Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20221130091944.2171610-7-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 039ec9734fcdd..ddc30037f9cef 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -896,7 +896,7 @@ done: } static int xhci_handle_halted_endpoint(struct xhci_hcd *xhci, - struct xhci_virt_ep *ep, unsigned int stream_id, + struct xhci_virt_ep *ep, struct xhci_td *td, enum xhci_ep_reset_type reset_type) { @@ -1110,8 +1110,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, td->status = -EPROTO; } /* reset ep, reset handler cleans up cancelled tds */ - err = xhci_handle_halted_endpoint(xhci, ep, 0, td, - reset_type); + err = xhci_handle_halted_endpoint(xhci, ep, td, reset_type); if (err) break; ep->ep_state &= ~EP_STOP_CMD_PENDING; @@ -2183,8 +2182,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, } /* Almost same procedure as for STALL_ERROR below */ xhci_clear_hub_tt_buffer(xhci, td, ep); - xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td, - EP_HARD_RESET); + xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET); return 0; case COMP_STALL_ERROR: /* @@ -2200,8 +2198,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, if (ep->ep_index != 0) xhci_clear_hub_tt_buffer(xhci, td, ep); - xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td, - EP_HARD_RESET); + xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET); return 0; /* xhci_handle_halted_endpoint marked td cancelled */ default: @@ -2490,8 +2487,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, td->status = 0; - xhci_handle_halted_endpoint(xhci, ep, ep_ring->stream_id, td, - EP_SOFT_RESET); + xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET); return 0; default: /* do nothing */ @@ -2568,10 +2564,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dbg(xhci, "Stream transaction error ep %u no id\n", ep_index); if (ep->err_count++ > MAX_SOFT_RETRY) - xhci_handle_halted_endpoint(xhci, ep, 0, NULL, + xhci_handle_halted_endpoint(xhci, ep, NULL, EP_HARD_RESET); else - xhci_handle_halted_endpoint(xhci, ep, 0, NULL, + xhci_handle_halted_endpoint(xhci, ep, NULL, EP_SOFT_RESET); goto cleanup; case COMP_RING_UNDERRUN: @@ -2755,9 +2751,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (trb_comp_code == COMP_STALL_ERROR || xhci_requires_manual_halt_cleanup(xhci, ep_ctx, trb_comp_code)) { - xhci_handle_halted_endpoint(xhci, ep, - ep_ring->stream_id, - NULL, + xhci_handle_halted_endpoint(xhci, ep, NULL, EP_HARD_RESET); } goto cleanup; @@ -2850,9 +2844,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (trb_comp_code == COMP_STALL_ERROR || xhci_requires_manual_halt_cleanup(xhci, ep_ctx, trb_comp_code)) - xhci_handle_halted_endpoint(xhci, ep, - ep_ring->stream_id, - td, EP_HARD_RESET); + xhci_handle_halted_endpoint(xhci, ep, td, + EP_HARD_RESET); goto cleanup; } -- GitLab From a08ca6ebafe615c9028c53fc4c9e6c9b2b1f2888 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Nov 2022 15:17:49 +0100 Subject: [PATCH 1248/1480] USB: serial: f81232: fix division by zero on line-speed change The driver leaves the line speed unchanged in case a requested speed is not supported. Make sure to handle the case where the current speed is B0 (hangup) without dividing by zero when determining the clock source. Fixes: 268ddb5e9b62 ("USB: serial: f81232: add high baud rate support") Cc: stable@vger.kernel.org # 5.2 Cc: Ji-Ze Hong (Peter Hong) Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/f81232.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 2dd58cd9f0ccb..891fb1fe69df7 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -130,9 +130,6 @@ static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ, static int calc_baud_divisor(speed_t baudrate, speed_t clockrate) { - if (!baudrate) - return 0; - return DIV_ROUND_CLOSEST(clockrate, baudrate); } @@ -498,9 +495,14 @@ static void f81232_set_baudrate(struct tty_struct *tty, speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE }; for (i = 0; i < ARRAY_SIZE(baud_list); ++i) { - idx = f81232_find_clk(baud_list[i]); + baudrate = baud_list[i]; + if (baudrate == 0) { + tty_encode_baud_rate(tty, 0, 0); + return; + } + + idx = f81232_find_clk(baudrate); if (idx >= 0) { - baudrate = baud_list[i]; tty_encode_baud_rate(tty, baudrate, baudrate); break; } -- GitLab From 188c9c2e0c7f4ae864113f80c40bafb394062271 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Nov 2022 15:18:19 +0100 Subject: [PATCH 1249/1480] USB: serial: f81534: fix division by zero on line-speed change The driver leaves the line speed unchanged in case a requested speed is not supported. Make sure to handle the case where the current speed is B0 (hangup) without dividing by zero when determining the clock source. Fixes: 3aacac02f385 ("USB: serial: f81534: add high baud rate support") Cc: stable@vger.kernel.org # 4.16 Cc: Ji-Ze Hong (Peter Hong) Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/f81534.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index ddfcd72eb0ae7..4083ae961be43 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -536,9 +536,6 @@ static int f81534_submit_writer(struct usb_serial_port *port, gfp_t mem_flags) static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate) { - if (!baudrate) - return 0; - /* Round to nearest divisor */ return DIV_ROUND_CLOSEST(clockrate, baudrate); } @@ -568,9 +565,14 @@ static int f81534_set_port_config(struct usb_serial_port *port, u32 baud_list[] = {baudrate, old_baudrate, F81534_DEFAULT_BAUD_RATE}; for (i = 0; i < ARRAY_SIZE(baud_list); ++i) { - idx = f81534_find_clk(baud_list[i]); + baudrate = baud_list[i]; + if (baudrate == 0) { + tty_encode_baud_rate(tty, 0, 0); + return 0; + } + + idx = f81534_find_clk(baudrate); if (idx >= 0) { - baudrate = baud_list[i]; tty_encode_baud_rate(tty, baudrate, baudrate); break; } -- GitLab From 63b8ed26cd093ecc1bcdd1fd841f238a52c11031 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Nov 2022 15:18:57 +0100 Subject: [PATCH 1250/1480] USB: serial: xr: avoid requesting zero DTE rate When the requested line speed is B0 (hangup) there is no need to use the current speed in the line-coding request. This specifically avoids requesting a zero DTE rate when the current speed is B0, which could potentially confuse buggy firmware. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/xr_serial.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/serial/xr_serial.c b/drivers/usb/serial/xr_serial.c index f3811e060a441..fdb0aae546c33 100644 --- a/drivers/usb/serial/xr_serial.c +++ b/drivers/usb/serial/xr_serial.c @@ -749,8 +749,6 @@ static void xr_cdc_set_line_coding(struct tty_struct *tty, if (tty->termios.c_ospeed) lc->dwDTERate = cpu_to_le32(tty->termios.c_ospeed); - else if (old_termios) - lc->dwDTERate = cpu_to_le32(old_termios->c_ospeed); else lc->dwDTERate = cpu_to_le32(9600); -- GitLab From 69b14fde0b8dd159ba19d2b2083a0f2958a9130c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 30 Nov 2022 12:13:00 +1100 Subject: [PATCH 1251/1480] driver core: fix up missed scsi/cxlflash class.devnode() conversion. Fixes: ff62b8e6588f ("driver core: make struct class.devnode() take a const *") Link: https://lore.kernel.org/r/20221130123851.6a9f2242@canb.auug.org.au Signed-off-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/cxlflash/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index cd1324ec742de..395b00b942f70 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3857,7 +3857,7 @@ static void cxlflash_pci_resume(struct pci_dev *pdev) * * Return: Allocated string describing the devtmpfs structure. */ -static char *cxlflash_devnode(struct device *dev, umode_t *mode) +static char *cxlflash_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cxlflash/%s", dev_name(dev)); } -- GitLab From 50dc8d18f62d58a2330f08fddc069f263d191c90 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 30 Nov 2022 12:32:57 +1100 Subject: [PATCH 1252/1480] driver core: fix up missed drivers/s390/char/hmcdrv_dev.c class.devnode() conversion. Fixes: ff62b8e6588f ("driver core: make struct class.devnode() take a const *") Link: https://lore.kernel.org/r/20221130123851.6a9f2242@canb.auug.org.au Signed-off-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/hmcdrv_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c index 20e9cd542e033..cb8fdf057ecaf 100644 --- a/drivers/s390/char/hmcdrv_dev.c +++ b/drivers/s390/char/hmcdrv_dev.c @@ -90,7 +90,7 @@ static dev_t hmcdrv_dev_no; /* device number (major/minor) */ * * Return: recommended device file name in /dev */ -static char *hmcdrv_dev_name(struct device *dev, umode_t *mode) +static char *hmcdrv_dev_name(const struct device *dev, umode_t *mode) { char *nodename = NULL; const char *devname = dev_name(dev); /* kernel device name */ -- GitLab From 3d50b95b50db36de945bfc34d4d94b7e11ee8fd9 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Mon, 14 Nov 2022 11:56:06 +0000 Subject: [PATCH 1253/1480] i2c: smbus: add DDR support for SPD On my x05 laptop I got: Memory type 0x12 not supported yet, not instantiating SPD Adding the 0x12 case lead to a successful instantiated SPD AT24 EEPROM. i801_smbus 0000:00:1f.3: SMBus using polling i2c i2c-6: 2/2 memory slots populated (from DMI) at24 6-0050: 256 byte spd EEPROM, read-only i2c i2c-6: Successfully instantiated SPD at 0x50 at24 6-0051: 256 byte spd EEPROM, read-only And then, I decoded it successfully via decode-dimms. Signed-off-by: Corentin Labbe Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-smbus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 07c92c8495a3c..c85710ed95483 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -361,9 +361,15 @@ void i2c_register_spd(struct i2c_adapter *adap) return; } + /* + * Memory types could be found at section 7.18.2 (Memory Device — Type), table 78 + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf + */ switch (common_mem_type) { + case 0x12: /* DDR */ case 0x13: /* DDR2 */ case 0x18: /* DDR3 */ + case 0x1B: /* LPDDR */ case 0x1C: /* LPDDR2 */ case 0x1D: /* LPDDR3 */ name = "spd"; -- GitLab From 5bf71889ad9a4d39b7665c105a005c5a33d730ba Mon Sep 17 00:00:00 2001 From: Akhil R Date: Thu, 17 Nov 2022 15:34:15 +0530 Subject: [PATCH 1254/1480] i2c: tegra: Set ACPI node as primary fwnode Set ACPI node as the primary fwnode of I2C adapter to allow enumeration of child devices from the ACPI table Signed-off-by: Zubair Waheed Signed-off-by: Akhil R Reviewed-by: Thierry Reding Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 954022c04cc42..69c9ae161bbec 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1826,6 +1826,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) i2c_dev->adapter.class = I2C_CLASS_DEPRECATED; i2c_dev->adapter.algo = &tegra_i2c_algo; i2c_dev->adapter.nr = pdev->id; + ACPI_COMPANION_SET(&i2c_dev->adapter.dev, ACPI_COMPANION(&pdev->dev)); if (i2c_dev->hw->supports_bus_clear) i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info; -- GitLab From de917701da5d5ccb31825dca850ac49399e0f289 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 15 Nov 2022 12:30:18 +0000 Subject: [PATCH 1255/1480] dt-bindings: i2c: renesas,riic: Document RZ/Five SoC The RIIC block on the RZ/Five SoC is identical to one found on the RZ/G2UL SoC. "renesas,riic-r9a07g043" compatible string will be used on the RZ/Five SoC so to make this clear, update the comment to include RZ/Five SoC. No driver changes are required as generic compatible string "renesas,riic-rz" will be used as a fallback on RZ/Five SoC. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/renesas,riic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml index d3c0d5c427acb..2291a7cd619be 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml +++ b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml @@ -19,7 +19,7 @@ properties: - enum: - renesas,riic-r7s72100 # RZ/A1H - renesas,riic-r7s9210 # RZ/A2M - - renesas,riic-r9a07g043 # RZ/G2UL + - renesas,riic-r9a07g043 # RZ/G2UL and RZ/Five - renesas,riic-r9a07g044 # RZ/G2{L,LC} - renesas,riic-r9a07g054 # RZ/V2L - const: renesas,riic-rz # RZ/A or RZ/G2L -- GitLab From d7237462561fcd224fa687c56ccb68629f50fc0d Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Fri, 2 Dec 2022 01:38:49 -0800 Subject: [PATCH 1256/1480] drivers: mcb: fix resource leak in mcb_probe() When probe hook function failed in mcb_probe(), it doesn't put the device. Compiled test only. Fixes: 7bc364097a89 ("mcb: Acquire reference to device in probe") Signed-off-by: Zhengchao Shao Signed-off-by: Johannes Thumshirn Link: https://lore.kernel.org/r/9f87de36bfb85158b506cb78c6fc9db3f6a3bad1.1669624063.git.johannes.thumshirn@wdc.com Signed-off-by: Greg Kroah-Hartman --- drivers/mcb/mcb-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c index 338fc889b357a..b8ad4f16b4acd 100644 --- a/drivers/mcb/mcb-core.c +++ b/drivers/mcb/mcb-core.c @@ -71,8 +71,10 @@ static int mcb_probe(struct device *dev) get_device(dev); ret = mdrv->probe(mdev, found_id); - if (ret) + if (ret) { module_put(carrier_mod); + put_device(dev); + } return ret; } -- GitLab From 728ac3389296caf68638628c987aeae6c8851e2d Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 2 Dec 2022 01:38:50 -0800 Subject: [PATCH 1257/1480] mcb: mcb-parse: fix error handing in chameleon_parse_gdd() If mcb_device_register() returns error in chameleon_parse_gdd(), the refcount of bus and device name are leaked. Fix this by calling put_device() to give up the reference, so they can be released in mcb_release_dev() and kobject_cleanup(). Fixes: 3764e82e5150 ("drivers: Introduce MEN Chameleon Bus") Reviewed-by: Johannes Thumshirn Signed-off-by: Yang Yingliang Signed-off-by: Johannes Thumshirn Link: https://lore.kernel.org/r/ebfb06e39b19272f0197fa9136b5e4b6f34ad732.1669624063.git.johannes.thumshirn@wdc.com Signed-off-by: Greg Kroah-Hartman --- drivers/mcb/mcb-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c index 0266bfddfbe27..aa6938da0db85 100644 --- a/drivers/mcb/mcb-parse.c +++ b/drivers/mcb/mcb-parse.c @@ -108,7 +108,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus, return 0; err: - mcb_free_dev(mdev); + put_device(&mdev->dev); return ret; } -- GitLab From 11fa7fefe3d8fac7da56bc9aa3dd5fb3081ca797 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 2 Dec 2022 11:02:37 +0800 Subject: [PATCH 1258/1480] chardev: fix error handling in cdev_device_add() While doing fault injection test, I got the following report: ------------[ cut here ]------------ kobject: '(null)' (0000000039956980): is not initialized, yet kobject_put() is being called. WARNING: CPU: 3 PID: 6306 at kobject_put+0x23d/0x4e0 CPU: 3 PID: 6306 Comm: 283 Tainted: G W 6.1.0-rc2-00005-g307c1086d7c9 #1253 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:kobject_put+0x23d/0x4e0 Call Trace: cdev_device_add+0x15e/0x1b0 __iio_device_register+0x13b4/0x1af0 [industrialio] __devm_iio_device_register+0x22/0x90 [industrialio] max517_probe+0x3d8/0x6b4 [max517] i2c_device_probe+0xa81/0xc00 When device_add() is injected fault and returns error, if dev->devt is not set, cdev_add() is not called, cdev_del() is not needed. Fix this by checking dev->devt in error path. Fixes: 233ed09d7fda ("chardev: add helper function to register char devs with a struct device") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221202030237.520280-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- fs/char_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/char_dev.c b/fs/char_dev.c index 340e4543b24a9..13deb45f1ec65 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -554,7 +554,7 @@ int cdev_device_add(struct cdev *cdev, struct device *dev) } rc = device_add(dev); - if (rc) + if (rc && dev->devt) cdev_del(cdev); return rc; -- GitLab From b058ea3ab5afea873ab8d976277539ca9e43869a Mon Sep 17 00:00:00 2001 From: Joao Martins Date: Tue, 29 Nov 2022 13:12:35 +0000 Subject: [PATCH 1259/1480] vfio/iova_bitmap: refactor iova_bitmap_set() to better handle page boundaries Commit f38044e5ef58 ("vfio/iova_bitmap: Fix PAGE_SIZE unaligned bitmaps") had fixed the unaligned bitmaps by capping the remaining iterable set at the start of the bitmap. Although, that mistakenly worked around iova_bitmap_set() incorrectly setting bits across page boundary. Fix this by reworking the loop inside iova_bitmap_set() to iterate over a range of bits to set (cur_bit .. last_bit) which may span different pinned pages, thus updating @page_idx and @offset as it sets the bits. The previous cap to the first page is now adjusted to be always accounted rather than when there's only a non-zero pgoff. While at it, make @page_idx , @offset and @nbits to be unsigned int given that it won't be more than 512 and 4096 respectively (even a bigger PAGE_SIZE or a smaller struct page size won't make this bigger than the above 32-bit max). Also, delete the stale kdoc on Return type. Cc: Avihai Horon Fixes: f38044e5ef58 ("vfio/iova_bitmap: Fix PAGE_SIZE unaligned bitmaps") Co-developed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe Signed-off-by: Joao Martins Reviewed-by: Jason Gunthorpe Tested-by: Avihai Horon Link: https://lore.kernel.org/r/20221129131235.38880-1-joao.m.martins@oracle.com Signed-off-by: Alex Williamson --- drivers/vfio/iova_bitmap.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c index de6d6ea5c4967..0848f920efb7c 100644 --- a/drivers/vfio/iova_bitmap.c +++ b/drivers/vfio/iova_bitmap.c @@ -298,9 +298,7 @@ static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap) { unsigned long remaining, bytes; - /* Cap to one page in the first iteration, if PAGE_SIZE unaligned. */ - bytes = !bitmap->mapped.pgoff ? bitmap->mapped.npages << PAGE_SHIFT : - PAGE_SIZE - bitmap->mapped.pgoff; + bytes = (bitmap->mapped.npages << PAGE_SHIFT) - bitmap->mapped.pgoff; remaining = bitmap->mapped_total_index - bitmap->mapped_base_index; remaining = min_t(unsigned long, remaining, @@ -399,29 +397,27 @@ int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque, * Set the bits corresponding to the range [iova .. iova+length-1] in * the user bitmap. * - * Return: The number of bits set. */ void iova_bitmap_set(struct iova_bitmap *bitmap, unsigned long iova, size_t length) { struct iova_bitmap_map *mapped = &bitmap->mapped; - unsigned long offset = (iova - mapped->iova) >> mapped->pgshift; - unsigned long nbits = max_t(unsigned long, 1, length >> mapped->pgshift); - unsigned long page_idx = offset / BITS_PER_PAGE; - unsigned long page_offset = mapped->pgoff; - void *kaddr; - - offset = offset % BITS_PER_PAGE; + unsigned long cur_bit = ((iova - mapped->iova) >> + mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; + unsigned long last_bit = (((iova + length - 1) - mapped->iova) >> + mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; do { - unsigned long size = min(BITS_PER_PAGE - offset, nbits); + unsigned int page_idx = cur_bit / BITS_PER_PAGE; + unsigned int offset = cur_bit % BITS_PER_PAGE; + unsigned int nbits = min(BITS_PER_PAGE - offset, + last_bit - cur_bit + 1); + void *kaddr; kaddr = kmap_local_page(mapped->pages[page_idx]); - bitmap_set(kaddr + page_offset, offset, size); + bitmap_set(kaddr, offset, nbits); kunmap_local(kaddr); - page_offset = offset = 0; - nbits -= size; - page_idx++; - } while (nbits > 0); + cur_bit += nbits; + } while (cur_bit <= last_bit); } EXPORT_SYMBOL_GPL(iova_bitmap_set); -- GitLab From 5de7cdd7fa0f62b3e8d2facc8f604e49d887677e Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 12 Nov 2022 15:24:46 +0000 Subject: [PATCH 1260/1480] extcon: max77843: Replace irqchip mask_invert with unmask_base Remove use of the deprecated mask_invert flag. Inverted mask registers (where a '1' bit enables an IRQ) can be described more directly as an unmask register. Signed-off-by: Aidan MacDonald Reviewed-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77843.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index 8e6e97ec65a8a..1bc0426ce3f1e 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c @@ -189,8 +189,7 @@ static const struct regmap_irq max77843_muic_irq[] = { static const struct regmap_irq_chip max77843_muic_irq_chip = { .name = "max77843-muic", .status_base = MAX77843_MUIC_REG_INT1, - .mask_base = MAX77843_MUIC_REG_INTMASK1, - .mask_invert = true, + .unmask_base = MAX77843_MUIC_REG_INTMASK1, .num_regs = 3, .irqs = max77843_muic_irq, .num_irqs = ARRAY_SIZE(max77843_muic_irq), -- GitLab From df9c4faa81c9659eefc9e149ae9b2124de17dfa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:35:42 +0100 Subject: [PATCH 1261/1480] extcon: fsa9480: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-fsa9480.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-fsa9480.c b/drivers/extcon/extcon-fsa9480.c index 7cff66c29907e..e8b2671eb29bc 100644 --- a/drivers/extcon/extcon-fsa9480.c +++ b/drivers/extcon/extcon-fsa9480.c @@ -257,8 +257,7 @@ static irqreturn_t fsa9480_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int fsa9480_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int fsa9480_probe(struct i2c_client *client) { struct fsa9480_usbsw *info; int ret; @@ -370,7 +369,7 @@ static struct i2c_driver fsa9480_i2c_driver = { .pm = &fsa9480_pm_ops, .of_match_table = fsa9480_of_match, }, - .probe = fsa9480_probe, + .probe_new = fsa9480_probe, .id_table = fsa9480_id, }; -- GitLab From 881de30c28ac0725ab8fb9af905b568a849f8d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:35:43 +0100 Subject: [PATCH 1262/1480] extcon: rt8973: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-rt8973a.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index e6e448f6ea2f6..afc9b405d1030 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -548,8 +548,7 @@ static void rt8973a_init_dev_type(struct rt8973a_muic_info *info) } } -static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt8973a_muic_i2c_probe(struct i2c_client *i2c) { struct device_node *np = i2c->dev.of_node; struct rt8973a_muic_info *info; @@ -696,7 +695,7 @@ static struct i2c_driver rt8973a_muic_i2c_driver = { .pm = &rt8973a_muic_pm_ops, .of_match_table = rt8973a_dt_match, }, - .probe = rt8973a_muic_i2c_probe, + .probe_new = rt8973a_muic_i2c_probe, .remove = rt8973a_muic_i2c_remove, .id_table = rt8973a_i2c_id, }; -- GitLab From 5313121b22fd11db0d14f305c110168b8176efdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:35:44 +0100 Subject: [PATCH 1263/1480] extcon: usbc-tusb320: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-usbc-tusb320.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c index 2a120d8d3c272..396a026e0c90e 100644 --- a/drivers/extcon/extcon-usbc-tusb320.c +++ b/drivers/extcon/extcon-usbc-tusb320.c @@ -421,8 +421,7 @@ static int tusb320_typec_probe(struct i2c_client *client, return 0; } -static int tusb320_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tusb320_probe(struct i2c_client *client) { struct tusb320_priv *priv; const void *match_data; @@ -495,7 +494,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = { MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); static struct i2c_driver tusb320_extcon_driver = { - .probe = tusb320_probe, + .probe_new = tusb320_probe, .driver = { .name = "extcon-tusb320", .of_match_table = tusb320_extcon_dt_match, -- GitLab From af45de8368883c9620a7735a8c2532e52101c1a2 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:01 +0100 Subject: [PATCH 1264/1480] dt-bindings: qcom: geni-se: document I2C Master Hub wrapper variant The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Document the variant compatible, forbid UART and SPI sub-nodes, and remove requirement for the Master AHB clock and iommu property. Signed-off-by: Neil Armstrong Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang --- .../bindings/soc/qcom/qcom,geni-se.yaml | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml index 2bf5293fc9952..ab4df02052853 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml @@ -21,20 +21,19 @@ properties: compatible: enum: - qcom,geni-se-qup + - qcom,geni-se-i2c-master-hub reg: description: QUP wrapper common register address and length. maxItems: 1 clock-names: - items: - - const: m-ahb - - const: s-ahb + minItems: 1 + maxItems: 2 clocks: - items: - - description: Master AHB Clock - - description: Slave AHB Clock + minItems: 1 + maxItems: 2 "#address-cells": const: 2 @@ -81,6 +80,39 @@ patternProperties: description: GENI Serial Engine based UART Controller. $ref: /schemas/serial/qcom,serial-geni-qcom.yaml# +allOf: + - if: + properties: + compatible: + contains: + const: qcom,geni-se-i2c-master-hub + then: + properties: + clock-names: + items: + - const: s-ahb + + clocks: + items: + - description: Slave AHB Clock + + iommus: false + + patternProperties: + "spi@[0-9a-f]+$": false + "serial@[0-9a-f]+$": false + else: + properties: + clock-names: + items: + - const: m-ahb + - const: s-ahb + + clocks: + items: + - description: Master AHB Clock + - description: Slave AHB Clock + additionalProperties: false examples: -- GitLab From cb29d4e6a9ef004eed24774bc26839aa9e373ba4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:02 +0100 Subject: [PATCH 1265/1480] dt-bindings: i2c: qcom-geni: document I2C Master Hub serial I2C engine The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Document the I2C Serial Engine variant used within the I2C Master Hub Wrapper. This serial engine variant lacks DMA support, requires a core clock, and since DMA support is lacking the memory interconnect path isn't needed. Signed-off-by: Neil Armstrong Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang --- .../bindings/i2c/qcom,i2c-geni-qcom.yaml | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml index 0e7ed00562e21..f5f7dc8f325cb 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml @@ -10,18 +10,19 @@ maintainers: - Andy Gross - Bjorn Andersson -allOf: - - $ref: /schemas/i2c/i2c-controller.yaml# - properties: compatible: - const: qcom,geni-i2c + enum: + - qcom,geni-i2c + - qcom,geni-i2c-master-hub clocks: - maxItems: 1 + minItems: 1 + maxItems: 2 clock-names: - const: se + minItems: 1 + maxItems: 2 clock-frequency: default: 100000 @@ -35,13 +36,12 @@ properties: - const: rx interconnects: + minItems: 2 maxItems: 3 interconnect-names: - items: - - const: qup-core - - const: qup-config - - const: qup-memory + minItems: 2 + maxItems: 3 interrupts: maxItems: 1 @@ -71,6 +71,50 @@ required: - clock-names - reg +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + - if: + properties: + compatible: + contains: + const: qcom,geni-i2c-master-hub + then: + properties: + clocks: + minItems: 2 + + clock-names: + items: + - const: se + - const: core + + dmas: false + dma-names: false + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: qup-core + - const: qup-config + else: + properties: + clocks: + maxItems: 1 + + clock-names: + const: se + + interconnects: + minItems: 3 + + interconnect-names: + items: + - const: qup-core + - const: qup-config + - const: qup-memory + unevaluatedProperties: false examples: -- GitLab From 63fc9af83c11e02ea9c981d3bd0382e36f49916f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:03 +0100 Subject: [PATCH 1266/1480] soc: qcom: geni-se: add desc struct to specify clocks from device match data The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Prepare support for the I2C Master Hub variant by moving the required clocks list to a new desc struct then passing it through the compatible match data. Signed-off-by: Neil Armstrong Reviewed-by: Konrad Dybcio Signed-off-by: Wolfram Sang --- drivers/soc/qcom/qcom-geni-se.c | 69 ++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index a0ceeede450f1..9ddee9fd11ba7 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -81,19 +81,31 @@ */ #define MAX_CLK_PERF_LEVEL 32 -#define NUM_AHB_CLKS 2 +#define MAX_CLKS 2 /** * struct geni_wrapper - Data structure to represent the QUP Wrapper Core * @dev: Device pointer of the QUP wrapper core * @base: Base address of this instance of QUP wrapper core - * @ahb_clks: Handle to the primary & secondary AHB clocks + * @clks: Handle to the primary & optional secondary AHB clocks + * @num_clks: Count of clocks * @to_core: Core ICC path */ struct geni_wrapper { struct device *dev; void __iomem *base; - struct clk_bulk_data ahb_clks[NUM_AHB_CLKS]; + struct clk_bulk_data clks[MAX_CLKS]; + unsigned int num_clks; +}; + +/** + * struct geni_se_desc - Data structure to represent the QUP Wrapper resources + * @clks: Name of the primary & optional secondary AHB clocks + * @num_clks: Count of clock names + */ +struct geni_se_desc { + unsigned int num_clks; + const char * const *clks; }; static const char * const icc_path_names[] = {"qup-core", "qup-config", @@ -496,8 +508,7 @@ static void geni_se_clks_off(struct geni_se *se) struct geni_wrapper *wrapper = se->wrapper; clk_disable_unprepare(se->clk); - clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks), - wrapper->ahb_clks); + clk_bulk_disable_unprepare(wrapper->num_clks, wrapper->clks); } /** @@ -528,15 +539,13 @@ static int geni_se_clks_on(struct geni_se *se) int ret; struct geni_wrapper *wrapper = se->wrapper; - ret = clk_bulk_prepare_enable(ARRAY_SIZE(wrapper->ahb_clks), - wrapper->ahb_clks); + ret = clk_bulk_prepare_enable(wrapper->num_clks, wrapper->clks); if (ret) return ret; ret = clk_prepare_enable(se->clk); if (ret) - clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks), - wrapper->ahb_clks); + clk_bulk_disable_unprepare(wrapper->num_clks, wrapper->clks); return ret; } @@ -887,11 +896,33 @@ static int geni_se_probe(struct platform_device *pdev) return PTR_ERR(wrapper->base); if (!has_acpi_companion(&pdev->dev)) { - wrapper->ahb_clks[0].id = "m-ahb"; - wrapper->ahb_clks[1].id = "s-ahb"; - ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks); + const struct geni_se_desc *desc; + int i; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -EINVAL; + + wrapper->num_clks = min_t(unsigned int, desc->num_clks, MAX_CLKS); + + for (i = 0; i < wrapper->num_clks; ++i) + wrapper->clks[i].id = desc->clks[i]; + + ret = of_count_phandle_with_args(dev->of_node, "clocks", "#clock-cells"); + if (ret < 0) { + dev_err(dev, "invalid clocks property at %pOF\n", dev->of_node); + return ret; + } + + if (ret < wrapper->num_clks) { + dev_err(dev, "invalid clocks count at %pOF, expected %d entries\n", + dev->of_node, wrapper->num_clks); + return -EINVAL; + } + + ret = devm_clk_bulk_get(dev, wrapper->num_clks, wrapper->clks); if (ret) { - dev_err(dev, "Err getting AHB clks %d\n", ret); + dev_err(dev, "Err getting clks %d\n", ret); return ret; } } @@ -901,8 +932,18 @@ static int geni_se_probe(struct platform_device *pdev) return devm_of_platform_populate(dev); } +static const char * const qup_clks[] = { + "m-ahb", + "s-ahb", +}; + +static const struct geni_se_desc qup_desc = { + .clks = qup_clks, + .num_clks = ARRAY_SIZE(qup_clks), +}; + static const struct of_device_id geni_se_dt_match[] = { - { .compatible = "qcom,geni-se-qup", }, + { .compatible = "qcom,geni-se-qup", .data = &qup_desc }, {} }; MODULE_DEVICE_TABLE(of, geni_se_dt_match); -- GitLab From f4aba01db4801cc02d1fae4c8099984a23740996 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:04 +0100 Subject: [PATCH 1267/1480] soc: qcom: geni-se: add support for I2C Master Hub wrapper variant The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Add the clock list for the I2C Master Hub variant to a new desc struct then pass it through the I2C Master Hub compatible match data. Signed-off-by: Neil Armstrong Reviewed-by: Konrad Dybcio Signed-off-by: Wolfram Sang --- drivers/soc/qcom/qcom-geni-se.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 9ddee9fd11ba7..f0475b93ca730 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -942,8 +942,18 @@ static const struct geni_se_desc qup_desc = { .num_clks = ARRAY_SIZE(qup_clks), }; +static const char * const i2c_master_hub_clks[] = { + "s-ahb", +}; + +static const struct geni_se_desc i2c_master_hub_desc = { + .clks = i2c_master_hub_clks, + .num_clks = ARRAY_SIZE(i2c_master_hub_clks), +}; + static const struct of_device_id geni_se_dt_match[] = { { .compatible = "qcom,geni-se-qup", .data = &qup_desc }, + { .compatible = "qcom,geni-se-i2c-master-hub", .data = &i2c_master_hub_desc }, {} }; MODULE_DEVICE_TABLE(of, geni_se_dt_match); -- GitLab From 14d02fbadb5dc1cdf66078ef8430dd1cd22bfd53 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:05 +0100 Subject: [PATCH 1268/1480] i2c: qcom-geni: add desc struct to prepare support for I2C Master Hub variant The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Those I2C serial engines variants have some requirements: - a separate "core" clock - doesn't support DMA, thus no memory interconnect path - fixed FIFO size not discoverable in the HW_PARAM_0 register Add a desc struct specifying all those requirements which will be used in a next change when adding the I2C Master Hub serial engine compatible. Signed-off-by: Neil Armstrong Reviewed-by: Konrad Dybcio Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-qcom-geni.c | 50 ++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 84a77512614d9..75dd0718c5a12 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -88,6 +88,7 @@ struct geni_i2c_dev { int cur_wr; int cur_rd; spinlock_t lock; + struct clk *core_clk; u32 clk_freq_out; const struct geni_i2c_clk_fld *clk_fld; int suspended; @@ -100,6 +101,13 @@ struct geni_i2c_dev { bool abort_done; }; +struct geni_i2c_desc { + bool has_core_clk; + char *icc_ddr; + bool no_dma_support; + unsigned int tx_fifo_depth; +}; + struct geni_i2c_err_log { int err; const char *msg; @@ -764,6 +772,7 @@ static int geni_i2c_probe(struct platform_device *pdev) u32 proto, tx_depth, fifo_disable; int ret; struct device *dev = &pdev->dev; + const struct geni_i2c_desc *desc = NULL; gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL); if (!gi2c) @@ -776,6 +785,14 @@ static int geni_i2c_probe(struct platform_device *pdev) if (IS_ERR(gi2c->se.base)) return PTR_ERR(gi2c->se.base); + desc = device_get_match_data(&pdev->dev); + + if (desc && desc->has_core_clk) { + gi2c->core_clk = devm_clk_get(dev, "core"); + if (IS_ERR(gi2c->core_clk)) + return PTR_ERR(gi2c->core_clk); + } + gi2c->se.clk = devm_clk_get(dev, "se"); if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev)) return PTR_ERR(gi2c->se.clk); @@ -819,7 +836,7 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->adap.dev.of_node = dev->of_node; strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); - ret = geni_icc_get(&gi2c->se, "qup-memory"); + ret = geni_icc_get(&gi2c->se, desc ? desc->icc_ddr : "qup-memory"); if (ret) return ret; /* @@ -829,12 +846,17 @@ static int geni_i2c_probe(struct platform_device *pdev) */ gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; - gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out); + if (!desc || desc->icc_ddr) + gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out); ret = geni_icc_set_bw(&gi2c->se); if (ret) return ret; + ret = clk_prepare_enable(gi2c->core_clk); + if (ret) + return ret; + ret = geni_se_resources_on(&gi2c->se); if (ret) { dev_err(dev, "Error turning on resources %d\n", ret); @@ -844,10 +866,15 @@ static int geni_i2c_probe(struct platform_device *pdev) if (proto != GENI_SE_I2C) { dev_err(dev, "Invalid proto %d\n", proto); geni_se_resources_off(&gi2c->se); + clk_disable_unprepare(gi2c->core_clk); return -ENXIO; } - fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; + if (desc && desc->no_dma_support) + fifo_disable = false; + else + fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; + if (fifo_disable) { /* FIFO is disabled, so we can only use GPI DMA */ gi2c->gpi_mode = true; @@ -859,6 +886,16 @@ static int geni_i2c_probe(struct platform_device *pdev) } else { gi2c->gpi_mode = false; tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); + + /* I2C Master Hub Serial Elements doesn't have the HW_PARAM_0 register */ + if (!tx_depth && desc) + tx_depth = desc->tx_fifo_depth; + + if (!tx_depth) { + dev_err(dev, "Invalid TX FIFO depth\n"); + return -EINVAL; + } + gi2c->tx_wm = tx_depth - 1; geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, @@ -867,6 +904,7 @@ static int geni_i2c_probe(struct platform_device *pdev) dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); } + clk_disable_unprepare(gi2c->core_clk); ret = geni_se_resources_off(&gi2c->se); if (ret) { dev_err(dev, "Error turning off resources %d\n", ret); @@ -932,6 +970,8 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) gi2c->suspended = 1; } + clk_disable_unprepare(gi2c->core_clk); + return geni_icc_disable(&gi2c->se); } @@ -944,6 +984,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) if (ret) return ret; + ret = clk_prepare_enable(gi2c->core_clk); + if (ret) + return ret; + ret = geni_se_resources_on(&gi2c->se); if (ret) return ret; -- GitLab From cacd9643eca7a1f4635479aff4ec33aaade45e64 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 29 Nov 2022 15:47:06 +0100 Subject: [PATCH 1269/1480] i2c: qcom-geni: add support for I2C Master Hub variant The I2C Master Hub is a stripped down version of the GENI Serial Engine QUP Wrapper Controller but only supporting I2C serial engines without DMA support. Add the I2C Master Hub serial engine compatible along the specific requirements in a new desc struct passed through the device match data. Signed-off-by: Neil Armstrong Reviewed-by: Konrad Dybcio Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-qcom-geni.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 75dd0718c5a12..bfe75038bc149 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -1026,8 +1026,16 @@ static const struct dev_pm_ops geni_i2c_pm_ops = { NULL) }; +const struct geni_i2c_desc i2c_master_hub = { + .has_core_clk = true, + .icc_ddr = NULL, + .no_dma_support = true, + .tx_fifo_depth = 16, +}; + static const struct of_device_id geni_i2c_dt_match[] = { { .compatible = "qcom,geni-i2c" }, + { .compatible = "qcom,geni-i2c-master-hub", .data = &i2c_master_hub }, {} }; MODULE_DEVICE_TABLE(of, geni_i2c_dt_match); -- GitLab From 73e9841ba7e3e394c276d5f24ef4e639bd5f24e1 Mon Sep 17 00:00:00 2001 From: Binbin Zhou Date: Wed, 30 Nov 2022 13:55:51 +0800 Subject: [PATCH 1270/1480] i2c: gpio: Fix potential unused warning for 'i2c_gpio_dt_ids' Dropping a matching #ifdef check along with dropping of_match_ptr() is just a cleanup, while dropping of_match_ptr() that has no corresponding #ifdef fixes an actual warning. Suggested-by: Andy Shevchenko Acked-by: Arnd Bergmann Signed-off-by: Binbin Zhou Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-gpio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index b1985c1667e16..0e4385a9bcf71 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -482,19 +482,17 @@ static int i2c_gpio_remove(struct platform_device *pdev) return 0; } -#if defined(CONFIG_OF) static const struct of_device_id i2c_gpio_dt_ids[] = { { .compatible = "i2c-gpio", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); -#endif static struct platform_driver i2c_gpio_driver = { .driver = { .name = "i2c-gpio", - .of_match_table = of_match_ptr(i2c_gpio_dt_ids), + .of_match_table = i2c_gpio_dt_ids, }, .probe = i2c_gpio_probe, .remove = i2c_gpio_remove, -- GitLab From 99c4ec2397bb88c3325676a308b93aa8ba362de8 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Tue, 17 Apr 2018 16:32:32 +0200 Subject: [PATCH 1271/1480] i2c: mux: pca9541: switch to using .probe_new Use the new probe style for i2c drivers. Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-mux-pca9541.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index ea83de78f52db..09d1d9e67e31f 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -283,8 +283,7 @@ static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) /* * I2C init/probing/exit functions */ -static int pca9541_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pca9541_probe(struct i2c_client *client) { struct i2c_adapter *adap = client->adapter; struct i2c_mux_core *muxc; @@ -337,7 +336,7 @@ static struct i2c_driver pca9541_driver = { .name = "pca9541", .of_match_table = of_match_ptr(pca9541_of_match), }, - .probe = pca9541_probe, + .probe_new = pca9541_probe, .remove = pca9541_remove, .id_table = pca9541_id, }; -- GitLab From a00f6d3723f5617222ab8df228228c3c2c84e3ec Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Wed, 12 Oct 2022 18:36:47 +0200 Subject: [PATCH 1272/1480] drivers/i2c: use simple i2c probe All these drivers have an i2c probe function which doesn't use the "struct i2c_device_id *id" parameter, so they can trivially be converted to the "probe_new" style of probe with a single argument. This is part of an ongoing transition to single-argument i2c probe functions. Old-style probe functions involve a call to i2c_match_id: in drivers/i2c/i2c-core-base.c, /* * When there are no more users of probe(), * rename probe_new to probe. */ if (driver->probe_new) status = driver->probe_new(client); else if (driver->probe) status = driver->probe(client, i2c_match_id(driver->id_table, client)); else status = -EINVAL; Drivers which don't need the second parameter can be declared using probe_new instead, avoiding the call to i2c_match_id. Drivers which do can still be converted to probe_new-style, calling i2c_match_id themselves (as is done currently for of_match_id). This change was done using the following Coccinelle script, and fixed up for whitespace changes: @ rule1 @ identifier fn; identifier client, id; @@ - static int fn(struct i2c_client *client, const struct i2c_device_id *id) + static int fn(struct i2c_client *client) { ...when != id } @ rule2 depends on rule1 @ identifier rule1.fn; identifier driver; @@ struct i2c_driver driver = { - .probe + .probe_new = ( fn | - &fn + fn ) , }; Signed-off-by: Stephen Kitt Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 5 ++--- drivers/i2c/i2c-smbus.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 9aa7b9d9a4856..82478eab71af0 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1017,15 +1017,14 @@ static const struct i2c_device_id dummy_id[] = { { }, }; -static int dummy_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dummy_probe(struct i2c_client *client) { return 0; } static struct i2c_driver dummy_driver = { .driver.name = "dummy", - .probe = dummy_probe, + .probe_new = dummy_probe, .id_table = dummy_id, }; diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index c85710ed95483..cd19546d31fcb 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -112,8 +112,7 @@ static void smbalert_work(struct work_struct *work) } /* Setup SMBALERT# infrastructure */ -static int smbalert_probe(struct i2c_client *ara, - const struct i2c_device_id *id) +static int smbalert_probe(struct i2c_client *ara) { struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev); struct i2c_smbus_alert *alert; @@ -170,7 +169,7 @@ static struct i2c_driver smbalert_driver = { .driver = { .name = "smbus_alert", }, - .probe = smbalert_probe, + .probe_new = smbalert_probe, .remove = smbalert_remove, .id_table = smbalert_ids, }; -- GitLab From a5eacd2e3790ecf1cbc0be2e53a6f3d1ce3bb719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:22 +0100 Subject: [PATCH 1273/1480] i2c: mux: pca954x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-mux-pca954x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index a5f458b635df6..3639e6d7304cd 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -411,9 +411,9 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data) /* * I2C init/probing/exit functions */ -static int pca954x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pca954x_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct i2c_adapter *adap = client->adapter; struct device *dev = &client->dev; struct gpio_desc *gpio; @@ -554,7 +554,7 @@ static struct i2c_driver pca954x_driver = { .pm = &pca954x_pm, .of_match_table = pca954x_of_match, }, - .probe = pca954x_probe, + .probe_new = pca954x_probe, .remove = pca954x_remove, .id_table = pca954x_id, }; -- GitLab From 87ab726952267caabb9c1404e007e16e42f03b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Nov 2022 23:36:19 +0100 Subject: [PATCH 1274/1480] i2c: slave-eeprom: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-slave-eeprom.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-slave-eeprom.c b/drivers/i2c/i2c-slave-eeprom.c index 4abc2d9198815..5f25f23c4ff8c 100644 --- a/drivers/i2c/i2c-slave-eeprom.c +++ b/drivers/i2c/i2c-slave-eeprom.c @@ -140,8 +140,9 @@ static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_cli return 0; } -static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int i2c_slave_eeprom_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct eeprom_data *eeprom; int ret; unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data) + 1; @@ -206,7 +207,7 @@ static struct i2c_driver i2c_slave_eeprom_driver = { .driver = { .name = "i2c-slave-eeprom", }, - .probe = i2c_slave_eeprom_probe, + .probe_new = i2c_slave_eeprom_probe, .remove = i2c_slave_eeprom_remove, .id_table = i2c_slave_eeprom_id, }; -- GitLab From d78a167332e1ca8113268ed922c1212fd71b73ad Mon Sep 17 00:00:00 2001 From: Hui Tang Date: Mon, 14 Nov 2022 17:25:40 +0800 Subject: [PATCH 1275/1480] i2c: pxa-pci: fix missing pci_disable_device() on error in ce4100_i2c_probe Using pcim_enable_device() to avoid missing pci_disable_device(). Fixes: 7e94dd154e93 ("i2c-pxa2xx: Add PCI support for PXA I2C controller") Signed-off-by: Hui Tang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-pxa-pci.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c index f614cade432bb..30e38bc8b6db8 100644 --- a/drivers/i2c/busses/i2c-pxa-pci.c +++ b/drivers/i2c/busses/i2c-pxa-pci.c @@ -105,7 +105,7 @@ static int ce4100_i2c_probe(struct pci_dev *dev, int i; struct ce4100_devices *sds; - ret = pci_enable_device_mem(dev); + ret = pcim_enable_device(dev); if (ret) return ret; @@ -114,10 +114,8 @@ static int ce4100_i2c_probe(struct pci_dev *dev, return -EINVAL; } sds = kzalloc(sizeof(*sds), GFP_KERNEL); - if (!sds) { - ret = -ENOMEM; - goto err_mem; - } + if (!sds) + return -ENOMEM; for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) { sds->pdev[i] = add_i2c_device(dev, i); @@ -133,8 +131,6 @@ static int ce4100_i2c_probe(struct pci_dev *dev, err_dev_add: kfree(sds); -err_mem: - pci_disable_device(dev); return ret; } -- GitLab From bcc5e2dcf09089b337b76fc1a589f6ff95ca19ac Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Nov 2022 09:43:14 +0300 Subject: [PATCH 1276/1480] staging: rtl8192u: Fix use after free in ieee80211_rx() We cannot dereference the "skb" pointer after calling ieee80211_monitor_rx(), because it is a use after free. Fixes: 8fc8598e61f6 ("Staging: Added Realtek rtl8192u driver to staging") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/Y33BArx3k/aw6yv/@kili Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index f142d09869901..5c73e3f8541ae 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -951,9 +951,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, #endif if (ieee->iw_mode == IW_MODE_MONITOR) { + unsigned int len = skb->len; + ieee80211_monitor_rx(ieee, skb, rx_stats); stats->rx_packets++; - stats->rx_bytes += skb->len; + stats->rx_bytes += len; return 1; } -- GitLab From 24a525a671ef1e410926da010ef2a3a1b1b96481 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 22 Nov 2022 23:45:57 +0100 Subject: [PATCH 1277/1480] staging: rtl8192e: Remove unchanged variable AcmMethod AcmMethod is initialized and never changed. The evaluation will always have the same result. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/7d73a66184e13d5f8d4af7d21564032247a7e923.1669156825.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 2 -- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 -- drivers/staging/rtl8192e/rtl819x_Qos.h | 7 ------- 4 files changed, 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index b9c846015d286..80eba5d5ab37b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -224,8 +224,6 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val) u8 acm = pAciAifsn->f.acm; u8 AcmCtrl = rtl92e_readb(dev, AcmHwCtrl); - AcmCtrl = AcmCtrl | ((priv->AcmMethod == 2) ? 0x0 : 0x1); - if (acm) { switch (eACI) { case AC0_BE: diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 399ee9783f994..a8cbeb9545da3 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -830,7 +830,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) struct r8192_priv *priv = rtllib_priv(dev); u8 i; - priv->AcmMethod = eAcmWay2_SW; priv->dot11_current_preamble_mode = PREAMBLE_AUTO; priv->rtllib->status = 0; priv->polling_timer_on = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index b1656d4ecbad6..54c7a21280534 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -340,8 +340,6 @@ struct r8192_priv { struct bb_reg_definition PHYRegDef[4]; struct rate_adaptive rate_adaptive; - enum acm_method AcmMethod; - struct rt_firmware *pFirmware; enum rtl819x_loopback LoopbackMode; diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h index 5073f9f40fdc2..c010eb0d60366 100644 --- a/drivers/staging/rtl8192e/rtl819x_Qos.h +++ b/drivers/staging/rtl8192e/rtl819x_Qos.h @@ -97,13 +97,6 @@ enum direction_value { DIR_BI_DIR = 3, }; -enum acm_method { - eAcmWay0_SwAndHw = 0, - eAcmWay1_HW = 1, - eAcmWay2_SW = 2, -}; - - struct acm { u64 UsedTime; u64 MediumTime; -- GitLab From d694a05fda8797521d51ceba2e7942751391626a Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 22 Nov 2022 23:46:08 +0100 Subject: [PATCH 1278/1480] staging: rtl8192e: Remove unused variable skb_aggQ skb_aggQ is initialized, never used and purged. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/3197be3cb412eea1c662a5bec1b1afda2cee675d.1669156825.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 2 -- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 2 -- drivers/staging/rtl8192e/rtllib.h | 1 - 3 files changed, 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 80eba5d5ab37b..f02e67f68e237 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1946,8 +1946,6 @@ void rtl92e_stop_adapter(struct net_device *dev, bool reset) for (i = 0; i < MAX_QUEUE_SIZE; i++) skb_queue_purge(&priv->rtllib->skb_waitQ[i]); - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_purge(&priv->rtllib->skb_aggQ[i]); skb_queue_purge(&priv->skb_queue); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index a8cbeb9545da3..369a59a753fe8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -903,8 +903,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) for (i = 0; i < MAX_QUEUE_SIZE; i++) skb_queue_head_init(&priv->rtllib->skb_waitQ[i]); - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_head_init(&priv->rtllib->skb_aggQ[i]); } static void _rtl92e_init_priv_lock(struct r8192_priv *priv) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 7119c9c5e1fef..1152fbf433837 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1624,7 +1624,6 @@ struct rtllib_device { int mgmt_queue_tail; u8 AsocRetryCount; struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; bool bdynamic_txpower_enable; -- GitLab From efc6f7ce3adf3331298a4bfe2fa9d3912e660261 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 22 Nov 2022 23:46:15 +0100 Subject: [PATCH 1279/1480] staging: rtl8192e: Remove unused variable initialized_at_probe initialized_at_probe is initialized and never used. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/4855b2dd5b7296b0eb10e697f605fb820e1dfc7b.1669156825.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 - drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 369a59a753fe8..7b78bdfadc8da 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -836,7 +836,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->up_first_time = 1; priv->blinked_ingpio = false; priv->being_init_adapter = false; - priv->initialized_at_probe = false; priv->bdisable_nic = false; priv->bfirst_init = false; priv->txringcount = 64; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 54c7a21280534..1c00ad709a3c2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -309,7 +309,6 @@ struct r8192_priv { bool bfirst_init; bool bfirst_after_down; - bool initialized_at_probe; bool being_init_adapter; int irq; -- GitLab From aae3567db0e9e4be26c8c51c441d8bc43d613116 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 22 Nov 2022 23:46:21 +0100 Subject: [PATCH 1280/1480] staging: rtl8192e: Remove unused variable ChannelAccessSetting ChannelAccessSetting is never used. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/b88a31954532f47a4caf9abfcad8e20b32a618cc.1669156825.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 1c00ad709a3c2..ca2e685148d4d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -234,15 +234,6 @@ struct rt_stats { u32 CurrentShowTxate; }; -struct channel_access_setting { - u16 SIFS_Timer; - u16 DIFS_Timer; - u16 SlotTimeTimer; - u16 EIFS_Timer; - u16 CWminIndex; - u16 CWmaxIndex; -}; - struct init_gain { u8 xaagccore1; u8 xbagccore1; @@ -321,9 +312,6 @@ struct r8192_priv { struct delayed_work txpower_tracking_wq; struct delayed_work rfpath_check_wq; struct delayed_work gpio_change_rf_wq; - - struct channel_access_setting ChannelAccessSetting; - struct rtl819x_ops *ops; struct rtllib_device *rtllib; -- GitLab From e0005909e5e98f230397064de391371ba6a66fba Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 22 Nov 2022 23:46:29 +0100 Subject: [PATCH 1281/1480] staging: rtl8192e: Remove unused variable int_log int_log is initialized and incremented but never evaluated. Remove resulting dead code. Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/e2edcde052cc3c47e6e6b94d09e460b8cf6a49a8.1669156825.git.philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8190P_def.h | 15 --------------- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 3 --- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 -- 3 files changed, 20 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h index 53fd79a281892..ac192254a4bb3 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h @@ -154,21 +154,6 @@ struct tx_fwinfo_8190pci { }; -struct log_int_8190 { - u32 nIMR_COMDOK; - u32 nIMR_MGNTDOK; - u32 nIMR_HIGH; - u32 nIMR_VODOK; - u32 nIMR_VIDOK; - u32 nIMR_BEDOK; - u32 nIMR_BKDOK; - u32 nIMR_ROK; - u32 nIMR_RCOK; - u32 nIMR_TBDOK; - u32 nIMR_BDOK; - u32 nIMR_RXFOVW; -}; - struct phy_ofdm_rx_status_rxsc_sgien_exintfflag { u8 reserved:4; u8 rxsc:2; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 7b78bdfadc8da..f8fbe78ccad9f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -866,8 +866,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rst_progress = RESET_TYPE_NORESET; priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); - - memset(&priv->int_log, 0, sizeof(struct log_int_8190)); priv->rx_ctr = 0; priv->rtllib->wx_set_enc = 0; priv->hw_radio_off = false; @@ -2185,7 +2183,6 @@ static irqreturn_t _rtl92e_irq(int irq, void *netdev) if (inta & IMR_ROK) { priv->stats.rxint++; - priv->int_log.nIMR_ROK++; tasklet_schedule(&priv->irq_rx_tasklet); } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index ca2e685148d4d..cceb77492363a 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -317,8 +317,6 @@ struct r8192_priv { struct work_struct reset_wq; - struct log_int_8190 int_log; - enum rt_customer_id CustomerID; -- GitLab From d30f4436f364b4ad915ca2c09be07cd0f93ceb44 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 23 Nov 2022 16:12:53 +0800 Subject: [PATCH 1282/1480] staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() The skb is delivered to netif_rx() in rtllib_monitor_rx(), which may free it, after calling this, dereferencing skb may trigger use-after-free. Found by Smatch. Fixes: 94a799425eee ("From: wlanfae [PATCH 1/8] rtl8192e: Import new version of driver from realtek") Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20221123081253.22296-1-yuehaibing@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 6a0f5bbb99ef4..f8965afab7678 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1489,9 +1489,9 @@ static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb, hdrlen += 4; } - rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen); ieee->stats.rx_packets++; ieee->stats.rx_bytes += skb->len; + rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen); return 1; } -- GitLab From d43ea3d4d2efd015ae7999168a58796671df4138 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 16:42:49 +0100 Subject: [PATCH 1283/1480] staging: r8188eu: drop return value from issue_probereq_ex The only caller of issue_probereq_ex does not check the return value. We can remove it and make issue_probereq_ex a void function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126154253.178275-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 11 ++--------- drivers/staging/r8188eu/include/rtw_mlme_ext.h | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 161cb67f78828..2f3f7da08d0c7 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -4482,8 +4482,8 @@ inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps _issue_probereq(padapter, pssid, da, false); } -int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, - int try_cnt, int wait_ms) +void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, + int try_cnt, int wait_ms) { int ret; int i = 0; @@ -4497,13 +4497,6 @@ int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, msleep(wait_ms); } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); - - if (ret != _FAIL) { - ret = _SUCCESS; - goto exit; - } -exit: - return ret; } /* if psta == NULL, indicate we are station (client) now... */ diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index c46fc1a530859..720610bc8fefc 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -512,8 +512,8 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status); void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da); -s32 issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, - u8 *da, int try_cnt, int wait_ms); +void issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, + u8 *da, int try_cnt, int wait_ms); int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, -- GitLab From e0e14bbee1811209435d3ba29008769bd7a45057 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 16:42:50 +0100 Subject: [PATCH 1284/1480] staging: r8188eu: remove wait_ms parameter Remove the wait_ms parameter from function issue_probereq_ex. There's only one caller, who requests a waiting time of 1 ms. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126154253.178275-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 12 ++++++------ drivers/staging/r8188eu/include/rtw_mlme_ext.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 2f3f7da08d0c7..990336244030d 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -4483,20 +4483,20 @@ inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps } void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, - int try_cnt, int wait_ms) + int try_cnt) { int ret; int i = 0; do { - ret = _issue_probereq(padapter, pssid, da, wait_ms > 0); + ret = _issue_probereq(padapter, pssid, da, true); i++; - if (i < try_cnt && wait_ms > 0 && ret == _FAIL) - msleep(wait_ms); + if (i < try_cnt && ret == _FAIL) + msleep(1); - } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); + } while ((i < try_cnt) && (ret == _FAIL)); } /* if psta == NULL, indicate we are station (client) now... */ @@ -7046,7 +7046,7 @@ void linked_status_chk(struct adapter *padapter) } if (rx_chk != _SUCCESS) - issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3); if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 720610bc8fefc..04fd673d3a04c 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -513,7 +513,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da); void issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, - u8 *da, int try_cnt, int wait_ms); + u8 *da, int try_cnt); int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, -- GitLab From 77833c305dc897c094e5c5419c27568509346609 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 16:42:51 +0100 Subject: [PATCH 1285/1480] staging: r8188eu: fix the number of probereq retries issue_probereq_ex sends a probe request and retries if this fails. There's no point in making the number of retries configurable. Hard-code the value that's used by issue_probereq_ex's only caller. Simplify the code to check the loop condition only once. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126154253.178275-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 21 +++++++------------ .../staging/r8188eu/include/rtw_mlme_ext.h | 3 +-- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 990336244030d..667f54e313eff 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -4482,21 +4482,16 @@ inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps _issue_probereq(padapter, pssid, da, false); } -void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, - int try_cnt) +void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) { - int ret; - int i = 0; - - do { - ret = _issue_probereq(padapter, pssid, da, true); - - i++; + int i; - if (i < try_cnt && ret == _FAIL) + for (i = 0; i < 3; i++) { + if (_issue_probereq(padapter, pssid, da, true) == _FAIL) msleep(1); - - } while ((i < try_cnt) && (ret == _FAIL)); + else + break; + } } /* if psta == NULL, indicate we are station (client) now... */ @@ -7046,7 +7041,7 @@ void linked_status_chk(struct adapter *padapter) } if (rx_chk != _SUCCESS) - issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3); + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr); if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 04fd673d3a04c..089bd54467733 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -512,8 +512,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status); void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da); -void issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, - u8 *da, int try_cnt); +void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da); int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, -- GitLab From 92f1bb5ff104d7f36754f27c17483d4e8ffe85ae Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 16:42:52 +0100 Subject: [PATCH 1286/1480] staging: r8188eu: simplify the checks for zero address In function ap2sta_data_frame, we can use is_zero_ether_addr to check for all-zero ethernet addresses. Both pattrib->bssid and mybssid are 16-bit aligned. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126154253.178275-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_recv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index 5b0a66aebff19..631c500dda427 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -779,9 +779,8 @@ static int ap2sta_data_frame( } /* check BSSID */ - if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { + if (is_zero_ether_addr(pattrib->bssid) || is_zero_ether_addr(mybssid) || + (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { if (!bmcast) issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); -- GitLab From 57a8f00f03f1fa493fadd20992e700d24f6860cb Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 16:42:53 +0100 Subject: [PATCH 1287/1480] staging: r8188eu: use ieee80211 helper for protected bit Use ieee80211_has_protected to check if the "protected" bit is set. Remove the r8188eu driver's internal macro for this check. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126154253.178275-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- drivers/staging/r8188eu/include/wifi.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 667f54e313eff..93696892ec7dc 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -809,7 +809,7 @@ static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_fram if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) return; - offset = (GetPrivacy(pframe)) ? 4 : 0; + offset = ieee80211_has_protected(hdr->frame_control) ? 4 : 0; seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2)); status = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4)); diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h index 2381c519ceafe..254a4bc1a1419 100644 --- a/drivers/staging/r8188eu/include/wifi.h +++ b/drivers/staging/r8188eu/include/wifi.h @@ -170,9 +170,6 @@ enum WIFI_REG_DOMAIN { #define SetPrivacy(pbuf) \ *(__le16 *)(pbuf) |= cpu_to_le16(_PRIVACY_) -#define GetPrivacy(pbuf) \ - (((*(__le16 *)(pbuf)) & cpu_to_le16(_PRIVACY_)) != 0) - #define GetFrameType(pbuf) \ (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(3) | BIT(2))) -- GitLab From d664761116ea12a2417b268af2fd936fe571f612 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Wed, 30 Nov 2022 21:38:50 -0800 Subject: [PATCH 1288/1480] staging: greybus: loopback_test: Add blank line after declaration. Declarations are to be followed by a blank line. Add to follow Linux Kernel coding style. Issue reported by checkpatch. Reviewed-by: Johan Hovold Signed-off-by: Jack Schofield Link: https://lore.kernel.org/r/048967b5c3b157e19ccf4608f71da8418fc31877.1669872193.git.schofija@oregonstate.edu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/tools/loopback_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index 4c42e393cd3db..242138c4f6cf7 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -675,6 +675,7 @@ err: static int close_poll_files(struct loopback_test *t) { int i; + for (i = 0; i < t->poll_count; i++) close(t->fds[i].fd); -- GitLab From 2206c10685ab92a74ead37c30a7f817125ccd723 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Wed, 30 Nov 2022 21:38:51 -0800 Subject: [PATCH 1289/1480] staging: greybus: loopback_test: Remove void function return statement Void function return statement is not useful in this case. Issue reported by checkpatch. Reviewed-by: Johan Hovold Signed-off-by: Jack Schofield Link: https://lore.kernel.org/r/5d465d56a6e3de2cb9d2f34377cbb82678cc67b1.1669872193.git.schofija@oregonstate.edu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/tools/loopback_test.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index 242138c4f6cf7..7c1697304ab4a 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -862,7 +862,6 @@ void loopback_run(struct loopback_test *t) err: printf("Error running test\n"); - return; } static int sanity_check(struct loopback_test *t) -- GitLab From 2cb3ecf1c5fa4850073d48fb4a759fc650f08736 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Wed, 30 Nov 2022 21:38:52 -0800 Subject: [PATCH 1290/1480] staging: greybus: loopback_test: Remove extra blank lines Clean up extra uses of blank lines that do not follow the kernel coding style. Issue reported by checkpatch. Reviewed-by: Johan Hovold Signed-off-by: Jack Schofield Link: https://lore.kernel.org/r/51edbcc7583d64d3fe5a203d3a8649a695ef4a75.1669872193.git.schofija@oregonstate.edu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/tools/loopback_test.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index 7c1697304ab4a..d7ad51ff60c55 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -239,7 +239,6 @@ static void show_loopback_devices(struct loopback_test *t) for (i = 0; i < t->device_count; i++) printf("device[%d] = %s\n", i, t->devices[i].name); - } int open_sysfs(const char *sys_pfx, const char *node, int flags) @@ -274,7 +273,6 @@ float read_sysfs_float_fd(int fd, const char *sys_pfx, const char *node) char buf[SYSFS_MAX_INT]; if (read(fd, buf, sizeof(buf)) < 0) { - fprintf(stderr, "unable to read from %s%s %s\n", sys_pfx, node, strerror(errno)); close(fd); @@ -367,7 +365,6 @@ static int get_results(struct loopback_test *t) r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min; r->gbphy_firmware_latency_jitter = r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min; - } /*calculate the aggregate results of all enabled devices */ @@ -407,7 +404,6 @@ static int get_results(struct loopback_test *t) r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min; r->gbphy_firmware_latency_jitter = r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min; - } return 0; @@ -536,7 +532,6 @@ static int log_results(struct loopback_test *t) fprintf(stderr, "unable to open %s for appending\n", file_name); abort(); } - } for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) @@ -550,10 +545,8 @@ static int log_results(struct loopback_test *t) if (ret == -1) fprintf(stderr, "unable to write %d bytes to csv.\n", len); } - } - if (t->aggregate_output) { len = format_output(t, &t->aggregate_results, "aggregate", data, sizeof(data), &tm); @@ -741,7 +734,6 @@ static int wait_for_complete(struct loopback_test *t) ts = &t->poll_timeout; while (1) { - ret = ppoll(t->fds, t->poll_count, ts, &mask_old); if (ret <= 0) { stop_tests(t); @@ -781,7 +773,6 @@ static void prepare_devices(struct loopback_test *t) if (t->stop_all || device_enabled(t, i)) write_sysfs_val(t->devices[i].sysfs_entry, "type", 0); - for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; @@ -824,7 +815,6 @@ static int start(struct loopback_test *t) return 0; } - void loopback_run(struct loopback_test *t) { int i; @@ -853,7 +843,6 @@ void loopback_run(struct loopback_test *t) if (ret) goto err; - get_results(t); log_results(t); @@ -881,10 +870,8 @@ static int sanity_check(struct loopback_test *t) fprintf(stderr, "Bad device mask %x\n", (1 << i)); return -1; } - } - return 0; } -- GitLab From 64a4ade699e70b2b700cf6088916827b73988d52 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:20 +0100 Subject: [PATCH 1291/1480] staging: r8188eu: replace one GetAddr3Ptr call Define a struct ieee80211_mgmt in the OnBeacon function. Use it to replace one GetAddr3Ptr call. This is a tiny step towards making GetAddr3Ptr obsolete. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 93696892ec7dc..80342b53a129f 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -560,6 +560,7 @@ static void OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; int cam_idx; struct sta_info *psta; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -576,7 +577,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) return; } - if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { + if (!memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { /* we should update current network before auth, or some IE is wrong */ pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); -- GitLab From 84d55656bf4486eee77b783b88adebad0cf5d649 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:21 +0100 Subject: [PATCH 1292/1480] staging: r8188eu: read timestamp from ieee80211_mgmt Read the 64-bit timestamp from struct ieee80211_mgmt instead of parsing the beacon message ourselves. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 80342b53a129f..66e3a90da3a37 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -389,21 +389,6 @@ static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da) return _SUCCESS; } -static void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe) -{ - u8 *pIE; - __le32 *pbuf; - - pIE = pframe + sizeof(struct ieee80211_hdr_3addr); - pbuf = (__le32 *)pIE; - - pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1)); - - pmlmeext->TSFValue = pmlmeext->TSFValue << 32; - - pmlmeext->TSFValue |= le32_to_cpu(*pbuf); -} - static void correct_TSF(struct adapter *padapter) { u8 reg; @@ -592,8 +577,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) /* check the vendor of the assoc AP */ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr)); - /* update TSF Value */ - update_TSF(pmlmeext, pframe); + pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); /* start auth */ start_clnt_auth(padapter); @@ -635,8 +619,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) return; } - /* update TSF Value */ - update_TSF(pmlmeext, pframe); + pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); /* report sta add event */ report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); -- GitLab From 0e73b1276a51eeb649c9676e41c9e4208c8b40af Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:22 +0100 Subject: [PATCH 1293/1480] staging: r8188eu: replace GetAddr2Ptr calls Get the source address of a beacon frame from our struct ieee80211_mgmt instead of using the driver's internal GetAddr2Ptr helper. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 66e3a90da3a37..5a31b20dc46d9 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -586,7 +586,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) } if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { - psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (psta) { ret = rtw_check_bcn_info(padapter, pframe, len); if (!ret) { @@ -601,7 +601,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); } } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { - psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (psta) { /* update WMM, ERP in the beacon */ /* todo: the timer is used instead of the number of the beacon received */ @@ -621,8 +621,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); - /* report sta add event */ - report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); + report_add_sta_event(padapter, mgmt->sa, cam_idx); } } } -- GitLab From 1ed513f3e0ff13f2a84e3479b7774f213c7d7066 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:23 +0100 Subject: [PATCH 1294/1480] staging: r8188eu: pass only ies to process_p2p_ps_ie The process_p2p_ps_ie function parses the information elements of a beacon message and extracts p2p-related info. process_p2p_ps_ie does not receive a pointer to the information elements as one would expect. Instead it receives a pointer to the timestamp field in the beacon message. process_p2p_ps_ie increments this pointer by _BEACON_IE_OFFSET_ to jump to the start of the information elements (and decreases the buffer length accordingly). This is clumsy and hard to understand. Rewrite this such that process_p2p_ps_ie takes a pointer to the information elements and the total length of all elements. Check up-front that the total length is not negative. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 9 ++++++++- drivers/staging/r8188eu/core/rtw_p2p.c | 11 ++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 5a31b20dc46d9..07c57a2b61b9f 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -556,6 +556,13 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) uint len = precv_frame->len; struct wlan_bssid_ex *pbss; int ret = _SUCCESS; + u8 *ie_ptr; + u32 ie_len; + + ie_ptr = (u8 *)&mgmt->u.beacon.variable; + if (precv_frame->len < offsetof(struct ieee80211_mgmt, u.beacon.variable)) + return; + ie_len = precv_frame->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { report_survey_event(padapter, precv_frame); @@ -598,7 +605,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) /* todo: the timer is used instead of the number of the beacon received */ if ((sta_rx_pkts(psta) & 0xf) == 0) update_beacon_info(padapter, pframe, len, psta); - process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); + process_p2p_ps_ie(padapter, ie_ptr, ie_len); } } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { psta = rtw_get_stainfo(pstapriv, mgmt->sa); diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c index dc159e58f4288..ce05458bd1adc 100644 --- a/drivers/staging/r8188eu/core/rtw_p2p.c +++ b/drivers/staging/r8188eu/core/rtw_p2p.c @@ -1505,8 +1505,6 @@ void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType) void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) { - u8 *ies; - u32 ies_len; u8 *p2p_ie; u32 p2p_ielen = 0; u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */ @@ -1518,13 +1516,8 @@ void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) return; - if (IELength <= _BEACON_IE_OFFSET_) - return; - ies = IEs + _BEACON_IE_OFFSET_; - ies_len = IELength - _BEACON_IE_OFFSET_; - - p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); + p2p_ie = rtw_get_p2p_ie(IEs, IELength, NULL, &p2p_ielen); while (p2p_ie) { find_p2p = true; @@ -1579,7 +1572,7 @@ void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) } /* Get the next P2P IE */ - p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); + p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, IELength - (p2p_ie - IEs + p2p_ielen), NULL, &p2p_ielen); } if (find_p2p) { -- GitLab From 018da8b60688caec763d75cc6fb022a165028cea Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:24 +0100 Subject: [PATCH 1295/1480] staging: r8188eu: use ie buffer in update_beacon_info The update_beacon_info function parses information elements of a beacon message. It should take the pointer to the information elements and their total length, not the entire beacon message. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 4 ++-- drivers/staging/r8188eu/core/rtw_wlan_util.c | 9 +++------ drivers/staging/r8188eu/include/rtw_mlme_ext.h | 3 +-- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 07c57a2b61b9f..38dc98cffbc43 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -604,7 +604,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) /* update WMM, ERP in the beacon */ /* todo: the timer is used instead of the number of the beacon received */ if ((sta_rx_pkts(psta) & 0xf) == 0) - update_beacon_info(padapter, pframe, len, psta); + update_beacon_info(padapter, ie_ptr, ie_len, psta); process_p2p_ps_ie(padapter, ie_ptr, ie_len); } } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { @@ -613,7 +613,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) /* update WMM, ERP in the beacon */ /* todo: the timer is used instead of the number of the beacon received */ if ((sta_rx_pkts(psta) & 0xf) == 0) - update_beacon_info(padapter, pframe, len, psta); + update_beacon_info(padapter, ie_ptr, ie_len, psta); } else { /* allocate a new CAM entry for IBSS station */ cam_idx = allocate_fw_sta_entry(padapter); diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c index 965bb7da4cce3..da3465d6bb0f8 100644 --- a/drivers/staging/r8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c @@ -1035,16 +1035,13 @@ _mismatch: return _FAIL; } -void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) +void update_beacon_info(struct adapter *padapter, u8 *ie_ptr, uint ie_len, struct sta_info *psta) { unsigned int i; - unsigned int len; struct ndis_802_11_var_ie *pIE; - len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); - - for (i = 0; i < len;) { - pIE = (struct ndis_802_11_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); + for (i = 0; i < ie_len;) { + pIE = (struct ndis_802_11_var_ie *)(ie_ptr + i); switch (pIE->ElementID) { case _HT_EXTRA_INFO_IE_: /* HT info */ diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 089bd54467733..6724424a334e2 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -447,8 +447,7 @@ void HTOnAssocRsp(struct adapter *padapter); void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); void VCS_update(struct adapter *padapter, struct sta_info *psta); -void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len, - struct sta_info *psta); +void update_beacon_info(struct adapter *padapter, u8 *ie_ptr, uint ie_len, struct sta_info *psta); int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len); void update_IOT_info(struct adapter *padapter); void update_capinfo(struct adapter *adapter, u16 updatecap); -- GitLab From 02b51d08ec3a0f476c8b1537faa46e35e87e5ce0 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:25 +0100 Subject: [PATCH 1296/1480] staging: r8188eu: simplify update_sta_support_rate params The update_sta_support_rate function takes a pointer to information elements and the total length of all these elements. Use our variables for pointer and length instead of calculating them manually. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-7-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 38dc98cffbc43..f7d3ecf551bfe 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -621,7 +621,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) return; /* get supported rate */ - if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) { + if (update_sta_support_rate(padapter, ie_ptr, ie_len, cam_idx) == _FAIL) { pmlmeinfo->FW_sta_info[cam_idx].status = 0; return; } -- GitLab From 32634359a9c3d70cbf01af0ae87b27d8c0e1ebe3 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:26 +0100 Subject: [PATCH 1297/1480] staging: r8188eu: exit if beacon is not from our bss Do not process an incoming beacon message in the OnBeacon function if the beacon was sent by a base station other than the one to which we're connected. This patch does not modify the behaviour of the code. It reverts the if condition and returns if the beacon should not be processed. This is simpler than wrapping the entire processing into a large if clause. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-8-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 103 ++++++++++---------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index f7d3ecf551bfe..a15998d912a73 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -569,67 +569,68 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) return; } - if (!memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { - if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { - /* we should update current network before auth, or some IE is wrong */ - pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); - if (pbss) { - if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { - update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); - rtw_get_bcn_info(&pmlmepriv->cur_network); - } - kfree(pbss); + if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) + return; + + if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { + /* we should update current network before auth, or some IE is wrong */ + pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); + if (pbss) { + if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { + update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); + rtw_get_bcn_info(&pmlmepriv->cur_network); } + kfree(pbss); + } - /* check the vendor of the assoc AP */ - pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr)); + /* check the vendor of the assoc AP */ + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr)); - pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); + pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); - /* start auth */ - start_clnt_auth(padapter); + /* start auth */ + start_clnt_auth(padapter); - return; - } + return; + } - if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - ret = rtw_check_bcn_info(padapter, pframe, len); - if (!ret) { - receive_disconnect(padapter, - pmlmeinfo->network.MacAddress, 0); - return; - } - /* update WMM, ERP in the beacon */ - /* todo: the timer is used instead of the number of the beacon received */ - if ((sta_rx_pkts(psta) & 0xf) == 0) - update_beacon_info(padapter, ie_ptr, ie_len, psta); - process_p2p_ps_ie(padapter, ie_ptr, ie_len); + if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { + psta = rtw_get_stainfo(pstapriv, mgmt->sa); + if (psta) { + ret = rtw_check_bcn_info(padapter, pframe, len); + if (!ret) { + receive_disconnect(padapter, + pmlmeinfo->network.MacAddress, 0); + return; } - } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - /* update WMM, ERP in the beacon */ - /* todo: the timer is used instead of the number of the beacon received */ - if ((sta_rx_pkts(psta) & 0xf) == 0) - update_beacon_info(padapter, ie_ptr, ie_len, psta); - } else { - /* allocate a new CAM entry for IBSS station */ - cam_idx = allocate_fw_sta_entry(padapter); - if (cam_idx == NUM_STA) - return; + /* update WMM, ERP in the beacon */ + /* todo: the timer is used instead of the number of the beacon received */ + if ((sta_rx_pkts(psta) & 0xf) == 0) + update_beacon_info(padapter, ie_ptr, ie_len, psta); + process_p2p_ps_ie(padapter, ie_ptr, ie_len); + } + } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { + psta = rtw_get_stainfo(pstapriv, mgmt->sa); + if (psta) { + /* update WMM, ERP in the beacon */ + /* todo: the timer is used instead of the number of the beacon received */ + if ((sta_rx_pkts(psta) & 0xf) == 0) + update_beacon_info(padapter, ie_ptr, ie_len, psta); + } else { + /* allocate a new CAM entry for IBSS station */ + cam_idx = allocate_fw_sta_entry(padapter); + if (cam_idx == NUM_STA) + return; - /* get supported rate */ - if (update_sta_support_rate(padapter, ie_ptr, ie_len, cam_idx) == _FAIL) { - pmlmeinfo->FW_sta_info[cam_idx].status = 0; - return; - } + /* get supported rate */ + if (update_sta_support_rate(padapter, ie_ptr, ie_len, cam_idx) == _FAIL) { + pmlmeinfo->FW_sta_info[cam_idx].status = 0; + return; + } - pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); + pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); - report_add_sta_event(padapter, mgmt->sa, cam_idx); - } + report_add_sta_event(padapter, mgmt->sa, cam_idx); } } } -- GitLab From fa205589d5e9fc2d1b2f8d31f665152da04160bc Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:27 +0100 Subject: [PATCH 1298/1480] staging: r8188eu: stop beacon processing if kmalloc fails If we cannot allocate a struct wlan_bssid_ex in the OnBeacon function, we should stop processing the incoming beacon message and return. For kmalloc failures, the current code just skips the update of network and beacon info and tries to continue with the authentication. The update would set the encryption algorithm that should be used for the authentication. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-9-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index a15998d912a73..76424bcba416d 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -575,13 +575,14 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { /* we should update current network before auth, or some IE is wrong */ pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); - if (pbss) { - if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { - update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); - rtw_get_bcn_info(&pmlmepriv->cur_network); - } - kfree(pbss); + if (!pbss) + return; + + if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { + update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); + rtw_get_bcn_info(&pmlmepriv->cur_network); } + kfree(pbss); /* check the vendor of the assoc AP */ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr)); -- GitLab From dd99fe1f5a8319f0e236c0548cdba849451779d5 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:28 +0100 Subject: [PATCH 1299/1480] staging: r8188eu: simplify error handling for missing station Simplify the code to handle the case where we're associated to a station that is not in our list of known stations. We can simply exit in this case. This patch reverts the if-condition and saves one level of indentation. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-10-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 76424bcba416d..362313c49c526 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -597,19 +597,19 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - ret = rtw_check_bcn_info(padapter, pframe, len); - if (!ret) { - receive_disconnect(padapter, - pmlmeinfo->network.MacAddress, 0); - return; - } - /* update WMM, ERP in the beacon */ - /* todo: the timer is used instead of the number of the beacon received */ - if ((sta_rx_pkts(psta) & 0xf) == 0) - update_beacon_info(padapter, ie_ptr, ie_len, psta); - process_p2p_ps_ie(padapter, ie_ptr, ie_len); + if (!psta) + return; + + ret = rtw_check_bcn_info(padapter, pframe, len); + if (!ret) { + receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); + return; } + /* update WMM, ERP in the beacon */ + /* todo: the timer is used instead of the number of the beacon received */ + if ((sta_rx_pkts(psta) & 0xf) == 0) + update_beacon_info(padapter, ie_ptr, ie_len, psta); + process_p2p_ps_ie(padapter, ie_ptr, ie_len); } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (psta) { -- GitLab From 17c1202a9e689dc875c864c1f1e8dded70c0a8a0 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 26 Nov 2022 17:01:29 +0100 Subject: [PATCH 1300/1480] staging: r8188eu: remove a variable Check the result of rtw_check_bcn_info directly and remove the ret variable. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221126160129.178697-11-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 362313c49c526..d32b2d569e237 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -555,7 +555,6 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) u8 *pframe = precv_frame->rx_data; uint len = precv_frame->len; struct wlan_bssid_ex *pbss; - int ret = _SUCCESS; u8 *ie_ptr; u32 ie_len; @@ -600,8 +599,7 @@ static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) if (!psta) return; - ret = rtw_check_bcn_info(padapter, pframe, len); - if (!ret) { + if (rtw_check_bcn_info(padapter, pframe, len) != _SUCCESS) { receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); return; } -- GitLab From 49bd97c28b7e7f014a72821fd95fcf11e11599a4 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Sat, 19 Nov 2022 01:34:46 +0000 Subject: [PATCH 1301/1480] perf tools: Use dedicated non-atomic clear/set bit helpers Use the dedicated non-atomic helpers for {clear,set}_bit() and their test variants, i.e. the double-underscore versions. Depsite being defined in atomic.h, and despite the kernel versions being atomic in the kernel, tools' {clear,set}_bit() helpers aren't actually atomic. Move to the double-underscore versions so that the versions that are expected to be atomic (for kernel developers) can be made atomic without affecting users that don't want atomic operations. No functional change intended. Signed-off-by: Sean Christopherson Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andy Shevchenko Cc: James Morse Cc: Jiri Olsa Cc: Marc Zyngier Cc: Mark Rutland Cc: Oliver Upton Cc: Paolo Bonzini Cc: Peter Zijlstra Cc: Rasmus Villemoes Cc: Sean Christopherson Cc: Suzuki Poulouse Cc: Yury Norov Cc: alexandru elisei Cc: kvm@vger.kernel.org Cc: kvmarm@lists.cs.columbia.edu Cc: kvmarm@lists.linux.dev Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20221119013450.2643007-6-seanjc@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/find-bit-bench.c | 2 +- tools/perf/builtin-c2c.c | 6 +++--- tools/perf/builtin-kwork.c | 6 +++--- tools/perf/builtin-record.c | 6 +++--- tools/perf/builtin-sched.c | 2 +- tools/perf/tests/bitmap.c | 2 +- tools/perf/tests/mem2node.c | 2 +- tools/perf/util/affinity.c | 4 ++-- tools/perf/util/header.c | 8 ++++---- tools/perf/util/mmap.c | 6 +++--- tools/perf/util/pmu.c | 2 +- tools/perf/util/scripting-engines/trace-event-perl.c | 2 +- tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/session.c | 2 +- tools/perf/util/svghelper.c | 2 +- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tools/perf/bench/find-bit-bench.c b/tools/perf/bench/find-bit-bench.c index 22b5cfe970237..d103c3136983d 100644 --- a/tools/perf/bench/find-bit-bench.c +++ b/tools/perf/bench/find-bit-bench.c @@ -70,7 +70,7 @@ static int do_for_each_set_bit(unsigned int num_bits) bitmap_zero(to_test, num_bits); skip = num_bits / set_bits; for (i = 0; i < num_bits; i += skip) - set_bit(i, to_test); + __set_bit(i, to_test); for (i = 0; i < outer_iterations; i++) { old = accumulator; diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index a9190458d2d50..52d94c7dd8366 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -230,7 +230,7 @@ static void c2c_he__set_cpu(struct c2c_hist_entry *c2c_he, "WARNING: no sample cpu value")) return; - set_bit(sample->cpu, c2c_he->cpuset); + __set_bit(sample->cpu, c2c_he->cpuset); } static void c2c_he__set_node(struct c2c_hist_entry *c2c_he, @@ -247,7 +247,7 @@ static void c2c_he__set_node(struct c2c_hist_entry *c2c_he, if (WARN_ONCE(node < 0, "WARNING: failed to find node\n")) return; - set_bit(node, c2c_he->nodeset); + __set_bit(node, c2c_he->nodeset); if (c2c_he->paddr != sample->phys_addr) { c2c_he->paddr_cnt++; @@ -2318,7 +2318,7 @@ static int setup_nodes(struct perf_session *session) continue; perf_cpu_map__for_each_cpu(cpu, idx, map) { - set_bit(cpu.cpu, set); + __set_bit(cpu.cpu, set); if (WARN_ONCE(cpu2node[cpu.cpu] != -1, "node/cpu topology bug")) return -EINVAL; diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c index 4ffbf5908070d..0e02b80986440 100644 --- a/tools/perf/builtin-kwork.c +++ b/tools/perf/builtin-kwork.c @@ -222,7 +222,7 @@ static struct kwork_atom *atom_new(struct perf_kwork *kwork, list_add_tail(&page->list, &kwork->atom_page_list); found_atom: - set_bit(i, page->bitmap); + __set_bit(i, page->bitmap); atom->time = sample->time; atom->prev = NULL; atom->page_addr = page; @@ -235,8 +235,8 @@ static void atom_free(struct kwork_atom *atom) if (atom->prev != NULL) atom_free(atom->prev); - clear_bit(atom->bit_inpage, - ((struct kwork_atom_page *)atom->page_addr)->bitmap); + __clear_bit(atom->bit_inpage, + ((struct kwork_atom_page *)atom->page_addr)->bitmap); } static void atom_del(struct kwork_atom *atom) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bd462a3f2bbdb..b7fd7ec586fbc 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -3555,7 +3555,7 @@ static int record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cp /* Return ENODEV is input cpu is greater than max cpu */ if ((unsigned long)cpu.cpu > mask->nbits) return -ENODEV; - set_bit(cpu.cpu, mask->bits); + __set_bit(cpu.cpu, mask->bits); } return 0; @@ -3627,8 +3627,8 @@ static int record__init_thread_cpu_masks(struct record *rec, struct perf_cpu_map pr_debug("nr_threads: %d\n", rec->nr_threads); for (t = 0; t < rec->nr_threads; t++) { - set_bit(perf_cpu_map__cpu(cpus, t).cpu, rec->thread_masks[t].maps.bits); - set_bit(perf_cpu_map__cpu(cpus, t).cpu, rec->thread_masks[t].affinity.bits); + __set_bit(perf_cpu_map__cpu(cpus, t).cpu, rec->thread_masks[t].maps.bits); + __set_bit(perf_cpu_map__cpu(cpus, t).cpu, rec->thread_masks[t].affinity.bits); if (verbose) { pr_debug("thread_masks[%d]: ", t); mmap_cpu_mask__scnprintf(&rec->thread_masks[t].maps, "maps"); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f93737eef07ba..86e18575c9bee 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1573,7 +1573,7 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel, if (sched->map.comp) { cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS); - if (!test_and_set_bit(this_cpu.cpu, sched->map.comp_cpus_mask)) { + if (!__test_and_set_bit(this_cpu.cpu, sched->map.comp_cpus_mask)) { sched->map.comp_cpus[cpus_nr++] = this_cpu; new_cpu = true; } diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 4965dd6669566..0173f5402a35b 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -18,7 +18,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) if (map && bm) { for (i = 0; i < perf_cpu_map__nr(map); i++) - set_bit(perf_cpu_map__cpu(map, i).cpu, bm); + __set_bit(perf_cpu_map__cpu(map, i).cpu, bm); } if (map) diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 4c96829510c91..a0e88c4961074 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -33,7 +33,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) int i; perf_cpu_map__for_each_cpu(cpu, i, map) - set_bit(cpu.cpu, bm); + __set_bit(cpu.cpu, bm); } if (map) diff --git a/tools/perf/util/affinity.c b/tools/perf/util/affinity.c index 4ee96b3c755b7..38dc4524b7e86 100644 --- a/tools/perf/util/affinity.c +++ b/tools/perf/util/affinity.c @@ -58,14 +58,14 @@ void affinity__set(struct affinity *a, int cpu) return; a->changed = true; - set_bit(cpu, a->sched_cpus); + __set_bit(cpu, a->sched_cpus); /* * We ignore errors because affinity is just an optimization. * This could happen for example with isolated CPUs or cpusets. * In this case the IPIs inside the kernel's perf API still work. */ sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->sched_cpus); - clear_bit(cpu, a->sched_cpus); + __clear_bit(cpu, a->sched_cpus); } static void __affinity__cleanup(struct affinity *a) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 98dfaf84bd137..dc2ae397d400e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -79,12 +79,12 @@ struct perf_file_attr { void perf_header__set_feat(struct perf_header *header, int feat) { - set_bit(feat, header->adds_features); + __set_bit(feat, header->adds_features); } void perf_header__clear_feat(struct perf_header *header, int feat) { - clear_bit(feat, header->adds_features); + __clear_bit(feat, header->adds_features); } bool perf_header__has_feat(const struct perf_header *header, int feat) @@ -1358,7 +1358,7 @@ static int memory_node__read(struct memory_node *n, unsigned long idx) rewinddir(dir); for_each_memory(phys, dir) { - set_bit(phys, n->set); + __set_bit(phys, n->set); } closedir(dir); @@ -3952,7 +3952,7 @@ int perf_file_header__read(struct perf_file_header *header, if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { bitmap_zero(header->adds_features, HEADER_FEAT_BITS); - set_bit(HEADER_BUILD_ID, header->adds_features); + __set_bit(HEADER_BUILD_ID, header->adds_features); } } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index a4dff881be39b..49093b21ee2da 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -111,7 +111,7 @@ static int perf_mmap__aio_bind(struct mmap *map, int idx, struct perf_cpu cpu, i pr_err("Failed to allocate node mask for mbind: error %m\n"); return -1; } - set_bit(node_index, node_mask); + __set_bit(node_index, node_mask); if (mbind(data, mmap_len, MPOL_BIND, node_mask, node_index + 1 + 1, 0)) { pr_err("Failed to bind [%p-%p] AIO buffer to node %lu: error %m\n", data, data + mmap_len, node_index); @@ -256,7 +256,7 @@ static void build_node_mask(int node, struct mmap_cpu_mask *mask) for (idx = 0; idx < nr_cpus; idx++) { cpu = perf_cpu_map__cpu(cpu_map, idx); /* map c index to online cpu index */ if (cpu__get_node(cpu) == node) - set_bit(cpu.cpu, mask->bits); + __set_bit(cpu.cpu, mask->bits); } } @@ -270,7 +270,7 @@ static int perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params * if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask); else if (mp->affinity == PERF_AFFINITY_CPU) - set_bit(map->core.cpu.cpu, map->affinity_mask.bits); + __set_bit(map->core.cpu.cpu, map->affinity_mask.bits); return 0; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index e9a4f31926bf4..8ff6462f051e1 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1533,7 +1533,7 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to) memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS)); for (b = from; b <= to; b++) - set_bit(b, bits); + __set_bit(b, bits); } void perf_pmu__del_formats(struct list_head *formats) diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index a5d945415bbc1..5b602b6d46854 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -365,7 +365,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, sprintf(handler, "%s::%s", event->system, event->name); - if (!test_and_set_bit(event->id, events_defined)) + if (!__test_and_set_bit(event->id, events_defined)) define_event_symbols(event, handler, event->print_fmt.args); s = nsecs / NSEC_PER_SEC; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 1cf65db8f861d..d685a7399ee2e 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -934,7 +934,7 @@ static void python_process_tracepoint(struct perf_sample *sample, sprintf(handler_name, "%s__%s", event->system, event->name); - if (!test_and_set_bit(event->id, events_defined)) + if (!__test_and_set_bit(event->id, events_defined)) define_event_symbols(event, handler_name, event->print_fmt.args); handler = get_handler(handler_name); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0e1a3d6bacb92..1facd4616317d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2749,7 +2749,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, goto out_delete_map; } - set_bit(cpu.cpu, cpu_bitmap); + __set_bit(cpu.cpu, cpu_bitmap); } err = 0; diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 1e0c731fc5396..5c62d3118c41f 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -741,7 +741,7 @@ static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus) break; } - set_bit(c.cpu, cpumask_bits(b)); + __set_bit(c.cpu, cpumask_bits(b)); } perf_cpu_map__put(m); -- GitLab From 4de531ce41e5aab9d3c5884e8360faaec82fb62e Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 29 Nov 2022 21:51:48 +0100 Subject: [PATCH 1302/1480] staging: r8188eu: use ieee80211_mgmt to parse addresses Define a struct ieee80211_mgmt in the OnDisassoc function and use it to parse the addresses in the incoming disassoc message. This replaces some driver-specific functions for address parsing. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221129205152.128172-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index d32b2d569e237..b2b2cb57ed044 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1427,6 +1427,7 @@ static void OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; u16 reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1434,8 +1435,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) u8 *pframe = precv_frame->rx_data; struct wifidirect_info *pwdinfo = &padapter->wdinfo; - /* check A3 */ - if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) return; if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { @@ -1449,7 +1449,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; - psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + psta = rtw_get_stainfo(pstapriv, mgmt->sa); if (psta) { u8 updated = 0; @@ -1466,7 +1466,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) return; } else { - receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); + receive_disconnect(padapter, mgmt->bssid, reason); } pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } -- GitLab From e70cac829d63f24aac0ea858a5407d25cf55b85a Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 29 Nov 2022 21:51:49 +0100 Subject: [PATCH 1303/1480] staging: r8188eu: read reason code from ieee80211_mgmt Use the struct ieee80211_mgmt to read the reason code instead of parsing the message manually. Remove the pframe pointer, it's no longer used. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221129205152.128172-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index b2b2cb57ed044..fe58d4e3e2604 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1432,7 +1432,6 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - u8 *pframe = precv_frame->rx_data; struct wifidirect_info *pwdinfo = &padapter->wdinfo; if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) @@ -1443,7 +1442,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); } - reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); + reason = le16_to_cpu(mgmt->u.disassoc.reason_code); if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { struct sta_info *psta; -- GitLab From 8f7f05934ea24676c5c259a66bd71fa35ee22ef3 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 29 Nov 2022 21:51:50 +0100 Subject: [PATCH 1304/1480] staging: r8188eu: move bBusyTraffic update Move the update of bBusyTraffic into the else branch. The if branch ends with a return statement, so bBusyTraffic will not be updated in this case. With this change in place, we can reorder the code and save some levels of indentation. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221129205152.128172-4-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index fe58d4e3e2604..dd1e0b4fc5a09 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1466,8 +1466,8 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) return; } else { receive_disconnect(padapter, mgmt->bssid, reason); + pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } - pmlmepriv->LinkDetectInfo.bBusyTraffic = false; } static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) -- GitLab From 17580de3e2b876247f2201b6486559ef1e6b7f58 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 29 Nov 2022 21:51:51 +0100 Subject: [PATCH 1305/1480] staging: r8188eu: handle the non-ap case first The OnDisassoc function hasn't got much to do if we're not working as an access point. Move this case out of the large if statement to simplify the code. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221129205152.128172-5-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 36 ++++++++++----------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index dd1e0b4fc5a09..d5c9eb52fb0e4 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1433,6 +1433,8 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) return; @@ -1444,29 +1446,25 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) reason = le16_to_cpu(mgmt->u.disassoc.reason_code); - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - struct sta_info *psta; - struct sta_priv *pstapriv = &padapter->stapriv; - - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - u8 updated = 0; + if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + receive_disconnect(padapter, mgmt->bssid, reason); + pmlmepriv->LinkDetectInfo.bBusyTraffic = false; + return; + } - spin_lock_bh(&pstapriv->asoc_list_lock); - if (!list_empty(&psta->asoc_list)) { - list_del_init(&psta->asoc_list); - pstapriv->asoc_list_cnt--; - updated = ap_free_sta(padapter, psta, false, reason); - } - spin_unlock_bh(&pstapriv->asoc_list_lock); + psta = rtw_get_stainfo(pstapriv, mgmt->sa); + if (psta) { + u8 updated = 0; - associated_clients_update(padapter, updated); + spin_lock_bh(&pstapriv->asoc_list_lock); + if (!list_empty(&psta->asoc_list)) { + list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, false, reason); } + spin_unlock_bh(&pstapriv->asoc_list_lock); - return; - } else { - receive_disconnect(padapter, mgmt->bssid, reason); - pmlmepriv->LinkDetectInfo.bBusyTraffic = false; + associated_clients_update(padapter, updated); } } -- GitLab From 30b28fd639abf51464f015f6bebd7506bc895be2 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 29 Nov 2022 21:51:52 +0100 Subject: [PATCH 1306/1480] staging: r8188eu: simplify err handling for unknown station If we receive a disassoc message from an unknown station, we can drop this message immediately. Reorder the code to make this clearer. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221129205152.128172-6-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index d5c9eb52fb0e4..49e0b50b1243e 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -1435,6 +1435,7 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) struct wifidirect_info *pwdinfo = &padapter->wdinfo; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; + u8 updated = 0; if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) return; @@ -1453,19 +1454,18 @@ static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) } psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (psta) { - u8 updated = 0; - - spin_lock_bh(&pstapriv->asoc_list_lock); - if (!list_empty(&psta->asoc_list)) { - list_del_init(&psta->asoc_list); - pstapriv->asoc_list_cnt--; - updated = ap_free_sta(padapter, psta, false, reason); - } - spin_unlock_bh(&pstapriv->asoc_list_lock); + if (!psta) + return; - associated_clients_update(padapter, updated); + spin_lock_bh(&pstapriv->asoc_list_lock); + if (!list_empty(&psta->asoc_list)) { + list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, false, reason); } + spin_unlock_bh(&pstapriv->asoc_list_lock); + + associated_clients_update(padapter, updated); } static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) -- GitLab From 20ed9fa4965875fdde5bfd65d838465e38d46b22 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 30 Nov 2022 16:51:58 +0000 Subject: [PATCH 1307/1480] perf branch: Fix interpretation of branch records Commit 93315e46b000fc80 ("perf/core: Add speculation info to branch entries") added a new field in between type and new_type. Perf has its own copy of this struct so update it to match the kernel side. This doesn't currently cause any issues because new_type is only used by the Arm BRBE driver which isn't merged yet. Committer notes: Is this really an ABI? How are we supposed to deal with old perf.data files with new tools and vice versa? :-\ Fixes: 93315e46b000fc80 ("perf/core: Add speculation info to branch entries") Reviewed-by: Anshuman Khandual Signed-off-by: James Clark Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Sandipan Das Link: https://lore.kernel.org/r/20221130165158.517385-1-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/branch.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index d6017c9b1872d..3ed792db11255 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -22,9 +22,10 @@ struct branch_flags { u64 abort:1; u64 cycles:16; u64 type:4; + u64 spec:2; u64 new_type:4; u64 priv:3; - u64 reserved:33; + u64 reserved:31; }; }; }; -- GitLab From 7e8e5e879729b238cd17dcc292d86c1e6cc83ecc Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Mon, 28 Dec 2020 03:39:41 +0100 Subject: [PATCH 1308/1480] perf arm64: Fix mksyscalltbl, don't lose syscalls due to sort -nu When using "sort -nu", arm64 syscalls were lost. That is, the io_setup syscall (number 0) and all but one (typically ftruncate; 64) of the syscalls that are defined symbolically (like "#define __NR_ftruncate __NR3264_ftruncate") at the point where "sort" is applied. This creation-of-syscalls.c-scheme is, judging from comments, copy-pasted from powerpc, and worked there because at the time, its tools/arch/powerpc/include/uapi/asm/unistd.h had *literals*, like "#define __NR_ftruncate 93". With sort being numeric and the non-numeric key effectively evaluating to 0, the sort option "-u" means these "duplicates" are removed. There's no need to remove syscall lines with duplicate numbers for arm64 because there are none, so let's fix that by just losing the "-u". Having the table numerically sorted on syscall-number for the rest of the syscalls looks nice, so keep the "-n". Reviewed-by: Leo Yan Signed-off-by: Hans-Peter Nilsson Tested-by: Leo Yan Acked-by: Arnd Bergmann Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Garry Cc: Kim Phillips Cc: Leo Yan Cc: Mark Rutland Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20201228023941.E0DE2203B5@pchp3.se.axis.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/entry/syscalls/mksyscalltbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl index 459469b7222c1..a7ca48d1e37bc 100755 --- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl +++ b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl @@ -58,5 +58,5 @@ create_table() $gcc -E -dM -x c -I $incpath/include/uapi $input \ |sed -ne 's/^#define __NR_//p' \ - |sort -t' ' -k2 -nu \ + |sort -t' ' -k2 -n \ |create_table -- GitLab From 3f48ad1f243d07d6018a4af2762b6538febde689 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Fri, 2 Dec 2022 10:25:24 +0100 Subject: [PATCH 1309/1480] staging: r8188eu: merge two probereq_p2p functions _issue_probereq_p2p is called only by issue_probereq_p2p. Merge the two functions and remove the unused return value. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221202092525.403887-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 49e0b50b1243e..cf7b39cfb8f4c 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3183,9 +3183,8 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da) dump_mgntframe(padapter, pmgntframe); } -static int _issue_probereq_p2p(struct adapter *padapter, u8 *da) +inline void issue_probereq_p2p(struct adapter *padapter, u8 *da) { - int ret = _FAIL; struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; unsigned char *pframe; @@ -3201,7 +3200,7 @@ static int _issue_probereq_p2p(struct adapter *padapter, u8 *da) pmgntframe = alloc_mgtxmitframe(pxmitpriv); if (!pmgntframe) - goto exit; + return; /* update attribute */ pattrib = &pmgntframe->attrib; @@ -3457,15 +3456,6 @@ static int _issue_probereq_p2p(struct adapter *padapter, u8 *da) pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); - ret = _SUCCESS; - -exit: - return ret; -} - -inline void issue_probereq_p2p(struct adapter *adapter, u8 *da) -{ - _issue_probereq_p2p(adapter, da); } static s32 rtw_action_public_decache(struct recv_frame *recv_frame, u8 token) -- GitLab From 3d0862367ab8af1144c0e5495b8bf0e2ce892afe Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Fri, 2 Dec 2022 10:25:25 +0100 Subject: [PATCH 1310/1480] staging: r8188eu: remove unused da parameter All callers of issue_probereq_p2p set the da parameter to NULL. Remove this parameters and the code that runs only for da != NULL. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221202092525.403887-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 28 ++++++++----------- drivers/staging/r8188eu/core/rtw_p2p.c | 8 +++--- .../staging/r8188eu/include/rtw_mlme_ext.h | 2 +- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index cf7b39cfb8f4c..95a9470f4c993 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -3183,7 +3183,7 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da) dump_mgntframe(padapter, pmgntframe); } -inline void issue_probereq_p2p(struct adapter *padapter, u8 *da) +inline void issue_probereq_p2p(struct adapter *padapter) { struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; @@ -3216,20 +3216,16 @@ inline void issue_probereq_p2p(struct adapter *padapter, u8 *da) fctrl = &pwlanhdr->frame_control; *(fctrl) = 0; - if (da) { - memcpy(pwlanhdr->addr1, da, ETH_ALEN); - memcpy(pwlanhdr->addr3, da, ETH_ALEN); + if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { + /* This two flags will be set when this is only the P2P client mode. */ + memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); + memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); } else { - if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { - /* This two flags will be set when this is only the P2P client mode. */ - memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); - memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); - } else { - /* broadcast probe request frame */ - eth_broadcast_addr(pwlanhdr->addr1); - eth_broadcast_addr(pwlanhdr->addr3); - } + /* broadcast probe request frame */ + eth_broadcast_addr(pwlanhdr->addr1); + eth_broadcast_addr(pwlanhdr->addr3); } + memcpy(pwlanhdr->addr2, mac, ETH_ALEN); SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); @@ -5867,9 +5863,9 @@ void site_survey(struct adapter *padapter) if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { - issue_probereq_p2p(padapter, NULL); - issue_probereq_p2p(padapter, NULL); - issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter); + issue_probereq_p2p(padapter); + issue_probereq_p2p(padapter); } else { int i; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c index ce05458bd1adc..93d3c9c4399cf 100644 --- a/drivers/staging/r8188eu/core/rtw_p2p.c +++ b/drivers/staging/r8188eu/core/rtw_p2p.c @@ -1453,7 +1453,7 @@ static void pre_tx_invitereq_handler(struct adapter *padapter) set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter); _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); } @@ -1464,7 +1464,7 @@ static void pre_tx_provdisc_handler(struct adapter *padapter) set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter); _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); } @@ -1475,7 +1475,7 @@ static void pre_tx_negoreq_handler(struct adapter *padapter) set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter); _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); } @@ -1725,7 +1725,7 @@ static void pre_tx_scan_timer_process(struct timer_list *t) if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { if (pwdinfo->tx_prov_disc_info.benable) { /* the provision discovery request frame is trigger to send or not */ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK); - /* issue_probereq_p2p(adapter, NULL); */ + /* issue_probereq_p2p(adapter); */ /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */ } } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h index 6724424a334e2..589de7c54d930 100644 --- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h @@ -497,7 +497,7 @@ void issue_probersp_p2p(struct adapter *padapter, unsigned char *da); void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr); void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr); -void issue_probereq_p2p(struct adapter *padapter, u8 *da); +void issue_probereq_p2p(struct adapter *padapter); void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 success); void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr); -- GitLab From eb0b3f501e4dd5e6668bddbbb3c20ecd1545b60d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 30 Nov 2022 11:36:13 -0800 Subject: [PATCH 1311/1480] Revert "perf stat: Rename "aggregate-number" to "cpu-count" in JSON" This reverts commit c4b41b83c25073c09bfcc4e5ec496c9dd316656b. As Ian said, the "cpu-count" is not appropriate for uncore events, also it caused a perf test failure. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221130193613.1046804-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 847acdb5dc407..f1ee4b0521986 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -281,19 +281,19 @@ static void print_aggr_id_json(struct perf_stat_config *config, switch (config->aggr_mode) { case AGGR_CORE: - fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"cpu-count\" : %d, ", + fprintf(output, "\"core\" : \"S%d-D%d-C%d\", \"aggregate-number\" : %d, ", id.socket, id.die, id.core, nr); break; case AGGR_DIE: - fprintf(output, "\"die\" : \"S%d-D%d\", \"cpu-count\" : %d, ", + fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ", id.socket, id.die, nr); break; case AGGR_SOCKET: - fprintf(output, "\"socket\" : \"S%d\", \"cpu-count\" : %d, ", + fprintf(output, "\"socket\" : \"S%d\", \"aggregate-number\" : %d, ", id.socket, nr); break; case AGGR_NODE: - fprintf(output, "\"node\" : \"N%d\", \"cpu-count\" : %d, ", + fprintf(output, "\"node\" : \"N%d\", \"aggregate-number\" : %d, ", id.node, nr); break; case AGGR_NONE: -- GitLab From 506783ffa96f953eea94d6ff99c4e908965fc383 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Fri, 2 Dec 2022 10:31:58 +0100 Subject: [PATCH 1312/1480] staging: r8188eu: use subtype helpers in collect_bss_info Use the iee80211 helper functions to check the frame subtype in collect_bss_info. Replace the call to the driver-specific GetFrameSubType function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221202093159.404111-2-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 26 +++++++++------------ 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c index 95a9470f4c993..1b9cf7596a76e 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c @@ -5963,10 +5963,11 @@ void site_survey(struct adapter *padapter) /* collect bss info from Beacon and Probe request/response frames. */ u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; int i; u32 len; u8 *p; - u16 val16, subtype; + u16 val16; u8 *pframe = precv_frame->rx_data; u32 packet_len = precv_frame->len; u8 ie_offset; @@ -5982,23 +5983,18 @@ u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, st memset(bssid, 0, sizeof(struct wlan_bssid_ex)); - subtype = GetFrameSubType(pframe); - - if (subtype == WIFI_BEACON) { + if (ieee80211_is_beacon(mgmt->frame_control)) { bssid->Reserved[0] = 1; ie_offset = _BEACON_IE_OFFSET_; + } else if (ieee80211_is_probe_req(mgmt->frame_control)) { + ie_offset = _PROBEREQ_IE_OFFSET_; + bssid->Reserved[0] = 2; + } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { + ie_offset = _PROBERSP_IE_OFFSET_; + bssid->Reserved[0] = 3; } else { - /* FIXME : more type */ - if (subtype == WIFI_PROBEREQ) { - ie_offset = _PROBEREQ_IE_OFFSET_; - bssid->Reserved[0] = 2; - } else if (subtype == WIFI_PROBERSP) { - ie_offset = _PROBERSP_IE_OFFSET_; - bssid->Reserved[0] = 3; - } else { - bssid->Reserved[0] = 0; - ie_offset = _FIXED_IE_LENGTH_; - } + bssid->Reserved[0] = 0; + ie_offset = _FIXED_IE_LENGTH_; } bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; -- GitLab From 7868f8f858968066b23287c9733e777a8407384c Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Fri, 2 Dec 2022 10:31:59 +0100 Subject: [PATCH 1313/1480] staging: r8188eu: use subtype helper in rtw_check_bcn_info Use ieee80211_is_beacon to check the frame subtype in rtw_check_bcn_info. Replace the call to the driver-specific GetFrameSubType function. Tested-by: Philipp Hortmann # Edimax N150 Signed-off-by: Martin Kaiser Link: https://lore.kernel.org/r/20221202093159.404111-3-martin@kaiser.cx Signed-off-by: Greg Kroah-Hartman --- drivers/staging/r8188eu/core/rtw_wlan_util.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c index da3465d6bb0f8..f1ebb5358cb9a 100644 --- a/drivers/staging/r8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c @@ -874,9 +874,10 @@ void VCS_update(struct adapter *padapter, struct sta_info *psta) int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) { + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)pframe; unsigned int len; unsigned char *p; - unsigned short val16, subtype; + unsigned short val16; struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network; /* u8 wpa_ie[255], rsn_ie[255]; */ u16 wpa_len = 0, rsn_len = 0; @@ -908,9 +909,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) if (!bssid) return _FAIL; - subtype = GetFrameSubType(pframe) >> 4; - - if (subtype == WIFI_BEACON) + if (ieee80211_is_beacon(mgmt->frame_control)) bssid->Reserved[0] = 1; bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; -- GitLab From bf44039f1ee828c47e1eb83eb315f0fed5a66126 Mon Sep 17 00:00:00 2001 From: Matt Jan Date: Sun, 4 Dec 2022 18:19:16 +0800 Subject: [PATCH 1314/1480] staging: vme_user: remove multiple blank lines Remove multiple unnecessary blank lines in accordance with the Linux kernel coding-style regulations. The issues were reported by the checkpatch script. Signed-off-by: Matt Jan Link: https://lore.kernel.org/r/20221204101916.GA51992@zoo868e Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme_user/vme.h | 2 -- drivers/staging/vme_user/vme_fake.c | 5 ----- drivers/staging/vme_user/vme_tsi148.c | 6 ------ drivers/staging/vme_user/vme_tsi148.h | 7 ------- 4 files changed, 20 deletions(-) diff --git a/drivers/staging/vme_user/vme.h b/drivers/staging/vme_user/vme.h index b204a9b4be1bd..98da8d039d606 100644 --- a/drivers/staging/vme_user/vme.h +++ b/drivers/staging/vme_user/vme.h @@ -27,7 +27,6 @@ enum vme_resource_type { #define VME_A64_MAX 0x10000000000000000ULL #define VME_CRCSR_MAX 0x1000000ULL - /* VME Cycle Types */ #define VME_SCT 0x1 #define VME_BLT 0x2 @@ -185,6 +184,5 @@ int vme_bus_num(struct vme_dev *); int vme_register_driver(struct vme_driver *, unsigned int); void vme_unregister_driver(struct vme_driver *); - #endif /* _VME_H_ */ diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index dd646b0c531d4..a9d3a7f5c440f 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -356,7 +356,6 @@ static int __fake_master_get(struct vme_master_resource *image, int *enabled, return 0; } - static int fake_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, u32 *aspace, u32 *cycle, u32 *dwidth) @@ -373,7 +372,6 @@ static int fake_master_get(struct vme_master_resource *image, int *enabled, return retval; } - static void fake_lm_check(struct fake_driver *bridge, unsigned long long addr, u32 aspace, u32 cycle) { @@ -1060,7 +1058,6 @@ static void fake_crcsr_exit(struct vme_bridge *fake_bridge) kfree(bridge->crcsr_kernel); } - static int __init fake_init(void) { int retval, i; @@ -1238,7 +1235,6 @@ err_struct: } - static void __exit fake_exit(void) { struct list_head *pos = NULL; @@ -1294,7 +1290,6 @@ static void __exit fake_exit(void) root_device_unregister(vme_root); } - MODULE_PARM_DESC(geoid, "Set geographical addressing"); module_param(geoid, int, 0); diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c index 0171f46d1848f..482049cfc6640 100644 --- a/drivers/staging/vme_user/vme_tsi148.c +++ b/drivers/staging/vme_user/vme_tsi148.c @@ -34,7 +34,6 @@ static int tsi148_probe(struct pci_dev *, const struct pci_device_id *); static void tsi148_remove(struct pci_dev *); - /* Module parameter */ static bool err_chk; static int geoid; @@ -673,7 +672,6 @@ static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, /* Need granularity before we set the size */ *size = (unsigned long long)((vme_bound - *vme_base) + granularity); - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160) *cycle |= VME_2eSST160; if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267) @@ -1142,7 +1140,6 @@ static int __tsi148_master_get(struct vme_master_resource *image, int *enabled, return 0; } - static int tsi148_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, u32 *aspace, u32 *cycle, u32 *dwidth) @@ -1244,7 +1241,6 @@ out: return retval; } - static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, size_t count, loff_t offset) { @@ -2000,7 +1996,6 @@ static int tsi148_lm_get(struct vme_lm_resource *lm, if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) *aspace |= VME_A64; - if (lm_ctl & TSI148_LCSR_LMAT_SUPR) *cycle |= VME_SUPER; if (lm_ctl & TSI148_LCSR_LMAT_NPRIV) @@ -2551,7 +2546,6 @@ static void tsi148_remove(struct pci_dev *pdev) bridge = tsi148_bridge->driver_priv; - dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); /* diff --git a/drivers/staging/vme_user/vme_tsi148.h b/drivers/staging/vme_user/vme_tsi148.h index 226fedc6f1671..b3cb4a089cc86 100644 --- a/drivers/staging/vme_user/vme_tsi148.h +++ b/drivers/staging/vme_user/vme_tsi148.h @@ -87,7 +87,6 @@ struct tsi148_dma_entry { * Control and Status Registers */ - /* * Command/Status Registers (CRG + $004) */ @@ -342,7 +341,6 @@ static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, #define TSI148_LCSR_IT7_ITOFL 0x3F4 #define TSI148_LCSR_IT7_ITAT 0x3F8 - #define TSI148_LCSR_IT0 0x300 #define TSI148_LCSR_IT1 0x320 #define TSI148_LCSR_IT2 0x340 @@ -464,7 +462,6 @@ static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, #define TSI148_LCSR_DMA0 0x500 #define TSI148_LCSR_DMA1 0x580 - static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0, TSI148_LCSR_DMA1 }; @@ -532,9 +529,6 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_CSRBSR 0xFF8 #define TSI148_CBAR 0xFFC - - - /* * TSI148 Register Bit Definitions */ @@ -828,7 +822,6 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */ #define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */ - /* * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280 */ -- GitLab From 7bef797d707f1744f71156b21d41e3b8c946631f Mon Sep 17 00:00:00 2001 From: Chen Zhongjin Date: Mon, 5 Dec 2022 16:48:05 +0800 Subject: [PATCH 1315/1480] vme: Fix error not catched in fake_init() In fake_init(), __root_device_register() is possible to fail but it's ignored, which can cause unregistering vme_root fail when exit. general protection fault, probably for non-canonical address 0xdffffc000000008c KASAN: null-ptr-deref in range [0x0000000000000460-0x0000000000000467] RIP: 0010:root_device_unregister+0x26/0x60 Call Trace: __x64_sys_delete_module+0x34f/0x540 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Return error when __root_device_register() fails. Fixes: 658bcdae9c67 ("vme: Adding Fake VME driver") Signed-off-by: Chen Zhongjin Link: https://lore.kernel.org/r/20221205084805.147436-1-chenzhongjin@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme_user/vme_fake.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index a9d3a7f5c440f..6454ccf6e5b4b 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -1070,6 +1070,8 @@ static int __init fake_init(void) /* We need a fake parent device */ vme_root = __root_device_register("vme", THIS_MODULE); + if (IS_ERR(vme_root)) + return PTR_ERR(vme_root); /* If we want to support more than one bridge at some point, we need to * dynamically allocate this so we get one per device. -- GitLab From 8f8bcc8c720c360885639de66fe69756febed824 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 5 Dec 2022 11:29:16 -0400 Subject: [PATCH 1316/1480] vfio/pci: Move all the SPAPR PCI specific logic to vfio_pci_core.ko The vfio_spapr_pci_eeh_open/release() functions are one line wrappers around an arch function. Just call them directly. This eliminates some weird exported symbols that don't need to exist. Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/1-v5-fc5346cacfd4+4c482-vfio_modules_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci_core.c | 11 +++++++++-- drivers/vfio/vfio_spapr_eeh.c | 13 ------------- include/linux/vfio.h | 11 ----------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 189d4930c276d..56501e7ef5645 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -27,6 +27,9 @@ #include #include #include +#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) +#include +#endif #include "vfio_pci_priv.h" @@ -686,7 +689,9 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) vdev->sriov_pf_core_dev->vf_token->users--; mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock); } - vfio_spapr_pci_eeh_release(vdev->pdev); +#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) + eeh_dev_release(vdev->pdev); +#endif vfio_pci_core_disable(vdev); mutex_lock(&vdev->igate); @@ -705,7 +710,9 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_close_device); void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev) { vfio_pci_probe_mmaps(vdev); - vfio_spapr_pci_eeh_open(vdev->pdev); +#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) + eeh_dev_open(vdev->pdev); +#endif if (vdev->sriov_pf_core_dev) { mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock); diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c index 67f55ac1d459c..c9d102aafbcd1 100644 --- a/drivers/vfio/vfio_spapr_eeh.c +++ b/drivers/vfio/vfio_spapr_eeh.c @@ -15,19 +15,6 @@ #define DRIVER_AUTHOR "Gavin Shan, IBM Corporation" #define DRIVER_DESC "VFIO IOMMU SPAPR EEH" -/* We might build address mapping here for "fast" path later */ -void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) -{ - eeh_dev_open(pdev); -} -EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_open); - -void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) -{ - eeh_dev_release(pdev); -} -EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_release); - long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, unsigned int cmd, unsigned long arg) { diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 43b67e46a2cb5..9378ca79d5480 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -233,21 +233,10 @@ int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, int max_irq_type, size_t *data_size); -struct pci_dev; #if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) -void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); -void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, unsigned int cmd, unsigned long arg); #else -static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) -{ -} - -static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) -{ -} - static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, unsigned int cmd, unsigned long arg) -- GitLab From e5c38a203eb4343993e889eb69f5386f085f25ef Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 5 Dec 2022 11:29:17 -0400 Subject: [PATCH 1317/1480] vfio/spapr: Move VFIO_CHECK_EXTENSION into tce_iommu_ioctl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PPC64 kconfig is a bit of a rats nest, but it turns out that if CONFIG_SPAPR_TCE_IOMMU is on then EEH must be too: config SPAPR_TCE_IOMMU bool "sPAPR TCE IOMMU Support" depends on PPC_POWERNV || PPC_PSERIES select IOMMU_API help Enables bits of IOMMU API required by VFIO. The iommu_ops is not implemented as it is not necessary for VFIO. config PPC_POWERNV select FORCE_PCI config PPC_PSERIES select FORCE_PCI config EEH bool depends on (PPC_POWERNV || PPC_PSERIES) && PCI default y So, just open code the call to eeh_enabled() into tce_iommu_ioctl(). Reviewed-by: Christoph Hellwig Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Cornelia Huck Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/2-v5-fc5346cacfd4+4c482-vfio_modules_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/vfio_iommu_spapr_tce.c | 10 ++++------ drivers/vfio/vfio_spapr_eeh.c | 6 ------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 169f07ac162d9..73cec2beae70b 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -785,14 +785,12 @@ static long tce_iommu_ioctl(void *iommu_data, switch (arg) { case VFIO_SPAPR_TCE_IOMMU: case VFIO_SPAPR_TCE_v2_IOMMU: - ret = 1; - break; + return 1; + case VFIO_EEH: + return eeh_enabled(); default: - ret = vfio_spapr_iommu_eeh_ioctl(NULL, cmd, arg); - break; + return 0; } - - return (ret < 0) ? 0 : ret; } /* diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c index c9d102aafbcd1..221b1b637e18b 100644 --- a/drivers/vfio/vfio_spapr_eeh.c +++ b/drivers/vfio/vfio_spapr_eeh.c @@ -24,12 +24,6 @@ long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, long ret = -EINVAL; switch (cmd) { - case VFIO_CHECK_EXTENSION: - if (arg == VFIO_EEH) - ret = eeh_enabled() ? 1 : 0; - else - ret = 0; - break; case VFIO_EEH_PE_OP: pe = eeh_iommu_group_to_pe(group); if (!pe) -- GitLab From e276e25819b8a173a21947720bb0a548c0b724b7 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 5 Dec 2022 11:29:18 -0400 Subject: [PATCH 1318/1480] vfio: Move vfio_spapr_iommu_eeh_ioctl into vfio_iommu_spapr_tce.c As with the previous patch EEH is always enabled if SPAPR_TCE_IOMMU, so move this last bit of code into the main module. Now that this function only processes VFIO_EEH_PE_OP remove a level of indenting as well, it is only called by a case statement that already checked VFIO_EEH_PE_OP. This eliminates an unnecessary module and SPAPR code in a global header. Reviewed-by: Christoph Hellwig Reviewed-by: Cornelia Huck Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/3-v5-fc5346cacfd4+4c482-vfio_modules_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/Makefile | 1 - drivers/vfio/vfio_iommu_spapr_tce.c | 55 +++++++++++++++++- drivers/vfio/vfio_spapr_eeh.c | 88 ----------------------------- include/linux/vfio.h | 12 ---- 4 files changed, 53 insertions(+), 103 deletions(-) delete mode 100644 drivers/vfio/vfio_spapr_eeh.c diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index b693a1169286f..50b8e8e3fb10d 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -10,7 +10,6 @@ vfio-y += vfio_main.o \ obj-$(CONFIG_VFIO_VIRQFD) += vfio_virqfd.o obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o -obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o obj-$(CONFIG_VFIO_PCI) += pci/ obj-$(CONFIG_VFIO_PLATFORM) += platform/ obj-$(CONFIG_VFIO_MDEV) += mdev/ diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 73cec2beae70b..60a50ce8701e5 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -4,6 +4,7 @@ * * Copyright (C) 2013 IBM Corp. All rights reserved. * Author: Alexey Kardashevskiy + * Copyright Gavin Shan, IBM Corporation 2014. * * Derived from original vfio_iommu_type1.c: * Copyright (C) 2012 Red Hat, Inc. All rights reserved. @@ -773,6 +774,57 @@ static long tce_iommu_create_default_window(struct tce_container *container) return ret; } +static long vfio_spapr_ioctl_eeh_pe_op(struct iommu_group *group, + unsigned long arg) +{ + struct eeh_pe *pe; + struct vfio_eeh_pe_op op; + unsigned long minsz; + + pe = eeh_iommu_group_to_pe(group); + if (!pe) + return -ENODEV; + + minsz = offsetofend(struct vfio_eeh_pe_op, op); + if (copy_from_user(&op, (void __user *)arg, minsz)) + return -EFAULT; + if (op.argsz < minsz || op.flags) + return -EINVAL; + + switch (op.op) { + case VFIO_EEH_PE_DISABLE: + return eeh_pe_set_option(pe, EEH_OPT_DISABLE); + case VFIO_EEH_PE_ENABLE: + return eeh_pe_set_option(pe, EEH_OPT_ENABLE); + case VFIO_EEH_PE_UNFREEZE_IO: + return eeh_pe_set_option(pe, EEH_OPT_THAW_MMIO); + case VFIO_EEH_PE_UNFREEZE_DMA: + return eeh_pe_set_option(pe, EEH_OPT_THAW_DMA); + case VFIO_EEH_PE_GET_STATE: + return eeh_pe_get_state(pe); + break; + case VFIO_EEH_PE_RESET_DEACTIVATE: + return eeh_pe_reset(pe, EEH_RESET_DEACTIVATE, true); + case VFIO_EEH_PE_RESET_HOT: + return eeh_pe_reset(pe, EEH_RESET_HOT, true); + case VFIO_EEH_PE_RESET_FUNDAMENTAL: + return eeh_pe_reset(pe, EEH_RESET_FUNDAMENTAL, true); + case VFIO_EEH_PE_CONFIGURE: + return eeh_pe_configure(pe); + case VFIO_EEH_PE_INJECT_ERR: + minsz = offsetofend(struct vfio_eeh_pe_op, err.mask); + if (op.argsz < minsz) + return -EINVAL; + if (copy_from_user(&op, (void __user *)arg, minsz)) + return -EFAULT; + + return eeh_pe_inject_err(pe, op.err.type, op.err.func, + op.err.addr, op.err.mask); + default: + return -EINVAL; + } +} + static long tce_iommu_ioctl(void *iommu_data, unsigned int cmd, unsigned long arg) { @@ -1044,8 +1096,7 @@ static long tce_iommu_ioctl(void *iommu_data, ret = 0; list_for_each_entry(tcegrp, &container->group_list, next) { - ret = vfio_spapr_iommu_eeh_ioctl(tcegrp->grp, - cmd, arg); + ret = vfio_spapr_ioctl_eeh_pe_op(tcegrp->grp, arg); if (ret) return ret; } diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c deleted file mode 100644 index 221b1b637e18b..0000000000000 --- a/drivers/vfio/vfio_spapr_eeh.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * EEH functionality support for VFIO devices. The feature is only - * available on sPAPR compatible platforms. - * - * Copyright Gavin Shan, IBM Corporation 2014. - */ - -#include -#include -#include -#include - -#define DRIVER_VERSION "0.1" -#define DRIVER_AUTHOR "Gavin Shan, IBM Corporation" -#define DRIVER_DESC "VFIO IOMMU SPAPR EEH" - -long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, - unsigned int cmd, unsigned long arg) -{ - struct eeh_pe *pe; - struct vfio_eeh_pe_op op; - unsigned long minsz; - long ret = -EINVAL; - - switch (cmd) { - case VFIO_EEH_PE_OP: - pe = eeh_iommu_group_to_pe(group); - if (!pe) - return -ENODEV; - - minsz = offsetofend(struct vfio_eeh_pe_op, op); - if (copy_from_user(&op, (void __user *)arg, minsz)) - return -EFAULT; - if (op.argsz < minsz || op.flags) - return -EINVAL; - - switch (op.op) { - case VFIO_EEH_PE_DISABLE: - ret = eeh_pe_set_option(pe, EEH_OPT_DISABLE); - break; - case VFIO_EEH_PE_ENABLE: - ret = eeh_pe_set_option(pe, EEH_OPT_ENABLE); - break; - case VFIO_EEH_PE_UNFREEZE_IO: - ret = eeh_pe_set_option(pe, EEH_OPT_THAW_MMIO); - break; - case VFIO_EEH_PE_UNFREEZE_DMA: - ret = eeh_pe_set_option(pe, EEH_OPT_THAW_DMA); - break; - case VFIO_EEH_PE_GET_STATE: - ret = eeh_pe_get_state(pe); - break; - case VFIO_EEH_PE_RESET_DEACTIVATE: - ret = eeh_pe_reset(pe, EEH_RESET_DEACTIVATE, true); - break; - case VFIO_EEH_PE_RESET_HOT: - ret = eeh_pe_reset(pe, EEH_RESET_HOT, true); - break; - case VFIO_EEH_PE_RESET_FUNDAMENTAL: - ret = eeh_pe_reset(pe, EEH_RESET_FUNDAMENTAL, true); - break; - case VFIO_EEH_PE_CONFIGURE: - ret = eeh_pe_configure(pe); - break; - case VFIO_EEH_PE_INJECT_ERR: - minsz = offsetofend(struct vfio_eeh_pe_op, err.mask); - if (op.argsz < minsz) - return -EINVAL; - if (copy_from_user(&op, (void __user *)arg, minsz)) - return -EFAULT; - - ret = eeh_pe_inject_err(pe, op.err.type, op.err.func, - op.err.addr, op.err.mask); - break; - default: - ret = -EINVAL; - } - } - - return ret; -} -EXPORT_SYMBOL_GPL(vfio_spapr_iommu_eeh_ioctl); - -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 9378ca79d5480..b4d5d4ca3d7d5 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -233,18 +233,6 @@ int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, int max_irq_type, size_t *data_size); -#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) -long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, unsigned int cmd, - unsigned long arg); -#else -static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, - unsigned int cmd, - unsigned long arg) -{ - return -ENOTTY; -} -#endif /* CONFIG_VFIO_SPAPR_EEH */ - /* * IRQfd - generic */ -- GitLab From 20601c45a0fa20bbb5545f4dd69f4f18448f4973 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 5 Dec 2022 11:29:19 -0400 Subject: [PATCH 1319/1480] vfio: Remove CONFIG_VFIO_SPAPR_EEH We don't need a kconfig symbol for this, just directly test CONFIG_EEH in the few places that need it. Reviewed-by: Christoph Hellwig Reviewed-by: Cornelia Huck Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/4-v5-fc5346cacfd4+4c482-vfio_modules_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 5 ----- drivers/vfio/pci/vfio_pci_core.c | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index 86c381ceb9a1e..d25b91adfd64c 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -20,11 +20,6 @@ config VFIO_IOMMU_SPAPR_TCE depends on SPAPR_TCE_IOMMU default VFIO -config VFIO_SPAPR_EEH - tristate - depends on EEH && VFIO_IOMMU_SPAPR_TCE - default VFIO - config VFIO_VIRQFD tristate select EVENTFD diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 56501e7ef5645..f9365a5bc9612 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -27,7 +27,7 @@ #include #include #include -#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) +#if IS_ENABLED(CONFIG_EEH) #include #endif @@ -689,7 +689,7 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) vdev->sriov_pf_core_dev->vf_token->users--; mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock); } -#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) +#if IS_ENABLED(CONFIG_EEH) eeh_dev_release(vdev->pdev); #endif vfio_pci_core_disable(vdev); @@ -710,7 +710,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_close_device); void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev) { vfio_pci_probe_mmaps(vdev); -#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) +#if IS_ENABLED(CONFIG_EEH) eeh_dev_open(vdev->pdev); #endif -- GitLab From e2d55709398e62cf53e5c7df3758ae52cc62d63a Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 5 Dec 2022 11:29:20 -0400 Subject: [PATCH 1320/1480] vfio: Fold vfio_virqfd.ko into vfio.ko This is only 1.8k, putting it in its own module is not really necessary. The kconfig infrastructure is still there to completely remove it for systems that are trying for small footprint. Put it in the main vfio.ko module now that kbuild can support multiple .c files. Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/5-v5-fc5346cacfd4+4c482-vfio_modules_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 2 +- drivers/vfio/Makefile | 4 +--- drivers/vfio/vfio.h | 13 +++++++++++++ drivers/vfio/vfio_main.c | 7 +++++++ drivers/vfio/virqfd.c | 17 +++-------------- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index d25b91adfd64c..0b8d53f63c7e5 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -21,7 +21,7 @@ config VFIO_IOMMU_SPAPR_TCE default VFIO config VFIO_VIRQFD - tristate + bool select EVENTFD default n diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 50b8e8e3fb10d..0721ed4831c92 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -1,13 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 -vfio_virqfd-y := virqfd.o - obj-$(CONFIG_VFIO) += vfio.o vfio-y += vfio_main.o \ iova_bitmap.o \ container.o +vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o -obj-$(CONFIG_VFIO_VIRQFD) += vfio_virqfd.o obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o obj-$(CONFIG_VFIO_PCI) += pci/ diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index bcad54bbab08c..a7113b4baaa24 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -124,6 +124,19 @@ long vfio_container_ioctl_check_extension(struct vfio_container *container, int __init vfio_container_init(void); void vfio_container_cleanup(void); +#if IS_ENABLED(CONFIG_VFIO_VIRQFD) +int __init vfio_virqfd_init(void); +void vfio_virqfd_exit(void); +#else +static inline int __init vfio_virqfd_init(void) +{ + return 0; +} +static inline void vfio_virqfd_exit(void) +{ +} +#endif + #ifdef CONFIG_VFIO_NOIOMMU extern bool vfio_noiommu __read_mostly; #else diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 662e267a3e13d..7f88569c3ebaf 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1832,6 +1832,10 @@ static int __init vfio_init(void) if (ret) return ret; + ret = vfio_virqfd_init(); + if (ret) + goto err_virqfd; + /* /dev/vfio/$GROUP */ vfio.class = class_create(THIS_MODULE, "vfio"); if (IS_ERR(vfio.class)) { @@ -1862,6 +1866,8 @@ err_dev_class: class_destroy(vfio.class); vfio.class = NULL; err_group_class: + vfio_virqfd_exit(); +err_virqfd: vfio_container_cleanup(); return ret; } @@ -1876,6 +1882,7 @@ static void __exit vfio_cleanup(void) class_destroy(vfio.device_class); vfio.device_class = NULL; class_destroy(vfio.class); + vfio_virqfd_exit(); vfio_container_cleanup(); vfio.class = NULL; xa_destroy(&vfio_device_set_xa); diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c index 414e98d82b02e..497a17b378656 100644 --- a/drivers/vfio/virqfd.c +++ b/drivers/vfio/virqfd.c @@ -12,15 +12,12 @@ #include #include #include - -#define DRIVER_VERSION "0.1" -#define DRIVER_AUTHOR "Alex Williamson " -#define DRIVER_DESC "IRQFD support for VFIO bus drivers" +#include "vfio.h" static struct workqueue_struct *vfio_irqfd_cleanup_wq; static DEFINE_SPINLOCK(virqfd_lock); -static int __init vfio_virqfd_init(void) +int __init vfio_virqfd_init(void) { vfio_irqfd_cleanup_wq = create_singlethread_workqueue("vfio-irqfd-cleanup"); @@ -30,7 +27,7 @@ static int __init vfio_virqfd_init(void) return 0; } -static void __exit vfio_virqfd_exit(void) +void vfio_virqfd_exit(void) { destroy_workqueue(vfio_irqfd_cleanup_wq); } @@ -216,11 +213,3 @@ void vfio_virqfd_disable(struct virqfd **pvirqfd) flush_workqueue(vfio_irqfd_cleanup_wq); } EXPORT_SYMBOL_GPL(vfio_virqfd_disable); - -module_init(vfio_virqfd_init); -module_exit(vfio_virqfd_exit); - -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -- GitLab From ce3895735cc26957dc6b2a8f5af07ddab09483ae Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 2 Dec 2022 09:46:15 -0700 Subject: [PATCH 1321/1480] vfio/ap/ccw/samples: Fix device_register() unwind path We always need to call put_device() if device_register() fails. All vfio drivers calling device_register() include a similar unwind stack via gotos, therefore split device_unregister() into its device_del() and put_device() components in the unwind path, and add a goto target to handle only the put_device() requirement. Reported-by: Ruan Jinjie Link: https://lore.kernel.org/all/20221118032827.3725190-1-ruanjinjie@huawei.com Fixes: d61fc96f47fd ("sample: vfio mdev display - host device") Fixes: 9d1a546c53b4 ("docs: Sample driver to demonstrate how to use Mediated device framework.") Fixes: a5e6e6505f38 ("sample: vfio bochs vbe display (host device for bochs-drm)") Fixes: 9e6f07cd1eaa ("vfio/ccw: create a parent struct") Fixes: 36360658eb5a ("s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem") Cc: Tony Krowiak Cc: Halil Pasic Cc: Jason Herne Cc: Kirti Wankhede Reviewed-by: Kevin Tian Reviewed-by: Eric Farman Reviewed-by: Tony Krowiak Reviewed-by: Jason J. Herne Link: https://lore.kernel.org/r/166999942139.645727.12439756512449846442.stgit@omen Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_drv.c | 3 ++- drivers/s390/crypto/vfio_ap_drv.c | 2 +- samples/vfio-mdev/mbochs.c | 7 ++++--- samples/vfio-mdev/mdpy.c | 7 ++++--- samples/vfio-mdev/mtty.c | 7 ++++--- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index c2a65808605af..54aba7cceb33f 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -199,8 +199,9 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) return 0; out_unreg: - device_unregister(&parent->dev); + device_del(&parent->dev); out_free: + put_device(&parent->dev); dev_set_drvdata(&sch->dev, NULL); return ret; } diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c index f43cfeabd2cc8..997b524bdd2b5 100644 --- a/drivers/s390/crypto/vfio_ap_drv.c +++ b/drivers/s390/crypto/vfio_ap_drv.c @@ -122,7 +122,7 @@ static int vfio_ap_matrix_dev_create(void) return 0; matrix_drv_err: - device_unregister(&matrix_dev->device); + device_del(&matrix_dev->device); matrix_reg_err: put_device(&matrix_dev->device); matrix_alloc_err: diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 8b5a3a778a257..e54eb752e1ba8 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1430,7 +1430,7 @@ static int __init mbochs_dev_init(void) ret = device_register(&mbochs_dev); if (ret) - goto err_class; + goto err_put; ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver, mbochs_mdev_types, @@ -1441,8 +1441,9 @@ static int __init mbochs_dev_init(void) return 0; err_device: - device_unregister(&mbochs_dev); -err_class: + device_del(&mbochs_dev); +err_put: + put_device(&mbochs_dev); class_destroy(mbochs_class); err_driver: mdev_unregister_driver(&mbochs_driver); diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 721fb06c6413f..e8400fdab71da 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -717,7 +717,7 @@ static int __init mdpy_dev_init(void) ret = device_register(&mdpy_dev); if (ret) - goto err_class; + goto err_put; ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver, mdpy_mdev_types, @@ -728,8 +728,9 @@ static int __init mdpy_dev_init(void) return 0; err_device: - device_unregister(&mdpy_dev); -err_class: + device_del(&mdpy_dev); +err_put: + put_device(&mdpy_dev); class_destroy(mdpy_class); err_driver: mdev_unregister_driver(&mdpy_driver); diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 3c2a421b9b696..e887de672c526 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1330,7 +1330,7 @@ static int __init mtty_dev_init(void) ret = device_register(&mtty_dev.dev); if (ret) - goto err_class; + goto err_put; ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev, &mtty_driver, mtty_mdev_types, @@ -1340,8 +1340,9 @@ static int __init mtty_dev_init(void) return 0; err_device: - device_unregister(&mtty_dev.dev); -err_class: + device_del(&mtty_dev.dev); +err_put: + put_device(&mtty_dev.dev); class_destroy(mtty_dev.vd_class); err_driver: mdev_unregister_driver(&mtty_driver); -- GitLab From 64f6a5d1922bf6d2b2d845de20d4563a6f328e2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Dec 2022 13:12:03 +0100 Subject: [PATCH 1322/1480] container_of: add container_of_const() that preserves const-ness of the pointer container_of does not preserve the const-ness of a pointer that is passed into it, which can cause C code that passes in a const pointer to get a pointer back that is not const and then scribble all over the data in it. To prevent this, container_of_const() will preserve the const status of the pointer passed into it using the newly available _Generic() method. Suggested-by: Jason Gunthorpe Suggested-by: Sakari Ailus Reviewed-by: Matthew Wilcox (Oracle) Reviewed-by: Jason Gunthorpe Reviewed-by: Andy Shevchenko Reviewed-by: Sakari Ailus Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221205121206.166576-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/container_of.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/container_of.h b/include/linux/container_of.h index 2008e9f4058c6..1d898f9158b45 100644 --- a/include/linux/container_of.h +++ b/include/linux/container_of.h @@ -22,4 +22,17 @@ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); }) +/** + * container_of_const - cast a member of a structure out to the containing + * structure and preserve the const-ness of the pointer + * @ptr: the pointer to the member + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#define container_of_const(ptr, type, member) \ + _Generic(ptr, \ + const typeof(*(ptr)) *: ((const type *)container_of(ptr, type, member)),\ + default: ((type *)container_of(ptr, type, member)) \ + ) + #endif /* _LINUX_CONTAINER_OF_H */ -- GitLab From 6149f83b3165955e9519de483b30b26d1518ad0f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Dec 2022 13:12:04 +0100 Subject: [PATCH 1323/1480] device.h: move kobj_to_dev() to use container_of_const() Instead of rolling our own const-checking logic, use the newly introduced container_of_const() to handle it all for us automatically. Cc: Thomas Gleixner Reviewed-by: Sakari Ailus Reviewed-by: Jason Gunthorpe Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221205121206.166576-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index 84ae52de6746a..8d172d06b8c15 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -680,26 +680,7 @@ struct device_link { bool supplier_preactivated; /* Owned by consumer probe. */ }; -static inline struct device *__kobj_to_dev(struct kobject *kobj) -{ - return container_of(kobj, struct device, kobj); -} - -static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) -{ - return container_of(kobj, const struct device, kobj); -} - -/* - * container_of() will happily take a const * and spit back a non-const * as it - * is just doing pointer math. But we want to be a bit more careful in the - * driver code, so manually force any const * of a kobject to also be a const * - * to a device. - */ -#define kobj_to_dev(kobj) \ - _Generic((kobj), \ - const struct kobject *: __kobj_to_dev_const, \ - struct kobject *: __kobj_to_dev)(kobj) +#define kobj_to_dev(__kobj) container_of_const(__kobj, struct device, kobj) /** * device_iommu_mapped - Returns true when the device DMA is translated -- GitLab From c3da679286bee1d897bb24a804cca4ff58781bec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Dec 2022 13:12:05 +0100 Subject: [PATCH 1324/1480] usb.h: take advantage of container_of_const() Instead of rolling our own const-checking logic in to_usb_interface() and to_usb_device() use the newly added container_of_const() instead, making the logic much simpler overall. Reviewed-by: Sakari Ailus Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/20221205121206.166576-3-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 42 ++---------------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 4b463a5e4ba22..010c681b8822f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -259,26 +259,7 @@ struct usb_interface { struct work_struct reset_ws; /* for resets in atomic context */ }; -static inline struct usb_interface *__to_usb_interface(struct device *d) -{ - return container_of(d, struct usb_interface, dev); -} - -static inline const struct usb_interface *__to_usb_interface_const(const struct device *d) -{ - return container_of(d, struct usb_interface, dev); -} - -/* - * container_of() will happily take a const * and spit back a non-const * as it - * is just doing pointer math. But we want to be a bit more careful in the USB - * driver code, so manually force any const * of a device to also be a const * - * to a usb_device. - */ -#define to_usb_interface(dev) \ - _Generic((dev), \ - const struct device *: __to_usb_interface_const, \ - struct device *: __to_usb_interface)(dev) +#define to_usb_interface(__dev) container_of_const(__dev, struct usb_interface, dev) static inline void *usb_get_intfdata(struct usb_interface *intf) { @@ -730,26 +711,7 @@ struct usb_device { unsigned use_generic_driver:1; }; -static inline struct usb_device *__to_usb_device(struct device *d) -{ - return container_of(d, struct usb_device, dev); -} - -static inline const struct usb_device *__to_usb_device_const(const struct device *d) -{ - return container_of(d, struct usb_device, dev); -} - -/* - * container_of() will happily take a const * and spit back a non-const * as it - * is just doing pointer math. But we want to be a bit more careful in the USB - * driver code, so manually force any const * of a device to also be a const * - * to a usb_device. - */ -#define to_usb_device(dev) \ - _Generic((dev), \ - const struct device *: __to_usb_device_const, \ - struct device *: __to_usb_device)(dev) +#define to_usb_device(__dev) container_of_const(__dev, struct usb_device, dev) static inline struct usb_device *__intf_to_usbdev(struct usb_interface *intf) { -- GitLab From 47446b50ad2549af4fcc93f82a148ab107e6ef6a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Dec 2022 13:12:06 +0100 Subject: [PATCH 1325/1480] firmware_loader: fix up to_fw_sysfs() to preserve const to_fw_sysfs() was changed in commit 23680f0b7d7f ("driver core: make struct class.dev_uevent() take a const *") to pass in a const pointer but not pass it back out to handle some changes in the driver core. That isn't the best idea as it could cause problems if used incorrectly, so switch to use the container_of_const() macro instead which will preserve the const status of the pointer and enforce it by the compiler. Fixes: 23680f0b7d7f ("driver core: make struct class.dev_uevent() take a const *") Cc: Luis Chamberlain Reviewed-by: Sakari Ailus Reviewed-by: Jason Gunthorpe Acked-by: Russ Weight Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20221205121206.166576-4-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/sysfs.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/base/firmware_loader/sysfs.h b/drivers/base/firmware_loader/sysfs.h index fd0b4ad9bdbb6..2060add8ef81b 100644 --- a/drivers/base/firmware_loader/sysfs.h +++ b/drivers/base/firmware_loader/sysfs.h @@ -80,11 +80,7 @@ struct fw_sysfs { struct firmware *fw; void *fw_upload_priv; }; - -static inline struct fw_sysfs *to_fw_sysfs(const struct device *dev) -{ - return container_of(dev, struct fw_sysfs, dev); -} +#define to_fw_sysfs(__dev) container_of_const(__dev, struct fw_sysfs, dev) void __fw_load_abort(struct fw_priv *fw_priv); -- GitLab From c943a9374d12bebca2d0de7e273b1c723b58c122 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 6 Dec 2022 10:34:25 +0200 Subject: [PATCH 1326/1480] net/mlx5: Introduce ifc bits for pre_copy Introduce ifc related stuff to enable PRE_COPY of VF during migration. Signed-off-by: Shay Drory Acked-by: Leon Romanovsky Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-2-yishaih@nvidia.com Signed-off-by: Alex Williamson --- include/linux/mlx5/mlx5_ifc.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 5a4e914e2a6ff..230a96626a5f3 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1882,7 +1882,12 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { u8 max_reformat_remove_size[0x8]; u8 max_reformat_remove_offset[0x8]; - u8 reserved_at_c0[0xe0]; + u8 reserved_at_c0[0x8]; + u8 migration_multi_load[0x1]; + u8 migration_tracking_state[0x1]; + u8 reserved_at_ca[0x16]; + + u8 reserved_at_e0[0xc0]; u8 reserved_at_1a0[0xb]; u8 log_min_mkey_entity_size[0x5]; @@ -11918,7 +11923,8 @@ struct mlx5_ifc_query_vhca_migration_state_in_bits { u8 reserved_at_20[0x10]; u8 op_mod[0x10]; - u8 reserved_at_40[0x10]; + u8 incremental[0x1]; + u8 reserved_at_41[0xf]; u8 vhca_id[0x10]; u8 reserved_at_60[0x20]; @@ -11944,7 +11950,9 @@ struct mlx5_ifc_save_vhca_state_in_bits { u8 reserved_at_20[0x10]; u8 op_mod[0x10]; - u8 reserved_at_40[0x10]; + u8 incremental[0x1]; + u8 set_track[0x1]; + u8 reserved_at_42[0xe]; u8 vhca_id[0x10]; u8 reserved_at_60[0x20]; -- GitLab From 4db52602a6074e9cc523500b8304600ff63e7b85 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 6 Dec 2022 10:34:26 +0200 Subject: [PATCH 1327/1480] vfio: Extend the device migration protocol with PRE_COPY The optional PRE_COPY states open the saving data transfer FD before reaching STOP_COPY and allows the device to dirty track internal state changes with the general idea to reduce the volume of data transferred in the STOP_COPY stage. While in PRE_COPY the device remains RUNNING, but the saving FD is open. Only if the device also supports RUNNING_P2P can it support PRE_COPY_P2P, which halts P2P transfers while continuing the saving FD. PRE_COPY, with P2P support, requires the driver to implement 7 new arcs and exists as an optional FSM branch between RUNNING and STOP_COPY: RUNNING -> PRE_COPY -> PRE_COPY_P2P -> STOP_COPY A new ioctl VFIO_MIG_GET_PRECOPY_INFO is provided to allow userspace to query the progress of the precopy operation in the driver with the idea it will judge to move to STOP_COPY at least once the initial data set is transferred, and possibly after the dirty size has shrunk appropriately. This ioctl is valid only in PRE_COPY states and kernel driver should return -EINVAL from any other migration state. Compared to the v1 clarification, STOP_COPY -> PRE_COPY is blocked and to be defined in future. We also split the pending_bytes report into the initial and sustaining values, e.g.: initial_bytes and dirty_bytes. initial_bytes: Amount of initial precopy data. dirty_bytes: Device state changes relative to data previously retrieved. These fields are not required to have any bearing to STOP_COPY phase. It is recommended to leave PRE_COPY for STOP_COPY only after the initial_bytes field reaches zero. Leaving PRE_COPY earlier might make things slower. Signed-off-by: Jason Gunthorpe Signed-off-by: Shay Drory Reviewed-by: Kevin Tian Reviewed-by: Shameer Kolothum Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-3-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/vfio_main.c | 74 ++++++++++++++++++++++- include/uapi/linux/vfio.h | 123 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 191 insertions(+), 6 deletions(-) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 7f88569c3ebaf..03dbcd3d96f0e 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1042,7 +1042,7 @@ int vfio_mig_get_next_state(struct vfio_device *device, enum vfio_device_mig_state new_fsm, enum vfio_device_mig_state *next_fsm) { - enum { VFIO_DEVICE_NUM_STATES = VFIO_DEVICE_STATE_RUNNING_P2P + 1 }; + enum { VFIO_DEVICE_NUM_STATES = VFIO_DEVICE_STATE_PRE_COPY_P2P + 1 }; /* * The coding in this table requires the driver to implement the * following FSM arcs: @@ -1057,30 +1057,65 @@ int vfio_mig_get_next_state(struct vfio_device *device, * RUNNING_P2P -> RUNNING * RUNNING_P2P -> STOP * STOP -> RUNNING_P2P - * Without P2P the driver must implement: + * + * If precopy is supported then the driver must support these additional + * FSM arcs: + * RUNNING -> PRE_COPY + * PRE_COPY -> RUNNING + * PRE_COPY -> STOP_COPY + * However, if precopy and P2P are supported together then the driver + * must support these additional arcs beyond the P2P arcs above: + * PRE_COPY -> RUNNING + * PRE_COPY -> PRE_COPY_P2P + * PRE_COPY_P2P -> PRE_COPY + * PRE_COPY_P2P -> RUNNING_P2P + * PRE_COPY_P2P -> STOP_COPY + * RUNNING -> PRE_COPY + * RUNNING_P2P -> PRE_COPY_P2P + * + * Without P2P and precopy the driver must implement: * RUNNING -> STOP * STOP -> RUNNING * * The coding will step through multiple states for some combination * transitions; if all optional features are supported, this means the * following ones: + * PRE_COPY -> PRE_COPY_P2P -> STOP_COPY + * PRE_COPY -> RUNNING -> RUNNING_P2P + * PRE_COPY -> RUNNING -> RUNNING_P2P -> STOP + * PRE_COPY -> RUNNING -> RUNNING_P2P -> STOP -> RESUMING + * PRE_COPY_P2P -> RUNNING_P2P -> RUNNING + * PRE_COPY_P2P -> RUNNING_P2P -> STOP + * PRE_COPY_P2P -> RUNNING_P2P -> STOP -> RESUMING * RESUMING -> STOP -> RUNNING_P2P + * RESUMING -> STOP -> RUNNING_P2P -> PRE_COPY_P2P * RESUMING -> STOP -> RUNNING_P2P -> RUNNING + * RESUMING -> STOP -> RUNNING_P2P -> RUNNING -> PRE_COPY * RESUMING -> STOP -> STOP_COPY + * RUNNING -> RUNNING_P2P -> PRE_COPY_P2P * RUNNING -> RUNNING_P2P -> STOP * RUNNING -> RUNNING_P2P -> STOP -> RESUMING * RUNNING -> RUNNING_P2P -> STOP -> STOP_COPY + * RUNNING_P2P -> RUNNING -> PRE_COPY * RUNNING_P2P -> STOP -> RESUMING * RUNNING_P2P -> STOP -> STOP_COPY + * STOP -> RUNNING_P2P -> PRE_COPY_P2P * STOP -> RUNNING_P2P -> RUNNING + * STOP -> RUNNING_P2P -> RUNNING -> PRE_COPY * STOP_COPY -> STOP -> RESUMING * STOP_COPY -> STOP -> RUNNING_P2P * STOP_COPY -> STOP -> RUNNING_P2P -> RUNNING + * + * The following transitions are blocked: + * STOP_COPY -> PRE_COPY + * STOP_COPY -> PRE_COPY_P2P */ static const u8 vfio_from_fsm_table[VFIO_DEVICE_NUM_STATES][VFIO_DEVICE_NUM_STATES] = { [VFIO_DEVICE_STATE_STOP] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_STOP_COPY, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_RESUMING, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, @@ -1089,14 +1124,38 @@ int vfio_mig_get_next_state(struct vfio_device *device, [VFIO_DEVICE_STATE_RUNNING] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_PRE_COPY, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, [VFIO_DEVICE_STATE_ERROR] = VFIO_DEVICE_STATE_ERROR, }, + [VFIO_DEVICE_STATE_PRE_COPY] = { + [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_PRE_COPY, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_PRE_COPY_P2P, + [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_PRE_COPY_P2P, + [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_ERROR] = VFIO_DEVICE_STATE_ERROR, + }, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = { + [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_PRE_COPY, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_PRE_COPY_P2P, + [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_STOP_COPY, + [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, + [VFIO_DEVICE_STATE_ERROR] = VFIO_DEVICE_STATE_ERROR, + }, [VFIO_DEVICE_STATE_STOP_COPY] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_STOP, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_ERROR, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_ERROR, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_STOP_COPY, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_STOP, @@ -1105,6 +1164,8 @@ int vfio_mig_get_next_state(struct vfio_device *device, [VFIO_DEVICE_STATE_RESUMING] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_STOP, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_STOP, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_RESUMING, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_STOP, @@ -1113,6 +1174,8 @@ int vfio_mig_get_next_state(struct vfio_device *device, [VFIO_DEVICE_STATE_RUNNING_P2P] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_RUNNING, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_PRE_COPY_P2P, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_STOP, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_RUNNING_P2P, @@ -1121,6 +1184,8 @@ int vfio_mig_get_next_state(struct vfio_device *device, [VFIO_DEVICE_STATE_ERROR] = { [VFIO_DEVICE_STATE_STOP] = VFIO_DEVICE_STATE_ERROR, [VFIO_DEVICE_STATE_RUNNING] = VFIO_DEVICE_STATE_ERROR, + [VFIO_DEVICE_STATE_PRE_COPY] = VFIO_DEVICE_STATE_ERROR, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_DEVICE_STATE_ERROR, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_DEVICE_STATE_ERROR, [VFIO_DEVICE_STATE_RESUMING] = VFIO_DEVICE_STATE_ERROR, [VFIO_DEVICE_STATE_RUNNING_P2P] = VFIO_DEVICE_STATE_ERROR, @@ -1131,6 +1196,11 @@ int vfio_mig_get_next_state(struct vfio_device *device, static const unsigned int state_flags_table[VFIO_DEVICE_NUM_STATES] = { [VFIO_DEVICE_STATE_STOP] = VFIO_MIGRATION_STOP_COPY, [VFIO_DEVICE_STATE_RUNNING] = VFIO_MIGRATION_STOP_COPY, + [VFIO_DEVICE_STATE_PRE_COPY] = + VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY, + [VFIO_DEVICE_STATE_PRE_COPY_P2P] = VFIO_MIGRATION_STOP_COPY | + VFIO_MIGRATION_P2P | + VFIO_MIGRATION_PRE_COPY, [VFIO_DEVICE_STATE_STOP_COPY] = VFIO_MIGRATION_STOP_COPY, [VFIO_DEVICE_STATE_RESUMING] = VFIO_MIGRATION_STOP_COPY, [VFIO_DEVICE_STATE_RUNNING_P2P] = diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 3e45dbaf190ef..23105eb036fa6 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -819,12 +819,20 @@ struct vfio_device_feature { * VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_P2P means that RUNNING_P2P * is supported in addition to the STOP_COPY states. * + * VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY means that + * PRE_COPY is supported in addition to the STOP_COPY states. + * + * VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_P2P | VFIO_MIGRATION_PRE_COPY + * means that RUNNING_P2P, PRE_COPY and PRE_COPY_P2P are supported + * in addition to the STOP_COPY states. + * * Other combinations of flags have behavior to be defined in the future. */ struct vfio_device_feature_migration { __aligned_u64 flags; #define VFIO_MIGRATION_STOP_COPY (1 << 0) #define VFIO_MIGRATION_P2P (1 << 1) +#define VFIO_MIGRATION_PRE_COPY (1 << 2) }; #define VFIO_DEVICE_FEATURE_MIGRATION 1 @@ -875,8 +883,13 @@ struct vfio_device_feature_mig_state { * RESUMING - The device is stopped and is loading a new internal state * ERROR - The device has failed and must be reset * - * And 1 optional state to support VFIO_MIGRATION_P2P: + * And optional states to support VFIO_MIGRATION_P2P: * RUNNING_P2P - RUNNING, except the device cannot do peer to peer DMA + * And VFIO_MIGRATION_PRE_COPY: + * PRE_COPY - The device is running normally but tracking internal state + * changes + * And VFIO_MIGRATION_P2P | VFIO_MIGRATION_PRE_COPY: + * PRE_COPY_P2P - PRE_COPY, except the device cannot do peer to peer DMA * * The FSM takes actions on the arcs between FSM states. The driver implements * the following behavior for the FSM arcs: @@ -908,20 +921,48 @@ struct vfio_device_feature_mig_state { * * To abort a RESUMING session the device must be reset. * + * PRE_COPY -> RUNNING * RUNNING_P2P -> RUNNING * While in RUNNING the device is fully operational, the device may generate * interrupts, DMA, respond to MMIO, all vfio device regions are functional, * and the device may advance its internal state. * + * The PRE_COPY arc will terminate a data transfer session. + * + * PRE_COPY_P2P -> RUNNING_P2P * RUNNING -> RUNNING_P2P * STOP -> RUNNING_P2P * While in RUNNING_P2P the device is partially running in the P2P quiescent * state defined below. * + * The PRE_COPY_P2P arc will terminate a data transfer session. + * + * RUNNING -> PRE_COPY + * RUNNING_P2P -> PRE_COPY_P2P * STOP -> STOP_COPY - * This arc begin the process of saving the device state and will return a - * new data_fd. + * PRE_COPY, PRE_COPY_P2P and STOP_COPY form the "saving group" of states + * which share a data transfer session. Moving between these states alters + * what is streamed in session, but does not terminate or otherwise affect + * the associated fd. + * + * These arcs begin the process of saving the device state and will return a + * new data_fd. The migration driver may perform actions such as enabling + * dirty logging of device state when entering PRE_COPY or PER_COPY_P2P. * + * Each arc does not change the device operation, the device remains + * RUNNING, P2P quiesced or in STOP. The STOP_COPY state is described below + * in PRE_COPY_P2P -> STOP_COPY. + * + * PRE_COPY -> PRE_COPY_P2P + * Entering PRE_COPY_P2P continues all the behaviors of PRE_COPY above. + * However, while in the PRE_COPY_P2P state, the device is partially running + * in the P2P quiescent state defined below, like RUNNING_P2P. + * + * PRE_COPY_P2P -> PRE_COPY + * This arc allows returning the device to a full RUNNING behavior while + * continuing all the behaviors of PRE_COPY. + * + * PRE_COPY_P2P -> STOP_COPY * While in the STOP_COPY state the device has the same behavior as STOP * with the addition that the data transfers session continues to stream the * migration state. End of stream on the FD indicates the entire device @@ -939,6 +980,13 @@ struct vfio_device_feature_mig_state { * device state for this arc if required to prepare the device to receive the * migration data. * + * STOP_COPY -> PRE_COPY + * STOP_COPY -> PRE_COPY_P2P + * These arcs are not permitted and return error if requested. Future + * revisions of this API may define behaviors for these arcs, in this case + * support will be discoverable by a new flag in + * VFIO_DEVICE_FEATURE_MIGRATION. + * * any -> ERROR * ERROR cannot be specified as a device state, however any transition request * can be failed with an errno return and may then move the device_state into @@ -950,7 +998,7 @@ struct vfio_device_feature_mig_state { * The optional peer to peer (P2P) quiescent state is intended to be a quiescent * state for the device for the purposes of managing multiple devices within a * user context where peer-to-peer DMA between devices may be active. The - * RUNNING_P2P states must prevent the device from initiating + * RUNNING_P2P and PRE_COPY_P2P states must prevent the device from initiating * any new P2P DMA transactions. If the device can identify P2P transactions * then it can stop only P2P DMA, otherwise it must stop all DMA. The migration * driver must complete any such outstanding operations prior to completing the @@ -963,6 +1011,8 @@ struct vfio_device_feature_mig_state { * above FSM arcs. As there are multiple paths through the FSM arcs the path * should be selected based on the following rules: * - Select the shortest path. + * - The path cannot have saving group states as interior arcs, only + * starting/end states. * Refer to vfio_mig_get_next_state() for the result of the algorithm. * * The automatic transit through the FSM arcs that make up the combination @@ -976,6 +1026,9 @@ struct vfio_device_feature_mig_state { * support them. The user can discover if these states are supported by using * VFIO_DEVICE_FEATURE_MIGRATION. By using combination transitions the user can * avoid knowing about these optional states if the kernel driver supports them. + * + * Arcs touching PRE_COPY and PRE_COPY_P2P are removed if support for PRE_COPY + * is not present. */ enum vfio_device_mig_state { VFIO_DEVICE_STATE_ERROR = 0, @@ -984,8 +1037,70 @@ enum vfio_device_mig_state { VFIO_DEVICE_STATE_STOP_COPY = 3, VFIO_DEVICE_STATE_RESUMING = 4, VFIO_DEVICE_STATE_RUNNING_P2P = 5, + VFIO_DEVICE_STATE_PRE_COPY = 6, + VFIO_DEVICE_STATE_PRE_COPY_P2P = 7, +}; + +/** + * VFIO_MIG_GET_PRECOPY_INFO - _IO(VFIO_TYPE, VFIO_BASE + 21) + * + * This ioctl is used on the migration data FD in the precopy phase of the + * migration data transfer. It returns an estimate of the current data sizes + * remaining to be transferred. It allows the user to judge when it is + * appropriate to leave PRE_COPY for STOP_COPY. + * + * This ioctl is valid only in PRE_COPY states and kernel driver should + * return -EINVAL from any other migration state. + * + * The vfio_precopy_info data structure returned by this ioctl provides + * estimates of data available from the device during the PRE_COPY states. + * This estimate is split into two categories, initial_bytes and + * dirty_bytes. + * + * The initial_bytes field indicates the amount of initial precopy + * data available from the device. This field should have a non-zero initial + * value and decrease as migration data is read from the device. + * It is recommended to leave PRE_COPY for STOP_COPY only after this field + * reaches zero. Leaving PRE_COPY earlier might make things slower. + * + * The dirty_bytes field tracks device state changes relative to data + * previously retrieved. This field starts at zero and may increase as + * the internal device state is modified or decrease as that modified + * state is read from the device. + * + * Userspace may use the combination of these fields to estimate the + * potential data size available during the PRE_COPY phases, as well as + * trends relative to the rate the device is dirtying its internal + * state, but these fields are not required to have any bearing relative + * to the data size available during the STOP_COPY phase. + * + * Drivers have a lot of flexibility in when and what they transfer during the + * PRE_COPY phase, and how they report this from VFIO_MIG_GET_PRECOPY_INFO. + * + * During pre-copy the migration data FD has a temporary "end of stream" that is + * reached when both initial_bytes and dirty_byte are zero. For instance, this + * may indicate that the device is idle and not currently dirtying any internal + * state. When read() is done on this temporary end of stream the kernel driver + * should return ENOMSG from read(). Userspace can wait for more data (which may + * never come) by using poll. + * + * Once in STOP_COPY the migration data FD has a permanent end of stream + * signaled in the usual way by read() always returning 0 and poll always + * returning readable. ENOMSG may not be returned in STOP_COPY. + * Support for this ioctl is mandatory if a driver claims to support + * VFIO_MIGRATION_PRE_COPY. + * + * Return: 0 on success, -1 and errno set on failure. + */ +struct vfio_precopy_info { + __u32 argsz; + __u32 flags; + __aligned_u64 initial_bytes; + __aligned_u64 dirty_bytes; }; +#define VFIO_MIG_GET_PRECOPY_INFO _IO(VFIO_TYPE, VFIO_BASE + 21) + /* * Upon VFIO_DEVICE_FEATURE_SET, allow the device to be moved into a low power * state with the platform-based power management. Device use of lower power -- GitLab From 0e7caa65d707b93fbb4322c6313f739fa9103dfa Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:27 +0200 Subject: [PATCH 1328/1480] vfio/mlx5: Enforce a single SAVE command at a time Enforce a single SAVE command at a time. As the SAVE command is an asynchronous one, we must enforce running only a single command at a time. This will preserve ordering between multiple calls and protect from races on the migration file data structure. This is a must for the next patches from the series where as part of PRE_COPY we may have multiple images to be saved and multiple SAVE commands may be issued from different flows. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-4-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 6 ++++++ drivers/vfio/pci/mlx5/cmd.h | 1 + drivers/vfio/pci/mlx5/main.c | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 0848bc905d3ea..55ee8036f59cd 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -281,6 +281,7 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); mlx5_core_dealloc_pd(mdev, async_data->pdn); kvfree(async_data->out); + complete(&migf->save_comp); fput(migf->filp); } @@ -321,6 +322,10 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, return -ENOTCONN; mdev = mvdev->mdev; + err = wait_for_completion_interruptible(&migf->save_comp); + if (err) + return err; + err = mlx5_core_alloc_pd(mdev, &pdn); if (err) return err; @@ -371,6 +376,7 @@ err_create_mkey: dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); err_dma_map: mlx5_core_dealloc_pd(mdev, pdn); + complete(&migf->save_comp); return err; } diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 921d5720a1e57..8ffa7699872c4 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -37,6 +37,7 @@ struct mlx5_vf_migration_file { unsigned long last_offset; struct mlx5vf_pci_core_device *mvdev; wait_queue_head_t poll_wait; + struct completion save_comp; struct mlx5_async_ctx async_ctx; struct mlx5vf_async_data async_data; }; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 6e9cf2aacc527..0d71ebb2a9727 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -245,6 +245,13 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); init_waitqueue_head(&migf->poll_wait); + init_completion(&migf->save_comp); + /* + * save_comp is being used as a binary semaphore built from + * a completion. A normal mutex cannot be used because the lock is + * passed between kernel threads and lockdep can't model this. + */ + complete(&migf->save_comp); mlx5_cmd_init_async_ctx(mvdev->mdev, &migf->async_ctx); INIT_WORK(&migf->async_data.work, mlx5vf_mig_file_cleanup_cb); ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, -- GitLab From 9945a67ea4b30657dd998c7fbbea1b3950747168 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:28 +0200 Subject: [PATCH 1329/1480] vfio/mlx5: Refactor PD usage This patch refactors PD usage such as its life cycle will be as of the migration file instead of allocating/destroying it upon each SAVE/LOAD command. This is a preparation step towards the PRE_COPY series where multiple images will be SAVED/LOADED and a single PD can be simply reused. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-5-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 53 ++++++++++++++++++++++++------------ drivers/vfio/pci/mlx5/cmd.h | 5 +++- drivers/vfio/pci/mlx5/main.c | 44 ++++++++++++++++++++++-------- 3 files changed, 71 insertions(+), 31 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 55ee8036f59cd..a97eac49e3d68 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -279,7 +279,6 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mlx5_core_destroy_mkey(mdev, async_data->mkey); dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); - mlx5_core_dealloc_pd(mdev, async_data->pdn); kvfree(async_data->out); complete(&migf->save_comp); fput(migf->filp); @@ -314,7 +313,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {}; struct mlx5vf_async_data *async_data; struct mlx5_core_dev *mdev; - u32 pdn, mkey; + u32 mkey; int err; lockdep_assert_held(&mvdev->state_mutex); @@ -326,16 +325,12 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, if (err) return err; - err = mlx5_core_alloc_pd(mdev, &pdn); - if (err) - return err; - err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); if (err) goto err_dma_map; - err = _create_mkey(mdev, pdn, migf, NULL, &mkey); + err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey); if (err) goto err_create_mkey; @@ -357,7 +352,6 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, migf->total_length = 0; get_file(migf->filp); async_data->mkey = mkey; - async_data->pdn = pdn; err = mlx5_cmd_exec_cb(&migf->async_ctx, in, sizeof(in), async_data->out, out_size, mlx5vf_save_callback, @@ -375,7 +369,6 @@ err_out: err_create_mkey: dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); err_dma_map: - mlx5_core_dealloc_pd(mdev, pdn); complete(&migf->save_comp); return err; } @@ -386,7 +379,7 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_core_dev *mdev; u32 out[MLX5_ST_SZ_DW(load_vhca_state_out)] = {}; u32 in[MLX5_ST_SZ_DW(load_vhca_state_in)] = {}; - u32 pdn, mkey; + u32 mkey; int err; lockdep_assert_held(&mvdev->state_mutex); @@ -400,15 +393,11 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, } mdev = mvdev->mdev; - err = mlx5_core_alloc_pd(mdev, &pdn); - if (err) - goto end; - err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0); if (err) - goto err_reg; + goto end; - err = _create_mkey(mdev, pdn, migf, NULL, &mkey); + err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey); if (err) goto err_mkey; @@ -424,13 +413,41 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, mlx5_core_destroy_mkey(mdev, mkey); err_mkey: dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0); -err_reg: - mlx5_core_dealloc_pd(mdev, pdn); end: mutex_unlock(&migf->lock); return err; } +int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf) +{ + int err; + + lockdep_assert_held(&migf->mvdev->state_mutex); + if (migf->mvdev->mdev_detach) + return -ENOTCONN; + + err = mlx5_core_alloc_pd(migf->mvdev->mdev, &migf->pdn); + return err; +} + +void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf) +{ + lockdep_assert_held(&migf->mvdev->state_mutex); + if (migf->mvdev->mdev_detach) + return; + + mlx5_core_dealloc_pd(migf->mvdev->mdev, migf->pdn); +} + +void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf) +{ + lockdep_assert_held(&migf->mvdev->state_mutex); + + WARN_ON(migf->mvdev->mdev_detach); + + mlx5vf_cmd_dealloc_pd(migf); +} + static void combine_ranges(struct rb_root_cached *root, u32 cur_nodes, u32 req_nodes) { diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 8ffa7699872c4..ba760f956d535 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -16,7 +16,6 @@ struct mlx5vf_async_data { struct mlx5_async_work cb_work; struct work_struct work; int status; - u32 pdn; u32 mkey; void *out; }; @@ -27,6 +26,7 @@ struct mlx5_vf_migration_file { u8 disabled:1; u8 is_err:1; + u32 pdn; struct sg_append_table table; size_t total_length; size_t allocated_length; @@ -127,6 +127,9 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf); int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf); +int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf); +void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf); +void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf); void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 0d71ebb2a9727..1916f7c1468c1 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -236,12 +236,15 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) migf->filp = anon_inode_getfile("mlx5vf_mig", &mlx5vf_save_fops, migf, O_RDONLY); if (IS_ERR(migf->filp)) { - int err = PTR_ERR(migf->filp); - - kfree(migf); - return ERR_PTR(err); + ret = PTR_ERR(migf->filp); + goto end; } + migf->mvdev = mvdev; + ret = mlx5vf_cmd_alloc_pd(migf); + if (ret) + goto out_free; + stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); init_waitqueue_head(&migf->poll_wait); @@ -257,20 +260,25 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &migf->total_length); if (ret) - goto out_free; + goto out_pd; ret = mlx5vf_add_migration_pages( migf, DIV_ROUND_UP_ULL(migf->total_length, PAGE_SIZE)); if (ret) - goto out_free; + goto out_pd; - migf->mvdev = mvdev; ret = mlx5vf_cmd_save_vhca_state(mvdev, migf); if (ret) - goto out_free; + goto out_save; return migf; +out_save: + mlx5vf_disable_fd(migf); +out_pd: + mlx5vf_cmd_dealloc_pd(migf); out_free: fput(migf->filp); +end: + kfree(migf); return ERR_PTR(ret); } @@ -352,6 +360,7 @@ static struct mlx5_vf_migration_file * mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) { struct mlx5_vf_migration_file *migf; + int ret; migf = kzalloc(sizeof(*migf), GFP_KERNEL); if (!migf) @@ -360,20 +369,30 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) migf->filp = anon_inode_getfile("mlx5vf_mig", &mlx5vf_resume_fops, migf, O_WRONLY); if (IS_ERR(migf->filp)) { - int err = PTR_ERR(migf->filp); - - kfree(migf); - return ERR_PTR(err); + ret = PTR_ERR(migf->filp); + goto end; } + + migf->mvdev = mvdev; + ret = mlx5vf_cmd_alloc_pd(migf); + if (ret) + goto out_free; + stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); return migf; +out_free: + fput(migf->filp); +end: + kfree(migf); + return ERR_PTR(ret); } void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev) { if (mvdev->resuming_migf) { mlx5vf_disable_fd(mvdev->resuming_migf); + mlx5fv_cmd_clean_migf_resources(mvdev->resuming_migf); fput(mvdev->resuming_migf->filp); mvdev->resuming_migf = NULL; } @@ -381,6 +400,7 @@ void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev) mlx5_cmd_cleanup_async_ctx(&mvdev->saving_migf->async_ctx); cancel_work_sync(&mvdev->saving_migf->async_data.work); mlx5vf_disable_fd(mvdev->saving_migf); + mlx5fv_cmd_clean_migf_resources(mvdev->saving_migf); fput(mvdev->saving_migf->filp); mvdev->saving_migf = NULL; } -- GitLab From 91454f8b9bf4ce6be1d9a0b4de401bc3c6313a95 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:29 +0200 Subject: [PATCH 1330/1480] vfio/mlx5: Refactor MKEY usage This patch refactors MKEY usage such as its life cycle will be as of the migration file instead of allocating/destroying it upon each SAVE/LOAD command. This is a preparation step towards the PRE_COPY series where multiple images will be SAVED/LOADED. We achieve it by having a new struct named mlx5_vhca_data_buffer which holds the mkey and its related stuff as of sg_append_table, allocated_length, etc. The above fields were taken out from the migration file main struct, into mlx5_vhca_data_buffer dedicated struct with the proper helpers in place. For now we have a single mlx5_vhca_data_buffer per migration file. However, in coming patches we'll have multiple of them to support multiple images. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-6-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 162 ++++++++++++++++++++++------------- drivers/vfio/pci/mlx5/cmd.h | 37 +++++--- drivers/vfio/pci/mlx5/main.c | 92 +++++++++++--------- 3 files changed, 178 insertions(+), 113 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index a97eac49e3d68..ed4c472d2eae5 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -210,11 +210,11 @@ err_exec: } static int _create_mkey(struct mlx5_core_dev *mdev, u32 pdn, - struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *buf, struct mlx5_vhca_recv_buf *recv_buf, u32 *mkey) { - size_t npages = migf ? DIV_ROUND_UP(migf->total_length, PAGE_SIZE) : + size_t npages = buf ? DIV_ROUND_UP(buf->allocated_length, PAGE_SIZE) : recv_buf->npages; int err = 0, inlen; __be64 *mtt; @@ -232,10 +232,10 @@ static int _create_mkey(struct mlx5_core_dev *mdev, u32 pdn, DIV_ROUND_UP(npages, 2)); mtt = (__be64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt); - if (migf) { + if (buf) { struct sg_dma_page_iter dma_iter; - for_each_sgtable_dma_page(&migf->table.sgt, &dma_iter, 0) + for_each_sgtable_dma_page(&buf->table.sgt, &dma_iter, 0) *mtt++ = cpu_to_be64(sg_page_iter_dma_address(&dma_iter)); } else { int i; @@ -255,20 +255,99 @@ static int _create_mkey(struct mlx5_core_dev *mdev, u32 pdn, MLX5_SET(mkc, mkc, qpn, 0xffffff); MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT); MLX5_SET(mkc, mkc, translations_octword_size, DIV_ROUND_UP(npages, 2)); - MLX5_SET64(mkc, mkc, len, - migf ? migf->total_length : (npages * PAGE_SIZE)); + MLX5_SET64(mkc, mkc, len, npages * PAGE_SIZE); err = mlx5_core_create_mkey(mdev, mkey, in, inlen); kvfree(in); return err; } +static int mlx5vf_dma_data_buffer(struct mlx5_vhca_data_buffer *buf) +{ + struct mlx5vf_pci_core_device *mvdev = buf->migf->mvdev; + struct mlx5_core_dev *mdev = mvdev->mdev; + int ret; + + lockdep_assert_held(&mvdev->state_mutex); + if (mvdev->mdev_detach) + return -ENOTCONN; + + if (buf->dmaed || !buf->allocated_length) + return -EINVAL; + + ret = dma_map_sgtable(mdev->device, &buf->table.sgt, buf->dma_dir, 0); + if (ret) + return ret; + + ret = _create_mkey(mdev, buf->migf->pdn, buf, NULL, &buf->mkey); + if (ret) + goto err; + + buf->dmaed = true; + + return 0; +err: + dma_unmap_sgtable(mdev->device, &buf->table.sgt, buf->dma_dir, 0); + return ret; +} + +void mlx5vf_free_data_buffer(struct mlx5_vhca_data_buffer *buf) +{ + struct mlx5_vf_migration_file *migf = buf->migf; + struct sg_page_iter sg_iter; + + lockdep_assert_held(&migf->mvdev->state_mutex); + WARN_ON(migf->mvdev->mdev_detach); + + if (buf->dmaed) { + mlx5_core_destroy_mkey(migf->mvdev->mdev, buf->mkey); + dma_unmap_sgtable(migf->mvdev->mdev->device, &buf->table.sgt, + buf->dma_dir, 0); + } + + /* Undo alloc_pages_bulk_array() */ + for_each_sgtable_page(&buf->table.sgt, &sg_iter, 0) + __free_page(sg_page_iter_page(&sg_iter)); + sg_free_append_table(&buf->table); + kfree(buf); +} + +struct mlx5_vhca_data_buffer * +mlx5vf_alloc_data_buffer(struct mlx5_vf_migration_file *migf, + size_t length, + enum dma_data_direction dma_dir) +{ + struct mlx5_vhca_data_buffer *buf; + int ret; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dma_dir = dma_dir; + buf->migf = migf; + if (length) { + ret = mlx5vf_add_migration_pages(buf, + DIV_ROUND_UP_ULL(length, PAGE_SIZE)); + if (ret) + goto end; + + ret = mlx5vf_dma_data_buffer(buf); + if (ret) + goto end; + } + + return buf; +end: + mlx5vf_free_data_buffer(buf); + return ERR_PTR(ret); +} + void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) { struct mlx5vf_async_data *async_data = container_of(_work, struct mlx5vf_async_data, work); struct mlx5_vf_migration_file *migf = container_of(async_data, struct mlx5_vf_migration_file, async_data); - struct mlx5_core_dev *mdev = migf->mvdev->mdev; mutex_lock(&migf->lock); if (async_data->status) { @@ -276,9 +355,6 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) wake_up_interruptible(&migf->poll_wait); } mutex_unlock(&migf->lock); - - mlx5_core_destroy_mkey(mdev, async_data->mkey); - dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); kvfree(async_data->out); complete(&migf->save_comp); fput(migf->filp); @@ -292,7 +368,7 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) struct mlx5_vf_migration_file, async_data); if (!status) { - WRITE_ONCE(migf->total_length, + WRITE_ONCE(migf->buf->length, MLX5_GET(save_vhca_state_out, async_data->out, actual_image_size)); wake_up_interruptible(&migf->poll_wait); @@ -307,39 +383,28 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) } int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, - struct mlx5_vf_migration_file *migf) + struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *buf) { u32 out_size = MLX5_ST_SZ_BYTES(save_vhca_state_out); u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {}; struct mlx5vf_async_data *async_data; - struct mlx5_core_dev *mdev; - u32 mkey; int err; lockdep_assert_held(&mvdev->state_mutex); if (mvdev->mdev_detach) return -ENOTCONN; - mdev = mvdev->mdev; err = wait_for_completion_interruptible(&migf->save_comp); if (err) return err; - err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, - 0); - if (err) - goto err_dma_map; - - err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey); - if (err) - goto err_create_mkey; - MLX5_SET(save_vhca_state_in, in, opcode, MLX5_CMD_OP_SAVE_VHCA_STATE); MLX5_SET(save_vhca_state_in, in, op_mod, 0); MLX5_SET(save_vhca_state_in, in, vhca_id, mvdev->vhca_id); - MLX5_SET(save_vhca_state_in, in, mkey, mkey); - MLX5_SET(save_vhca_state_in, in, size, migf->total_length); + MLX5_SET(save_vhca_state_in, in, mkey, buf->mkey); + MLX5_SET(save_vhca_state_in, in, size, buf->allocated_length); async_data = &migf->async_data; async_data->out = kvzalloc(out_size, GFP_KERNEL); @@ -348,10 +413,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, goto err_out; } - /* no data exists till the callback comes back */ - migf->total_length = 0; get_file(migf->filp); - async_data->mkey = mkey; err = mlx5_cmd_exec_cb(&migf->async_ctx, in, sizeof(in), async_data->out, out_size, mlx5vf_save_callback, @@ -365,57 +427,33 @@ err_exec: fput(migf->filp); kvfree(async_data->out); err_out: - mlx5_core_destroy_mkey(mdev, mkey); -err_create_mkey: - dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0); -err_dma_map: complete(&migf->save_comp); return err; } int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, - struct mlx5_vf_migration_file *migf) + struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *buf) { - struct mlx5_core_dev *mdev; u32 out[MLX5_ST_SZ_DW(load_vhca_state_out)] = {}; u32 in[MLX5_ST_SZ_DW(load_vhca_state_in)] = {}; - u32 mkey; int err; lockdep_assert_held(&mvdev->state_mutex); if (mvdev->mdev_detach) return -ENOTCONN; - mutex_lock(&migf->lock); - if (!migf->total_length) { - err = -EINVAL; - goto end; - } - - mdev = mvdev->mdev; - err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0); + err = mlx5vf_dma_data_buffer(buf); if (err) - goto end; - - err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey); - if (err) - goto err_mkey; + return err; MLX5_SET(load_vhca_state_in, in, opcode, MLX5_CMD_OP_LOAD_VHCA_STATE); MLX5_SET(load_vhca_state_in, in, op_mod, 0); MLX5_SET(load_vhca_state_in, in, vhca_id, mvdev->vhca_id); - MLX5_SET(load_vhca_state_in, in, mkey, mkey); - MLX5_SET(load_vhca_state_in, in, size, migf->total_length); - - err = mlx5_cmd_exec_inout(mdev, load_vhca_state, in, out); - - mlx5_core_destroy_mkey(mdev, mkey); -err_mkey: - dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0); -end: - mutex_unlock(&migf->lock); - return err; + MLX5_SET(load_vhca_state_in, in, mkey, buf->mkey); + MLX5_SET(load_vhca_state_in, in, size, buf->length); + return mlx5_cmd_exec_inout(mvdev->mdev, load_vhca_state, in, out); } int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf) @@ -445,6 +483,10 @@ void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf) WARN_ON(migf->mvdev->mdev_detach); + if (migf->buf) { + mlx5vf_free_data_buffer(migf->buf); + migf->buf = NULL; + } mlx5vf_cmd_dealloc_pd(migf); } diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index ba760f956d535..b0f08dfc81207 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -12,11 +12,25 @@ #include #include +struct mlx5_vhca_data_buffer { + struct sg_append_table table; + loff_t start_pos; + u64 length; + u64 allocated_length; + u32 mkey; + enum dma_data_direction dma_dir; + u8 dmaed:1; + struct mlx5_vf_migration_file *migf; + /* Optimize mlx5vf_get_migration_page() for sequential access */ + struct scatterlist *last_offset_sg; + unsigned int sg_last_entry; + unsigned long last_offset; +}; + struct mlx5vf_async_data { struct mlx5_async_work cb_work; struct work_struct work; int status; - u32 mkey; void *out; }; @@ -27,14 +41,7 @@ struct mlx5_vf_migration_file { u8 is_err:1; u32 pdn; - struct sg_append_table table; - size_t total_length; - size_t allocated_length; - - /* Optimize mlx5vf_get_migration_page() for sequential access */ - struct scatterlist *last_offset_sg; - unsigned int sg_last_entry; - unsigned long last_offset; + struct mlx5_vhca_data_buffer *buf; struct mlx5vf_pci_core_device *mvdev; wait_queue_head_t poll_wait; struct completion save_comp; @@ -124,12 +131,20 @@ void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev, void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev); int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, - struct mlx5_vf_migration_file *migf); + struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *buf); int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, - struct mlx5_vf_migration_file *migf); + struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *buf); int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf); void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf); void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf); +struct mlx5_vhca_data_buffer * +mlx5vf_alloc_data_buffer(struct mlx5_vf_migration_file *migf, + size_t length, enum dma_data_direction dma_dir); +void mlx5vf_free_data_buffer(struct mlx5_vhca_data_buffer *buf); +int mlx5vf_add_migration_pages(struct mlx5_vhca_data_buffer *buf, + unsigned int npages); void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 1916f7c1468c1..5f694fce854cf 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -33,7 +33,7 @@ static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) } static struct page * -mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, +mlx5vf_get_migration_page(struct mlx5_vhca_data_buffer *buf, unsigned long offset) { unsigned long cur_offset = 0; @@ -41,20 +41,20 @@ mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, unsigned int i; /* All accesses are sequential */ - if (offset < migf->last_offset || !migf->last_offset_sg) { - migf->last_offset = 0; - migf->last_offset_sg = migf->table.sgt.sgl; - migf->sg_last_entry = 0; + if (offset < buf->last_offset || !buf->last_offset_sg) { + buf->last_offset = 0; + buf->last_offset_sg = buf->table.sgt.sgl; + buf->sg_last_entry = 0; } - cur_offset = migf->last_offset; + cur_offset = buf->last_offset; - for_each_sg(migf->last_offset_sg, sg, - migf->table.sgt.orig_nents - migf->sg_last_entry, i) { + for_each_sg(buf->last_offset_sg, sg, + buf->table.sgt.orig_nents - buf->sg_last_entry, i) { if (offset < sg->length + cur_offset) { - migf->last_offset_sg = sg; - migf->sg_last_entry += i; - migf->last_offset = cur_offset; + buf->last_offset_sg = sg; + buf->sg_last_entry += i; + buf->last_offset = cur_offset; return nth_page(sg_page(sg), (offset - cur_offset) / PAGE_SIZE); } @@ -63,8 +63,8 @@ mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, return NULL; } -static int mlx5vf_add_migration_pages(struct mlx5_vf_migration_file *migf, - unsigned int npages) +int mlx5vf_add_migration_pages(struct mlx5_vhca_data_buffer *buf, + unsigned int npages) { unsigned int to_alloc = npages; struct page **page_list; @@ -85,13 +85,13 @@ static int mlx5vf_add_migration_pages(struct mlx5_vf_migration_file *migf, } to_alloc -= filled; ret = sg_alloc_append_table_from_pages( - &migf->table, page_list, filled, 0, + &buf->table, page_list, filled, 0, filled << PAGE_SHIFT, UINT_MAX, SG_MAX_SINGLE_ALLOC, GFP_KERNEL); if (ret) goto err; - migf->allocated_length += filled * PAGE_SIZE; + buf->allocated_length += filled * PAGE_SIZE; /* clean input for another bulk allocation */ memset(page_list, 0, filled * sizeof(*page_list)); to_fill = min_t(unsigned int, to_alloc, @@ -108,16 +108,8 @@ err: static void mlx5vf_disable_fd(struct mlx5_vf_migration_file *migf) { - struct sg_page_iter sg_iter; - mutex_lock(&migf->lock); - /* Undo alloc_pages_bulk_array() */ - for_each_sgtable_page(&migf->table.sgt, &sg_iter, 0) - __free_page(sg_page_iter_page(&sg_iter)); - sg_free_append_table(&migf->table); migf->disabled = true; - migf->total_length = 0; - migf->allocated_length = 0; migf->filp->f_pos = 0; mutex_unlock(&migf->lock); } @@ -136,6 +128,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, loff_t *pos) { struct mlx5_vf_migration_file *migf = filp->private_data; + struct mlx5_vhca_data_buffer *vhca_buf = migf->buf; ssize_t done = 0; if (pos) @@ -144,16 +137,16 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (!(filp->f_flags & O_NONBLOCK)) { if (wait_event_interruptible(migf->poll_wait, - READ_ONCE(migf->total_length) || migf->is_err)) + READ_ONCE(vhca_buf->length) || migf->is_err)) return -ERESTARTSYS; } mutex_lock(&migf->lock); - if ((filp->f_flags & O_NONBLOCK) && !READ_ONCE(migf->total_length)) { + if ((filp->f_flags & O_NONBLOCK) && !READ_ONCE(vhca_buf->length)) { done = -EAGAIN; goto out_unlock; } - if (*pos > migf->total_length) { + if (*pos > vhca_buf->length) { done = -EINVAL; goto out_unlock; } @@ -162,7 +155,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, goto out_unlock; } - len = min_t(size_t, migf->total_length - *pos, len); + len = min_t(size_t, vhca_buf->length - *pos, len); while (len) { size_t page_offset; struct page *page; @@ -171,7 +164,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, int ret; page_offset = (*pos) % PAGE_SIZE; - page = mlx5vf_get_migration_page(migf, *pos - page_offset); + page = mlx5vf_get_migration_page(vhca_buf, *pos - page_offset); if (!page) { if (done == 0) done = -EINVAL; @@ -208,7 +201,7 @@ static __poll_t mlx5vf_save_poll(struct file *filp, mutex_lock(&migf->lock); if (migf->disabled || migf->is_err) pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; - else if (READ_ONCE(migf->total_length)) + else if (READ_ONCE(migf->buf->length)) pollflags = EPOLLIN | EPOLLRDNORM; mutex_unlock(&migf->lock); @@ -227,6 +220,8 @@ static struct mlx5_vf_migration_file * mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) { struct mlx5_vf_migration_file *migf; + struct mlx5_vhca_data_buffer *buf; + size_t length; int ret; migf = kzalloc(sizeof(*migf), GFP_KERNEL); @@ -257,22 +252,23 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) complete(&migf->save_comp); mlx5_cmd_init_async_ctx(mvdev->mdev, &migf->async_ctx); INIT_WORK(&migf->async_data.work, mlx5vf_mig_file_cleanup_cb); - ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, - &migf->total_length); + ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length); if (ret) goto out_pd; - ret = mlx5vf_add_migration_pages( - migf, DIV_ROUND_UP_ULL(migf->total_length, PAGE_SIZE)); - if (ret) + buf = mlx5vf_alloc_data_buffer(migf, length, DMA_FROM_DEVICE); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); goto out_pd; + } - ret = mlx5vf_cmd_save_vhca_state(mvdev, migf); + ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf); if (ret) goto out_save; + migf->buf = buf; return migf; out_save: - mlx5vf_disable_fd(migf); + mlx5vf_free_data_buffer(buf); out_pd: mlx5vf_cmd_dealloc_pd(migf); out_free: @@ -286,6 +282,7 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, size_t len, loff_t *pos) { struct mlx5_vf_migration_file *migf = filp->private_data; + struct mlx5_vhca_data_buffer *vhca_buf = migf->buf; loff_t requested_length; ssize_t done = 0; @@ -306,10 +303,10 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, goto out_unlock; } - if (migf->allocated_length < requested_length) { + if (vhca_buf->allocated_length < requested_length) { done = mlx5vf_add_migration_pages( - migf, - DIV_ROUND_UP(requested_length - migf->allocated_length, + vhca_buf, + DIV_ROUND_UP(requested_length - vhca_buf->allocated_length, PAGE_SIZE)); if (done) goto out_unlock; @@ -323,7 +320,7 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, int ret; page_offset = (*pos) % PAGE_SIZE; - page = mlx5vf_get_migration_page(migf, *pos - page_offset); + page = mlx5vf_get_migration_page(vhca_buf, *pos - page_offset); if (!page) { if (done == 0) done = -EINVAL; @@ -342,7 +339,7 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, len -= page_len; done += page_len; buf += page_len; - migf->total_length += page_len; + vhca_buf->length += page_len; } out_unlock: mutex_unlock(&migf->lock); @@ -360,6 +357,7 @@ static struct mlx5_vf_migration_file * mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) { struct mlx5_vf_migration_file *migf; + struct mlx5_vhca_data_buffer *buf; int ret; migf = kzalloc(sizeof(*migf), GFP_KERNEL); @@ -378,9 +376,18 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) if (ret) goto out_free; + buf = mlx5vf_alloc_data_buffer(migf, 0, DMA_TO_DEVICE); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); + goto out_pd; + } + + migf->buf = buf; stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); return migf; +out_pd: + mlx5vf_cmd_dealloc_pd(migf); out_free: fput(migf->filp); end: @@ -474,7 +481,8 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, if (cur == VFIO_DEVICE_STATE_RESUMING && new == VFIO_DEVICE_STATE_STOP) { ret = mlx5vf_cmd_load_vhca_state(mvdev, - mvdev->resuming_migf); + mvdev->resuming_migf, + mvdev->resuming_migf->buf); if (ret) return ERR_PTR(ret); mlx5vf_disable_fds(mvdev); -- GitLab From 8b599d143419669e57da3881d8293f17809688d7 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:30 +0200 Subject: [PATCH 1331/1480] vfio/mlx5: Refactor migration file state Refactor migration file state to be an emum which is mutual exclusive. As of that dropped the 'disabled' state as 'error' is the same from functional point of view. Next patches from the series will extend this enum for other relevant states. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-7-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 2 +- drivers/vfio/pci/mlx5/cmd.h | 7 +++++-- drivers/vfio/pci/mlx5/main.c | 11 ++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index ed4c472d2eae5..fcba12326185c 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -351,7 +351,7 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mutex_lock(&migf->lock); if (async_data->status) { - migf->is_err = true; + migf->state = MLX5_MIGF_STATE_ERROR; wake_up_interruptible(&migf->poll_wait); } mutex_unlock(&migf->lock); diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index b0f08dfc81207..14403e654e4e4 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -12,6 +12,10 @@ #include #include +enum mlx5_vf_migf_state { + MLX5_MIGF_STATE_ERROR = 1, +}; + struct mlx5_vhca_data_buffer { struct sg_append_table table; loff_t start_pos; @@ -37,8 +41,7 @@ struct mlx5vf_async_data { struct mlx5_vf_migration_file { struct file *filp; struct mutex lock; - u8 disabled:1; - u8 is_err:1; + enum mlx5_vf_migf_state state; u32 pdn; struct mlx5_vhca_data_buffer *buf; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 5f694fce854cf..d95646c2f010d 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -109,7 +109,7 @@ err: static void mlx5vf_disable_fd(struct mlx5_vf_migration_file *migf) { mutex_lock(&migf->lock); - migf->disabled = true; + migf->state = MLX5_MIGF_STATE_ERROR; migf->filp->f_pos = 0; mutex_unlock(&migf->lock); } @@ -137,7 +137,8 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (!(filp->f_flags & O_NONBLOCK)) { if (wait_event_interruptible(migf->poll_wait, - READ_ONCE(vhca_buf->length) || migf->is_err)) + READ_ONCE(vhca_buf->length) || + migf->state == MLX5_MIGF_STATE_ERROR)) return -ERESTARTSYS; } @@ -150,7 +151,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, done = -EINVAL; goto out_unlock; } - if (migf->disabled || migf->is_err) { + if (migf->state == MLX5_MIGF_STATE_ERROR) { done = -ENODEV; goto out_unlock; } @@ -199,7 +200,7 @@ static __poll_t mlx5vf_save_poll(struct file *filp, poll_wait(filp, &migf->poll_wait, wait); mutex_lock(&migf->lock); - if (migf->disabled || migf->is_err) + if (migf->state == MLX5_MIGF_STATE_ERROR) pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; else if (READ_ONCE(migf->buf->length)) pollflags = EPOLLIN | EPOLLRDNORM; @@ -298,7 +299,7 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, return -ENOMEM; mutex_lock(&migf->lock); - if (migf->disabled) { + if (migf->state == MLX5_MIGF_STATE_ERROR) { done = -ENODEV; goto out_unlock; } -- GitLab From c668878381b5702f867ec7f43ee3b74259c6ea03 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:31 +0200 Subject: [PATCH 1332/1480] vfio/mlx5: Refactor to use queue based data chunks Refactor to use queue based data chunks on the migration file. The SAVE command adds a chunk to the tail of the queue while the read() API finds the required chunk and returns its data. In case the queue is empty but the state of the migration file is MLX5_MIGF_STATE_COMPLETE, read() may not be blocked but will return 0 to indicate end of file. This is a step towards maintaining multiple images and their meta data (i.e. headers) on the migration file as part of next patches from the series. Note: At that point, we still use a single chunk on the migration file but becomes ready to support multiple. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-8-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 24 +++++- drivers/vfio/pci/mlx5/cmd.h | 5 ++ drivers/vfio/pci/mlx5/main.c | 145 +++++++++++++++++++++++++++-------- 3 files changed, 136 insertions(+), 38 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index fcba12326185c..0e36b4c8c8169 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -351,6 +351,7 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mutex_lock(&migf->lock); if (async_data->status) { + migf->buf = async_data->buf; migf->state = MLX5_MIGF_STATE_ERROR; wake_up_interruptible(&migf->poll_wait); } @@ -368,9 +369,15 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) struct mlx5_vf_migration_file, async_data); if (!status) { - WRITE_ONCE(migf->buf->length, - MLX5_GET(save_vhca_state_out, async_data->out, - actual_image_size)); + unsigned long flags; + + async_data->buf->length = + MLX5_GET(save_vhca_state_out, async_data->out, + actual_image_size); + spin_lock_irqsave(&migf->list_lock, flags); + list_add_tail(&async_data->buf->buf_elm, &migf->buf_list); + spin_unlock_irqrestore(&migf->list_lock, flags); + migf->state = MLX5_MIGF_STATE_COMPLETE; wake_up_interruptible(&migf->poll_wait); } @@ -407,6 +414,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, MLX5_SET(save_vhca_state_in, in, size, buf->allocated_length); async_data = &migf->async_data; + async_data->buf = buf; async_data->out = kvzalloc(out_size, GFP_KERNEL); if (!async_data->out) { err = -ENOMEM; @@ -479,14 +487,22 @@ void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf) void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf) { - lockdep_assert_held(&migf->mvdev->state_mutex); + struct mlx5_vhca_data_buffer *entry; + lockdep_assert_held(&migf->mvdev->state_mutex); WARN_ON(migf->mvdev->mdev_detach); if (migf->buf) { mlx5vf_free_data_buffer(migf->buf); migf->buf = NULL; } + + while ((entry = list_first_entry_or_null(&migf->buf_list, + struct mlx5_vhca_data_buffer, buf_elm))) { + list_del(&entry->buf_elm); + mlx5vf_free_data_buffer(entry); + } + mlx5vf_cmd_dealloc_pd(migf); } diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 14403e654e4e4..6e594689566e4 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -14,6 +14,7 @@ enum mlx5_vf_migf_state { MLX5_MIGF_STATE_ERROR = 1, + MLX5_MIGF_STATE_COMPLETE, }; struct mlx5_vhca_data_buffer { @@ -24,6 +25,7 @@ struct mlx5_vhca_data_buffer { u32 mkey; enum dma_data_direction dma_dir; u8 dmaed:1; + struct list_head buf_elm; struct mlx5_vf_migration_file *migf; /* Optimize mlx5vf_get_migration_page() for sequential access */ struct scatterlist *last_offset_sg; @@ -34,6 +36,7 @@ struct mlx5_vhca_data_buffer { struct mlx5vf_async_data { struct mlx5_async_work cb_work; struct work_struct work; + struct mlx5_vhca_data_buffer *buf; int status; void *out; }; @@ -45,6 +48,8 @@ struct mlx5_vf_migration_file { u32 pdn; struct mlx5_vhca_data_buffer *buf; + spinlock_t list_lock; + struct list_head buf_list; struct mlx5vf_pci_core_device *mvdev; wait_queue_head_t poll_wait; struct completion save_comp; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index d95646c2f010d..ca16425811c4b 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -124,11 +124,90 @@ static int mlx5vf_release_file(struct inode *inode, struct file *filp) return 0; } +static struct mlx5_vhca_data_buffer * +mlx5vf_get_data_buff_from_pos(struct mlx5_vf_migration_file *migf, loff_t pos, + bool *end_of_data) +{ + struct mlx5_vhca_data_buffer *buf; + bool found = false; + + *end_of_data = false; + spin_lock_irq(&migf->list_lock); + if (list_empty(&migf->buf_list)) { + *end_of_data = true; + goto end; + } + + buf = list_first_entry(&migf->buf_list, struct mlx5_vhca_data_buffer, + buf_elm); + if (pos >= buf->start_pos && + pos < buf->start_pos + buf->length) { + found = true; + goto end; + } + + /* + * As we use a stream based FD we may expect having the data always + * on first chunk + */ + migf->state = MLX5_MIGF_STATE_ERROR; + +end: + spin_unlock_irq(&migf->list_lock); + return found ? buf : NULL; +} + +static ssize_t mlx5vf_buf_read(struct mlx5_vhca_data_buffer *vhca_buf, + char __user **buf, size_t *len, loff_t *pos) +{ + unsigned long offset; + ssize_t done = 0; + size_t copy_len; + + copy_len = min_t(size_t, + vhca_buf->start_pos + vhca_buf->length - *pos, *len); + while (copy_len) { + size_t page_offset; + struct page *page; + size_t page_len; + u8 *from_buff; + int ret; + + offset = *pos - vhca_buf->start_pos; + page_offset = offset % PAGE_SIZE; + offset -= page_offset; + page = mlx5vf_get_migration_page(vhca_buf, offset); + if (!page) + return -EINVAL; + page_len = min_t(size_t, copy_len, PAGE_SIZE - page_offset); + from_buff = kmap_local_page(page); + ret = copy_to_user(*buf, from_buff + page_offset, page_len); + kunmap_local(from_buff); + if (ret) + return -EFAULT; + *pos += page_len; + *len -= page_len; + *buf += page_len; + done += page_len; + copy_len -= page_len; + } + + if (*pos >= vhca_buf->start_pos + vhca_buf->length) { + spin_lock_irq(&vhca_buf->migf->list_lock); + list_del_init(&vhca_buf->buf_elm); + spin_unlock_irq(&vhca_buf->migf->list_lock); + } + + return done; +} + static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, loff_t *pos) { struct mlx5_vf_migration_file *migf = filp->private_data; - struct mlx5_vhca_data_buffer *vhca_buf = migf->buf; + struct mlx5_vhca_data_buffer *vhca_buf; + bool first_loop_call = true; + bool end_of_data; ssize_t done = 0; if (pos) @@ -137,53 +216,47 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (!(filp->f_flags & O_NONBLOCK)) { if (wait_event_interruptible(migf->poll_wait, - READ_ONCE(vhca_buf->length) || - migf->state == MLX5_MIGF_STATE_ERROR)) + !list_empty(&migf->buf_list) || + migf->state == MLX5_MIGF_STATE_ERROR || + migf->state == MLX5_MIGF_STATE_COMPLETE)) return -ERESTARTSYS; } mutex_lock(&migf->lock); - if ((filp->f_flags & O_NONBLOCK) && !READ_ONCE(vhca_buf->length)) { - done = -EAGAIN; - goto out_unlock; - } - if (*pos > vhca_buf->length) { - done = -EINVAL; - goto out_unlock; - } if (migf->state == MLX5_MIGF_STATE_ERROR) { done = -ENODEV; goto out_unlock; } - len = min_t(size_t, vhca_buf->length - *pos, len); while (len) { - size_t page_offset; - struct page *page; - size_t page_len; - u8 *from_buff; - int ret; + ssize_t count; + + vhca_buf = mlx5vf_get_data_buff_from_pos(migf, *pos, + &end_of_data); + if (first_loop_call) { + first_loop_call = false; + if (end_of_data && migf->state != MLX5_MIGF_STATE_COMPLETE) { + if (filp->f_flags & O_NONBLOCK) { + done = -EAGAIN; + goto out_unlock; + } + } + } - page_offset = (*pos) % PAGE_SIZE; - page = mlx5vf_get_migration_page(vhca_buf, *pos - page_offset); - if (!page) { - if (done == 0) - done = -EINVAL; + if (end_of_data) + goto out_unlock; + + if (!vhca_buf) { + done = -EINVAL; goto out_unlock; } - page_len = min_t(size_t, len, PAGE_SIZE - page_offset); - from_buff = kmap_local_page(page); - ret = copy_to_user(buf, from_buff + page_offset, page_len); - kunmap_local(from_buff); - if (ret) { - done = -EFAULT; + count = mlx5vf_buf_read(vhca_buf, &buf, &len, pos); + if (count < 0) { + done = count; goto out_unlock; } - *pos += page_len; - len -= page_len; - done += page_len; - buf += page_len; + done += count; } out_unlock: @@ -202,7 +275,8 @@ static __poll_t mlx5vf_save_poll(struct file *filp, mutex_lock(&migf->lock); if (migf->state == MLX5_MIGF_STATE_ERROR) pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; - else if (READ_ONCE(migf->buf->length)) + else if (!list_empty(&migf->buf_list) || + migf->state == MLX5_MIGF_STATE_COMPLETE) pollflags = EPOLLIN | EPOLLRDNORM; mutex_unlock(&migf->lock); @@ -253,6 +327,8 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) complete(&migf->save_comp); mlx5_cmd_init_async_ctx(mvdev->mdev, &migf->async_ctx); INIT_WORK(&migf->async_data.work, mlx5vf_mig_file_cleanup_cb); + INIT_LIST_HEAD(&migf->buf_list); + spin_lock_init(&migf->list_lock); ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length); if (ret) goto out_pd; @@ -266,7 +342,6 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf); if (ret) goto out_save; - migf->buf = buf; return migf; out_save: mlx5vf_free_data_buffer(buf); @@ -386,6 +461,8 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) migf->buf = buf; stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); + INIT_LIST_HEAD(&migf->buf_list); + spin_lock_init(&migf->list_lock); return migf; out_pd: mlx5vf_cmd_dealloc_pd(migf); -- GitLab From 3319d287f4c04b9deece8ea00e27a70bbe32941b Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:32 +0200 Subject: [PATCH 1333/1480] vfio/mlx5: Introduce device transitions of PRE_COPY In order to support PRE_COPY, mlx5 driver is transferring multiple states (images) of the device. e.g.: the source VF can save and transfer multiple states, and the target VF will load them by that order. The device is saving three kinds of states: 1) Initial state - when the device moves to PRE_COPY state. 2) Middle state - during PRE_COPY phase via VFIO_MIG_GET_PRECOPY_INFO. There can be multiple states of this type. 3) Final state - when the device moves to STOP_COPY state. After moving to PRE_COPY state, user is holding the saving migf FD and can use it. For example: user can start transferring data via read() callback. Also, user can switch from PRE_COPY to STOP_COPY whenever he sees it fits. This will invoke saving of final state. This means that mlx5 VFIO device can be switched to STOP_COPY without transferring any data in PRE_COPY state. Therefore, when the device moves to STOP_COPY, mlx5 will store the final state on a dedicated queue entry on the list. Co-developed-by: Shay Drory Signed-off-by: Shay Drory Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-9-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 96 +++++++++++++++++++++++++++++++++--- drivers/vfio/pci/mlx5/cmd.h | 16 +++++- drivers/vfio/pci/mlx5/main.c | 90 ++++++++++++++++++++++++++++++--- 3 files changed, 184 insertions(+), 18 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 0e36b4c8c8169..5fcece201d4c0 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -14,18 +14,36 @@ _mlx5vf_free_page_tracker_resources(struct mlx5vf_pci_core_device *mvdev); int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod) { + struct mlx5_vf_migration_file *migf = mvdev->saving_migf; u32 out[MLX5_ST_SZ_DW(suspend_vhca_out)] = {}; u32 in[MLX5_ST_SZ_DW(suspend_vhca_in)] = {}; + int err; lockdep_assert_held(&mvdev->state_mutex); if (mvdev->mdev_detach) return -ENOTCONN; + /* + * In case PRE_COPY is used, saving_migf is exposed while the device is + * running. Make sure to run only once there is no active save command. + * Running both in parallel, might end-up with a failure in the save + * command once it will try to turn on 'tracking' on a suspended device. + */ + if (migf) { + err = wait_for_completion_interruptible(&migf->save_comp); + if (err) + return err; + } + MLX5_SET(suspend_vhca_in, in, opcode, MLX5_CMD_OP_SUSPEND_VHCA); MLX5_SET(suspend_vhca_in, in, vhca_id, mvdev->vhca_id); MLX5_SET(suspend_vhca_in, in, op_mod, op_mod); - return mlx5_cmd_exec_inout(mvdev->mdev, suspend_vhca, in, out); + err = mlx5_cmd_exec_inout(mvdev->mdev, suspend_vhca, in, out); + if (migf) + complete(&migf->save_comp); + + return err; } int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod) @@ -45,7 +63,7 @@ int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod) } int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, - size_t *state_size) + size_t *state_size, u8 query_flags) { u32 out[MLX5_ST_SZ_DW(query_vhca_migration_state_out)] = {}; u32 in[MLX5_ST_SZ_DW(query_vhca_migration_state_in)] = {}; @@ -59,6 +77,8 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, MLX5_CMD_OP_QUERY_VHCA_MIGRATION_STATE); MLX5_SET(query_vhca_migration_state_in, in, vhca_id, mvdev->vhca_id); MLX5_SET(query_vhca_migration_state_in, in, op_mod, 0); + MLX5_SET(query_vhca_migration_state_in, in, incremental, + query_flags & MLX5VF_QUERY_INC); ret = mlx5_cmd_exec_inout(mvdev->mdev, query_vhca_migration_state, in, out); @@ -342,6 +362,56 @@ end: return ERR_PTR(ret); } +void mlx5vf_put_data_buffer(struct mlx5_vhca_data_buffer *buf) +{ + spin_lock_irq(&buf->migf->list_lock); + list_add_tail(&buf->buf_elm, &buf->migf->avail_list); + spin_unlock_irq(&buf->migf->list_lock); +} + +struct mlx5_vhca_data_buffer * +mlx5vf_get_data_buffer(struct mlx5_vf_migration_file *migf, + size_t length, enum dma_data_direction dma_dir) +{ + struct mlx5_vhca_data_buffer *buf, *temp_buf; + struct list_head free_list; + + lockdep_assert_held(&migf->mvdev->state_mutex); + if (migf->mvdev->mdev_detach) + return ERR_PTR(-ENOTCONN); + + INIT_LIST_HEAD(&free_list); + + spin_lock_irq(&migf->list_lock); + list_for_each_entry_safe(buf, temp_buf, &migf->avail_list, buf_elm) { + if (buf->dma_dir == dma_dir) { + list_del_init(&buf->buf_elm); + if (buf->allocated_length >= length) { + spin_unlock_irq(&migf->list_lock); + goto found; + } + /* + * Prevent holding redundant buffers. Put in a free + * list and call at the end not under the spin lock + * (&migf->list_lock) to mlx5vf_free_data_buffer which + * might sleep. + */ + list_add(&buf->buf_elm, &free_list); + } + } + spin_unlock_irq(&migf->list_lock); + buf = mlx5vf_alloc_data_buffer(migf, length, dma_dir); + +found: + while ((temp_buf = list_first_entry_or_null(&free_list, + struct mlx5_vhca_data_buffer, buf_elm))) { + list_del(&temp_buf->buf_elm); + mlx5vf_free_data_buffer(temp_buf); + } + + return buf; +} + void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) { struct mlx5vf_async_data *async_data = container_of(_work, @@ -351,7 +421,7 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mutex_lock(&migf->lock); if (async_data->status) { - migf->buf = async_data->buf; + mlx5vf_put_data_buffer(async_data->buf); migf->state = MLX5_MIGF_STATE_ERROR; wake_up_interruptible(&migf->poll_wait); } @@ -369,15 +439,19 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) struct mlx5_vf_migration_file, async_data); if (!status) { + size_t image_size; unsigned long flags; - async_data->buf->length = - MLX5_GET(save_vhca_state_out, async_data->out, - actual_image_size); + image_size = MLX5_GET(save_vhca_state_out, async_data->out, + actual_image_size); + async_data->buf->length = image_size; + async_data->buf->start_pos = migf->max_pos; + migf->max_pos += async_data->buf->length; spin_lock_irqsave(&migf->list_lock, flags); list_add_tail(&async_data->buf->buf_elm, &migf->buf_list); spin_unlock_irqrestore(&migf->list_lock, flags); - migf->state = MLX5_MIGF_STATE_COMPLETE; + if (async_data->last_chunk) + migf->state = MLX5_MIGF_STATE_COMPLETE; wake_up_interruptible(&migf->poll_wait); } @@ -391,7 +465,8 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf, - struct mlx5_vhca_data_buffer *buf) + struct mlx5_vhca_data_buffer *buf, bool inc, + bool track) { u32 out_size = MLX5_ST_SZ_BYTES(save_vhca_state_out); u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {}; @@ -412,9 +487,12 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, MLX5_SET(save_vhca_state_in, in, vhca_id, mvdev->vhca_id); MLX5_SET(save_vhca_state_in, in, mkey, buf->mkey); MLX5_SET(save_vhca_state_in, in, size, buf->allocated_length); + MLX5_SET(save_vhca_state_in, in, incremental, inc); + MLX5_SET(save_vhca_state_in, in, set_track, track); async_data = &migf->async_data; async_data->buf = buf; + async_data->last_chunk = !track; async_data->out = kvzalloc(out_size, GFP_KERNEL); if (!async_data->out) { err = -ENOMEM; @@ -497,6 +575,8 @@ void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf) migf->buf = NULL; } + list_splice(&migf->avail_list, &migf->buf_list); + while ((entry = list_first_entry_or_null(&migf->buf_list, struct mlx5_vhca_data_buffer, buf_elm))) { list_del(&entry->buf_elm); diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 6e594689566e4..34e61c7aa23d1 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -38,6 +38,7 @@ struct mlx5vf_async_data { struct work_struct work; struct mlx5_vhca_data_buffer *buf; int status; + u8 last_chunk:1; void *out; }; @@ -47,9 +48,11 @@ struct mlx5_vf_migration_file { enum mlx5_vf_migf_state state; u32 pdn; + loff_t max_pos; struct mlx5_vhca_data_buffer *buf; spinlock_t list_lock; struct list_head buf_list; + struct list_head avail_list; struct mlx5vf_pci_core_device *mvdev; wait_queue_head_t poll_wait; struct completion save_comp; @@ -129,10 +132,14 @@ struct mlx5vf_pci_core_device { struct mlx5_core_dev *mdev; }; +enum { + MLX5VF_QUERY_INC = (1UL << 0), +}; + int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod); int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod); int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, - size_t *state_size); + size_t *state_size, u8 query_flags); void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev, const struct vfio_migration_ops *mig_ops, const struct vfio_log_ops *log_ops); @@ -140,7 +147,8 @@ void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev); int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf, - struct mlx5_vhca_data_buffer *buf); + struct mlx5_vhca_data_buffer *buf, bool inc, + bool track); int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf, struct mlx5_vhca_data_buffer *buf); @@ -151,6 +159,10 @@ struct mlx5_vhca_data_buffer * mlx5vf_alloc_data_buffer(struct mlx5_vf_migration_file *migf, size_t length, enum dma_data_direction dma_dir); void mlx5vf_free_data_buffer(struct mlx5_vhca_data_buffer *buf); +struct mlx5_vhca_data_buffer * +mlx5vf_get_data_buffer(struct mlx5_vf_migration_file *migf, + size_t length, enum dma_data_direction dma_dir); +void mlx5vf_put_data_buffer(struct mlx5_vhca_data_buffer *buf); int mlx5vf_add_migration_pages(struct mlx5_vhca_data_buffer *buf, unsigned int npages); void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index ca16425811c4b..9cabba4560447 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -195,6 +195,7 @@ static ssize_t mlx5vf_buf_read(struct mlx5_vhca_data_buffer *vhca_buf, if (*pos >= vhca_buf->start_pos + vhca_buf->length) { spin_lock_irq(&vhca_buf->migf->list_lock); list_del_init(&vhca_buf->buf_elm); + list_add_tail(&vhca_buf->buf_elm, &vhca_buf->migf->avail_list); spin_unlock_irq(&vhca_buf->migf->list_lock); } @@ -283,6 +284,16 @@ static __poll_t mlx5vf_save_poll(struct file *filp, return pollflags; } +/* + * FD is exposed and user can use it after receiving an error. + * Mark migf in error, and wake the user. + */ +static void mlx5vf_mark_err(struct mlx5_vf_migration_file *migf) +{ + migf->state = MLX5_MIGF_STATE_ERROR; + wake_up_interruptible(&migf->poll_wait); +} + static const struct file_operations mlx5vf_save_fops = { .owner = THIS_MODULE, .read = mlx5vf_save_read, @@ -291,8 +302,42 @@ static const struct file_operations mlx5vf_save_fops = { .llseek = no_llseek, }; +static int mlx5vf_pci_save_device_inc_data(struct mlx5vf_pci_core_device *mvdev) +{ + struct mlx5_vf_migration_file *migf = mvdev->saving_migf; + struct mlx5_vhca_data_buffer *buf; + size_t length; + int ret; + + if (migf->state == MLX5_MIGF_STATE_ERROR) + return -ENODEV; + + ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, + MLX5VF_QUERY_INC); + if (ret) + goto err; + + buf = mlx5vf_get_data_buffer(migf, length, DMA_FROM_DEVICE); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); + goto err; + } + + ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, true, false); + if (ret) + goto err_save; + + return 0; + +err_save: + mlx5vf_put_data_buffer(buf); +err: + mlx5vf_mark_err(migf); + return ret; +} + static struct mlx5_vf_migration_file * -mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) +mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track) { struct mlx5_vf_migration_file *migf; struct mlx5_vhca_data_buffer *buf; @@ -328,8 +373,9 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) mlx5_cmd_init_async_ctx(mvdev->mdev, &migf->async_ctx); INIT_WORK(&migf->async_data.work, mlx5vf_mig_file_cleanup_cb); INIT_LIST_HEAD(&migf->buf_list); + INIT_LIST_HEAD(&migf->avail_list); spin_lock_init(&migf->list_lock); - ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length); + ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, 0); if (ret) goto out_pd; @@ -339,7 +385,7 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev) goto out_pd; } - ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf); + ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, false, track); if (ret) goto out_save; return migf; @@ -462,6 +508,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); INIT_LIST_HEAD(&migf->buf_list); + INIT_LIST_HEAD(&migf->avail_list); spin_lock_init(&migf->list_lock); return migf; out_pd: @@ -514,7 +561,8 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, return NULL; } - if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_RUNNING_P2P) { + if ((cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_RUNNING_P2P) || + (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_PRE_COPY_P2P)) { ret = mlx5vf_cmd_suspend_vhca(mvdev, MLX5_SUSPEND_VHCA_IN_OP_MOD_SUSPEND_INITIATOR); if (ret) @@ -522,7 +570,8 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, return NULL; } - if (cur == VFIO_DEVICE_STATE_RUNNING_P2P && new == VFIO_DEVICE_STATE_RUNNING) { + if ((cur == VFIO_DEVICE_STATE_RUNNING_P2P && new == VFIO_DEVICE_STATE_RUNNING) || + (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P && new == VFIO_DEVICE_STATE_PRE_COPY)) { ret = mlx5vf_cmd_resume_vhca(mvdev, MLX5_RESUME_VHCA_IN_OP_MOD_RESUME_INITIATOR); if (ret) @@ -533,7 +582,7 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_STOP_COPY) { struct mlx5_vf_migration_file *migf; - migf = mlx5vf_pci_save_device_data(mvdev); + migf = mlx5vf_pci_save_device_data(mvdev, false); if (IS_ERR(migf)) return ERR_CAST(migf); get_file(migf->filp); @@ -541,7 +590,10 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, return migf->filp; } - if ((cur == VFIO_DEVICE_STATE_STOP_COPY && new == VFIO_DEVICE_STATE_STOP)) { + if ((cur == VFIO_DEVICE_STATE_STOP_COPY && new == VFIO_DEVICE_STATE_STOP) || + (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) || + (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P && + new == VFIO_DEVICE_STATE_RUNNING_P2P)) { mlx5vf_disable_fds(mvdev); return NULL; } @@ -567,6 +619,28 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, return NULL; } + if ((cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_PRE_COPY) || + (cur == VFIO_DEVICE_STATE_RUNNING_P2P && + new == VFIO_DEVICE_STATE_PRE_COPY_P2P)) { + struct mlx5_vf_migration_file *migf; + + migf = mlx5vf_pci_save_device_data(mvdev, true); + if (IS_ERR(migf)) + return ERR_CAST(migf); + get_file(migf->filp); + mvdev->saving_migf = migf; + return migf->filp; + } + + if (cur == VFIO_DEVICE_STATE_PRE_COPY_P2P && new == VFIO_DEVICE_STATE_STOP_COPY) { + ret = mlx5vf_cmd_suspend_vhca(mvdev, + MLX5_SUSPEND_VHCA_IN_OP_MOD_SUSPEND_RESPONDER); + if (ret) + return ERR_PTR(ret); + ret = mlx5vf_pci_save_device_inc_data(mvdev); + return ret ? ERR_PTR(ret) : NULL; + } + /* * vfio_mig_get_next_state() does not use arcs other than the above */ @@ -635,7 +709,7 @@ static int mlx5vf_pci_get_data_size(struct vfio_device *vdev, mutex_lock(&mvdev->state_mutex); ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, - &state_size); + &state_size, 0); if (!ret) *stop_copy_length = state_size; mlx5vf_state_mutex_unlock(mvdev); -- GitLab From 0c9a38fee8b210a8dfd3f177526daac567ec9265 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:33 +0200 Subject: [PATCH 1334/1480] vfio/mlx5: Introduce SW headers for migration states As mentioned in the previous patches, mlx5 is transferring multiple states when the PRE_COPY protocol is used. This states mechanism requires the target VM to know the states' size in order to execute multiple loads. Therefore, add SW header, with the needed information, for each saved state the source VM is transferring to the target VM. This patch implements the source VM handling of the headers, following patch will implement the target VM handling of the headers. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-10-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 56 ++++++++++++++++++++++++++++++++++-- drivers/vfio/pci/mlx5/cmd.h | 13 +++++++++ drivers/vfio/pci/mlx5/main.c | 2 +- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 5fcece201d4c0..160fa38fc78dd 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -351,9 +351,11 @@ mlx5vf_alloc_data_buffer(struct mlx5_vf_migration_file *migf, if (ret) goto end; - ret = mlx5vf_dma_data_buffer(buf); - if (ret) - goto end; + if (dma_dir != DMA_NONE) { + ret = mlx5vf_dma_data_buffer(buf); + if (ret) + goto end; + } } return buf; @@ -422,6 +424,8 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mutex_lock(&migf->lock); if (async_data->status) { mlx5vf_put_data_buffer(async_data->buf); + if (async_data->header_buf) + mlx5vf_put_data_buffer(async_data->header_buf); migf->state = MLX5_MIGF_STATE_ERROR; wake_up_interruptible(&migf->poll_wait); } @@ -431,6 +435,32 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) fput(migf->filp); } +static int add_buf_header(struct mlx5_vhca_data_buffer *header_buf, + size_t image_size) +{ + struct mlx5_vf_migration_file *migf = header_buf->migf; + struct mlx5_vf_migration_header header = {}; + unsigned long flags; + struct page *page; + u8 *to_buff; + + header.image_size = cpu_to_le64(image_size); + page = mlx5vf_get_migration_page(header_buf, 0); + if (!page) + return -EINVAL; + to_buff = kmap_local_page(page); + memcpy(to_buff, &header, sizeof(header)); + kunmap_local(to_buff); + header_buf->length = sizeof(header); + header_buf->header_image_size = image_size; + header_buf->start_pos = header_buf->migf->max_pos; + migf->max_pos += header_buf->length; + spin_lock_irqsave(&migf->list_lock, flags); + list_add_tail(&header_buf->buf_elm, &migf->buf_list); + spin_unlock_irqrestore(&migf->list_lock, flags); + return 0; +} + static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) { struct mlx5vf_async_data *async_data = container_of(context, @@ -444,6 +474,11 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) image_size = MLX5_GET(save_vhca_state_out, async_data->out, actual_image_size); + if (async_data->header_buf) { + status = add_buf_header(async_data->header_buf, image_size); + if (status) + goto err; + } async_data->buf->length = image_size; async_data->buf->start_pos = migf->max_pos; migf->max_pos += async_data->buf->length; @@ -455,6 +490,7 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) wake_up_interruptible(&migf->poll_wait); } +err: /* * The error and the cleanup flows can't run from an * interrupt context @@ -470,6 +506,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, { u32 out_size = MLX5_ST_SZ_BYTES(save_vhca_state_out); u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {}; + struct mlx5_vhca_data_buffer *header_buf = NULL; struct mlx5vf_async_data *async_data; int err; @@ -499,6 +536,16 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, goto err_out; } + if (MLX5VF_PRE_COPY_SUPP(mvdev)) { + header_buf = mlx5vf_get_data_buffer(migf, + sizeof(struct mlx5_vf_migration_header), DMA_NONE); + if (IS_ERR(header_buf)) { + err = PTR_ERR(header_buf); + goto err_free; + } + } + + async_data->header_buf = header_buf; get_file(migf->filp); err = mlx5_cmd_exec_cb(&migf->async_ctx, in, sizeof(in), async_data->out, @@ -510,7 +557,10 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, return 0; err_exec: + if (header_buf) + mlx5vf_put_data_buffer(header_buf); fput(migf->filp); +err_free: kvfree(async_data->out); err_out: complete(&migf->save_comp); diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 34e61c7aa23d1..3e36ccca820ad 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -12,16 +12,26 @@ #include #include +#define MLX5VF_PRE_COPY_SUPP(mvdev) \ + ((mvdev)->core_device.vdev.migration_flags & VFIO_MIGRATION_PRE_COPY) + enum mlx5_vf_migf_state { MLX5_MIGF_STATE_ERROR = 1, MLX5_MIGF_STATE_COMPLETE, }; +struct mlx5_vf_migration_header { + __le64 image_size; + /* For future use in case we may need to change the kernel protocol */ + __le64 flags; +}; + struct mlx5_vhca_data_buffer { struct sg_append_table table; loff_t start_pos; u64 length; u64 allocated_length; + u64 header_image_size; u32 mkey; enum dma_data_direction dma_dir; u8 dmaed:1; @@ -37,6 +47,7 @@ struct mlx5vf_async_data { struct mlx5_async_work cb_work; struct work_struct work; struct mlx5_vhca_data_buffer *buf; + struct mlx5_vhca_data_buffer *header_buf; int status; u8 last_chunk:1; void *out; @@ -165,6 +176,8 @@ mlx5vf_get_data_buffer(struct mlx5_vf_migration_file *migf, void mlx5vf_put_data_buffer(struct mlx5_vhca_data_buffer *buf); int mlx5vf_add_migration_pages(struct mlx5_vhca_data_buffer *buf, unsigned int npages); +struct page *mlx5vf_get_migration_page(struct mlx5_vhca_data_buffer *buf, + unsigned long offset); void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 9cabba4560447..9a36e36ec33b7 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -32,7 +32,7 @@ static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) core_device); } -static struct page * +struct page * mlx5vf_get_migration_page(struct mlx5_vhca_data_buffer *buf, unsigned long offset) { -- GitLab From 0dce165b1adf8d7f67030bb257e00107db8022de Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:34 +0200 Subject: [PATCH 1335/1480] vfio/mlx5: Introduce vfio precopy ioctl implementation vfio precopy ioctl returns an estimation of data available for transferring from the device. Whenever a user is using VFIO_MIG_GET_PRECOPY_INFO, track the current state of the device, and if needed, append the dirty data to the transfer FD data. This is done by saving a middle state. As mlx5 runs the SAVE command asynchronously, make sure to query for incremental data only once there is no active save command. Running both in parallel, might end-up with a failure in the incremental query command on un-tracked vhca. Also, a middle state will be saved only after the previous state has finished its SAVE command and has been fully transferred, this prevents endless use resources. Co-developed-by: Shay Drory Signed-off-by: Shay Drory Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-11-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 16 +++++ drivers/vfio/pci/mlx5/main.c | 111 +++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 160fa38fc78dd..12e74ecebe641 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -67,12 +67,25 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, { u32 out[MLX5_ST_SZ_DW(query_vhca_migration_state_out)] = {}; u32 in[MLX5_ST_SZ_DW(query_vhca_migration_state_in)] = {}; + bool inc = query_flags & MLX5VF_QUERY_INC; int ret; lockdep_assert_held(&mvdev->state_mutex); if (mvdev->mdev_detach) return -ENOTCONN; + /* + * In case PRE_COPY is used, saving_migf is exposed while device is + * running. Make sure to run only once there is no active save command. + * Running both in parallel, might end-up with a failure in the + * incremental query command on un-tracked vhca. + */ + if (inc) { + ret = wait_for_completion_interruptible(&mvdev->saving_migf->save_comp); + if (ret) + return ret; + } + MLX5_SET(query_vhca_migration_state_in, in, opcode, MLX5_CMD_OP_QUERY_VHCA_MIGRATION_STATE); MLX5_SET(query_vhca_migration_state_in, in, vhca_id, mvdev->vhca_id); @@ -82,6 +95,9 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, ret = mlx5_cmd_exec_inout(mvdev->mdev, query_vhca_migration_state, in, out); + if (inc) + complete(&mvdev->saving_migf->save_comp); + if (ret) return ret; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 9a36e36ec33b7..2c8ac763057cd 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -294,10 +294,121 @@ static void mlx5vf_mark_err(struct mlx5_vf_migration_file *migf) wake_up_interruptible(&migf->poll_wait); } +static long mlx5vf_precopy_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct mlx5_vf_migration_file *migf = filp->private_data; + struct mlx5vf_pci_core_device *mvdev = migf->mvdev; + struct mlx5_vhca_data_buffer *buf; + struct vfio_precopy_info info = {}; + loff_t *pos = &filp->f_pos; + unsigned long minsz; + size_t inc_length = 0; + bool end_of_data; + int ret; + + if (cmd != VFIO_MIG_GET_PRECOPY_INFO) + return -ENOTTY; + + minsz = offsetofend(struct vfio_precopy_info, dirty_bytes); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + + if (info.argsz < minsz) + return -EINVAL; + + mutex_lock(&mvdev->state_mutex); + if (mvdev->mig_state != VFIO_DEVICE_STATE_PRE_COPY && + mvdev->mig_state != VFIO_DEVICE_STATE_PRE_COPY_P2P) { + ret = -EINVAL; + goto err_state_unlock; + } + + /* + * We can't issue a SAVE command when the device is suspended, so as + * part of VFIO_DEVICE_STATE_PRE_COPY_P2P no reason to query for extra + * bytes that can't be read. + */ + if (mvdev->mig_state == VFIO_DEVICE_STATE_PRE_COPY) { + /* + * Once the query returns it's guaranteed that there is no + * active SAVE command. + * As so, the other code below is safe with the proper locks. + */ + ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &inc_length, + MLX5VF_QUERY_INC); + if (ret) + goto err_state_unlock; + } + + mutex_lock(&migf->lock); + if (migf->state == MLX5_MIGF_STATE_ERROR) { + ret = -ENODEV; + goto err_migf_unlock; + } + + buf = mlx5vf_get_data_buff_from_pos(migf, *pos, &end_of_data); + if (buf) { + if (buf->start_pos == 0) { + info.initial_bytes = buf->header_image_size - *pos; + } else if (buf->start_pos == + sizeof(struct mlx5_vf_migration_header)) { + /* First data buffer following the header */ + info.initial_bytes = buf->start_pos + + buf->length - *pos; + } else { + info.dirty_bytes = buf->start_pos + buf->length - *pos; + } + } else { + if (!end_of_data) { + ret = -EINVAL; + goto err_migf_unlock; + } + + info.dirty_bytes = inc_length; + } + + if (!end_of_data || !inc_length) { + mutex_unlock(&migf->lock); + goto done; + } + + mutex_unlock(&migf->lock); + /* + * We finished transferring the current state and the device has a + * dirty state, save a new state to be ready for. + */ + buf = mlx5vf_get_data_buffer(migf, inc_length, DMA_FROM_DEVICE); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); + mlx5vf_mark_err(migf); + goto err_state_unlock; + } + + ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, true, true); + if (ret) { + mlx5vf_mark_err(migf); + mlx5vf_put_data_buffer(buf); + goto err_state_unlock; + } + +done: + mlx5vf_state_mutex_unlock(mvdev); + return copy_to_user((void __user *)arg, &info, minsz); +err_migf_unlock: + mutex_unlock(&migf->lock); +err_state_unlock: + mlx5vf_state_mutex_unlock(mvdev); + return ret; +} + static const struct file_operations mlx5vf_save_fops = { .owner = THIS_MODULE, .read = mlx5vf_save_read, .poll = mlx5vf_save_poll, + .unlocked_ioctl = mlx5vf_precopy_ioctl, + .compat_ioctl = compat_ptr_ioctl, .release = mlx5vf_release_file, .llseek = no_llseek, }; -- GitLab From 81156c27271c4a6c594e492c8d119fbacfc99f36 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:35 +0200 Subject: [PATCH 1336/1480] vfio/mlx5: Consider temporary end of stream as part of PRE_COPY During PRE_COPY the migration data FD may have a temporary "end of stream" that is reached when the initial_bytes were read and no other dirty data exists yet. For instance, this may indicate that the device is idle and not currently dirtying any internal state. When read() is done on this temporary end of stream the kernel driver should return ENOMSG from read(). Userspace can wait for more data or consider moving to STOP_COPY. To not block the user upon read() and let it get ENOMSG we add a new state named MLX5_MIGF_STATE_PRE_COPY on the migration file. In addition, we add the MLX5_MIGF_STATE_SAVE_LAST state to block the read() once we call the last SAVE upon moving to STOP_COPY. Any further error will be marked with MLX5_MIGF_STATE_ERROR and the user won't be blocked. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-12-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 7 +++++-- drivers/vfio/pci/mlx5/cmd.h | 2 ++ drivers/vfio/pci/mlx5/main.c | 7 +++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 12e74ecebe641..f6293da033cca 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -501,8 +501,8 @@ static void mlx5vf_save_callback(int status, struct mlx5_async_work *context) spin_lock_irqsave(&migf->list_lock, flags); list_add_tail(&async_data->buf->buf_elm, &migf->buf_list); spin_unlock_irqrestore(&migf->list_lock, flags); - if (async_data->last_chunk) - migf->state = MLX5_MIGF_STATE_COMPLETE; + migf->state = async_data->last_chunk ? + MLX5_MIGF_STATE_COMPLETE : MLX5_MIGF_STATE_PRE_COPY; wake_up_interruptible(&migf->poll_wait); } @@ -561,6 +561,9 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, } } + if (async_data->last_chunk) + migf->state = MLX5_MIGF_STATE_SAVE_LAST; + async_data->header_buf = header_buf; get_file(migf->filp); err = mlx5_cmd_exec_cb(&migf->async_ctx, in, sizeof(in), diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 3e36ccca820ad..d048f23977dd1 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -17,6 +17,8 @@ enum mlx5_vf_migf_state { MLX5_MIGF_STATE_ERROR = 1, + MLX5_MIGF_STATE_PRE_COPY, + MLX5_MIGF_STATE_SAVE_LAST, MLX5_MIGF_STATE_COMPLETE, }; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 2c8ac763057cd..44b1543c751c9 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -219,6 +219,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (wait_event_interruptible(migf->poll_wait, !list_empty(&migf->buf_list) || migf->state == MLX5_MIGF_STATE_ERROR || + migf->state == MLX5_MIGF_STATE_PRE_COPY || migf->state == MLX5_MIGF_STATE_COMPLETE)) return -ERESTARTSYS; } @@ -236,6 +237,12 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, &end_of_data); if (first_loop_call) { first_loop_call = false; + /* Temporary end of file as part of PRE_COPY */ + if (end_of_data && migf->state == MLX5_MIGF_STATE_PRE_COPY) { + done = -ENOMSG; + goto out_unlock; + } + if (end_of_data && migf->state != MLX5_MIGF_STATE_COMPLETE) { if (filp->f_flags & O_NONBLOCK) { done = -EAGAIN; -- GitLab From 34e2f27143d1b373f088e805f7e11cdf778f791d Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Tue, 6 Dec 2022 10:34:36 +0200 Subject: [PATCH 1337/1480] vfio/mlx5: Introduce multiple loads In order to support PRE_COPY, mlx5 driver transfers multiple states (images) of the device. e.g.: the source VF can save and transfer multiple states, and the target VF will load them by that order. This patch implements the changes for the target VF to decompose the header for each state and to write and load multiple states. Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-13-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 13 +- drivers/vfio/pci/mlx5/cmd.h | 10 ++ drivers/vfio/pci/mlx5/main.c | 279 +++++++++++++++++++++++++++++------ 3 files changed, 257 insertions(+), 45 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index f6293da033cca..993749818d90f 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -598,9 +598,11 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, if (mvdev->mdev_detach) return -ENOTCONN; - err = mlx5vf_dma_data_buffer(buf); - if (err) - return err; + if (!buf->dmaed) { + err = mlx5vf_dma_data_buffer(buf); + if (err) + return err; + } MLX5_SET(load_vhca_state_in, in, opcode, MLX5_CMD_OP_LOAD_VHCA_STATE); @@ -644,6 +646,11 @@ void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf) migf->buf = NULL; } + if (migf->buf_header) { + mlx5vf_free_data_buffer(migf->buf_header); + migf->buf_header = NULL; + } + list_splice(&migf->avail_list, &migf->buf_list); while ((entry = list_first_entry_or_null(&migf->buf_list, diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index d048f23977dd1..7729eac8c78c1 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -22,6 +22,14 @@ enum mlx5_vf_migf_state { MLX5_MIGF_STATE_COMPLETE, }; +enum mlx5_vf_load_state { + MLX5_VF_LOAD_STATE_READ_IMAGE_NO_HEADER, + MLX5_VF_LOAD_STATE_READ_HEADER, + MLX5_VF_LOAD_STATE_PREP_IMAGE, + MLX5_VF_LOAD_STATE_READ_IMAGE, + MLX5_VF_LOAD_STATE_LOAD_IMAGE, +}; + struct mlx5_vf_migration_header { __le64 image_size; /* For future use in case we may need to change the kernel protocol */ @@ -60,9 +68,11 @@ struct mlx5_vf_migration_file { struct mutex lock; enum mlx5_vf_migf_state state; + enum mlx5_vf_load_state load_state; u32 pdn; loff_t max_pos; struct mlx5_vhca_data_buffer *buf; + struct mlx5_vhca_data_buffer *buf_header; spinlock_t list_lock; struct list_head buf_list; struct list_head avail_list; diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 44b1543c751c9..5a669b73994a7 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -518,13 +518,162 @@ end: return ERR_PTR(ret); } +static int +mlx5vf_append_page_to_mig_buf(struct mlx5_vhca_data_buffer *vhca_buf, + const char __user **buf, size_t *len, + loff_t *pos, ssize_t *done) +{ + unsigned long offset; + size_t page_offset; + struct page *page; + size_t page_len; + u8 *to_buff; + int ret; + + offset = *pos - vhca_buf->start_pos; + page_offset = offset % PAGE_SIZE; + + page = mlx5vf_get_migration_page(vhca_buf, offset - page_offset); + if (!page) + return -EINVAL; + page_len = min_t(size_t, *len, PAGE_SIZE - page_offset); + to_buff = kmap_local_page(page); + ret = copy_from_user(to_buff + page_offset, *buf, page_len); + kunmap_local(to_buff); + if (ret) + return -EFAULT; + + *pos += page_len; + *done += page_len; + *buf += page_len; + *len -= page_len; + vhca_buf->length += page_len; + return 0; +} + +static int +mlx5vf_resume_read_image_no_header(struct mlx5_vhca_data_buffer *vhca_buf, + loff_t requested_length, + const char __user **buf, size_t *len, + loff_t *pos, ssize_t *done) +{ + int ret; + + if (requested_length > MAX_MIGRATION_SIZE) + return -ENOMEM; + + if (vhca_buf->allocated_length < requested_length) { + ret = mlx5vf_add_migration_pages( + vhca_buf, + DIV_ROUND_UP(requested_length - vhca_buf->allocated_length, + PAGE_SIZE)); + if (ret) + return ret; + } + + while (*len) { + ret = mlx5vf_append_page_to_mig_buf(vhca_buf, buf, len, pos, + done); + if (ret) + return ret; + } + + return 0; +} + +static ssize_t +mlx5vf_resume_read_image(struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *vhca_buf, + size_t image_size, const char __user **buf, + size_t *len, loff_t *pos, ssize_t *done, + bool *has_work) +{ + size_t copy_len, to_copy; + int ret; + + to_copy = min_t(size_t, *len, image_size - vhca_buf->length); + copy_len = to_copy; + while (to_copy) { + ret = mlx5vf_append_page_to_mig_buf(vhca_buf, buf, &to_copy, pos, + done); + if (ret) + return ret; + } + + *len -= copy_len; + if (vhca_buf->length == image_size) { + migf->load_state = MLX5_VF_LOAD_STATE_LOAD_IMAGE; + migf->max_pos += image_size; + *has_work = true; + } + + return 0; +} + +static int +mlx5vf_resume_read_header(struct mlx5_vf_migration_file *migf, + struct mlx5_vhca_data_buffer *vhca_buf, + const char __user **buf, + size_t *len, loff_t *pos, + ssize_t *done, bool *has_work) +{ + struct page *page; + size_t copy_len; + u8 *to_buff; + int ret; + + copy_len = min_t(size_t, *len, + sizeof(struct mlx5_vf_migration_header) - vhca_buf->length); + page = mlx5vf_get_migration_page(vhca_buf, 0); + if (!page) + return -EINVAL; + to_buff = kmap_local_page(page); + ret = copy_from_user(to_buff + vhca_buf->length, *buf, copy_len); + if (ret) { + ret = -EFAULT; + goto end; + } + + *buf += copy_len; + *pos += copy_len; + *done += copy_len; + *len -= copy_len; + vhca_buf->length += copy_len; + if (vhca_buf->length == sizeof(struct mlx5_vf_migration_header)) { + u64 flags; + + vhca_buf->header_image_size = le64_to_cpup((__le64 *)to_buff); + if (vhca_buf->header_image_size > MAX_MIGRATION_SIZE) { + ret = -ENOMEM; + goto end; + } + + flags = le64_to_cpup((__le64 *)(to_buff + + offsetof(struct mlx5_vf_migration_header, flags))); + if (flags) { + ret = -EOPNOTSUPP; + goto end; + } + + migf->load_state = MLX5_VF_LOAD_STATE_PREP_IMAGE; + migf->max_pos += vhca_buf->length; + *has_work = true; + } +end: + kunmap_local(to_buff); + return ret; +} + static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, size_t len, loff_t *pos) { struct mlx5_vf_migration_file *migf = filp->private_data; struct mlx5_vhca_data_buffer *vhca_buf = migf->buf; + struct mlx5_vhca_data_buffer *vhca_buf_header = migf->buf_header; loff_t requested_length; + bool has_work = false; ssize_t done = 0; + int ret = 0; if (pos) return -ESPIPE; @@ -534,56 +683,83 @@ static ssize_t mlx5vf_resume_write(struct file *filp, const char __user *buf, check_add_overflow((loff_t)len, *pos, &requested_length)) return -EINVAL; - if (requested_length > MAX_MIGRATION_SIZE) - return -ENOMEM; - + mutex_lock(&migf->mvdev->state_mutex); mutex_lock(&migf->lock); if (migf->state == MLX5_MIGF_STATE_ERROR) { - done = -ENODEV; + ret = -ENODEV; goto out_unlock; } - if (vhca_buf->allocated_length < requested_length) { - done = mlx5vf_add_migration_pages( - vhca_buf, - DIV_ROUND_UP(requested_length - vhca_buf->allocated_length, - PAGE_SIZE)); - if (done) - goto out_unlock; - } + while (len || has_work) { + has_work = false; + switch (migf->load_state) { + case MLX5_VF_LOAD_STATE_READ_HEADER: + ret = mlx5vf_resume_read_header(migf, vhca_buf_header, + &buf, &len, pos, + &done, &has_work); + if (ret) + goto out_unlock; + break; + case MLX5_VF_LOAD_STATE_PREP_IMAGE: + { + u64 size = vhca_buf_header->header_image_size; + + if (vhca_buf->allocated_length < size) { + mlx5vf_free_data_buffer(vhca_buf); + + migf->buf = mlx5vf_alloc_data_buffer(migf, + size, DMA_TO_DEVICE); + if (IS_ERR(migf->buf)) { + ret = PTR_ERR(migf->buf); + migf->buf = NULL; + goto out_unlock; + } - while (len) { - size_t page_offset; - struct page *page; - size_t page_len; - u8 *to_buff; - int ret; + vhca_buf = migf->buf; + } - page_offset = (*pos) % PAGE_SIZE; - page = mlx5vf_get_migration_page(vhca_buf, *pos - page_offset); - if (!page) { - if (done == 0) - done = -EINVAL; - goto out_unlock; + vhca_buf->start_pos = migf->max_pos; + migf->load_state = MLX5_VF_LOAD_STATE_READ_IMAGE; + break; } + case MLX5_VF_LOAD_STATE_READ_IMAGE_NO_HEADER: + ret = mlx5vf_resume_read_image_no_header(vhca_buf, + requested_length, + &buf, &len, pos, &done); + if (ret) + goto out_unlock; + break; + case MLX5_VF_LOAD_STATE_READ_IMAGE: + ret = mlx5vf_resume_read_image(migf, vhca_buf, + vhca_buf_header->header_image_size, + &buf, &len, pos, &done, &has_work); + if (ret) + goto out_unlock; + break; + case MLX5_VF_LOAD_STATE_LOAD_IMAGE: + ret = mlx5vf_cmd_load_vhca_state(migf->mvdev, migf, vhca_buf); + if (ret) + goto out_unlock; + migf->load_state = MLX5_VF_LOAD_STATE_READ_HEADER; - page_len = min_t(size_t, len, PAGE_SIZE - page_offset); - to_buff = kmap_local_page(page); - ret = copy_from_user(to_buff + page_offset, buf, page_len); - kunmap_local(to_buff); - if (ret) { - done = -EFAULT; - goto out_unlock; + /* prep header buf for next image */ + vhca_buf_header->length = 0; + vhca_buf_header->header_image_size = 0; + /* prep data buf for next image */ + vhca_buf->length = 0; + + break; + default: + break; } - *pos += page_len; - len -= page_len; - done += page_len; - buf += page_len; - vhca_buf->length += page_len; } + out_unlock: + if (ret) + migf->state = MLX5_MIGF_STATE_ERROR; mutex_unlock(&migf->lock); - return done; + mlx5vf_state_mutex_unlock(migf->mvdev); + return ret ? ret : done; } static const struct file_operations mlx5vf_resume_fops = { @@ -623,12 +799,29 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) } migf->buf = buf; + if (MLX5VF_PRE_COPY_SUPP(mvdev)) { + buf = mlx5vf_alloc_data_buffer(migf, + sizeof(struct mlx5_vf_migration_header), DMA_NONE); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); + goto out_buf; + } + + migf->buf_header = buf; + migf->load_state = MLX5_VF_LOAD_STATE_READ_HEADER; + } else { + /* Initial state will be to read the image */ + migf->load_state = MLX5_VF_LOAD_STATE_READ_IMAGE_NO_HEADER; + } + stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); INIT_LIST_HEAD(&migf->buf_list); INIT_LIST_HEAD(&migf->avail_list); spin_lock_init(&migf->list_lock); return migf; +out_buf: + mlx5vf_free_data_buffer(buf); out_pd: mlx5vf_cmd_dealloc_pd(migf); out_free: @@ -728,11 +921,13 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev, } if (cur == VFIO_DEVICE_STATE_RESUMING && new == VFIO_DEVICE_STATE_STOP) { - ret = mlx5vf_cmd_load_vhca_state(mvdev, - mvdev->resuming_migf, - mvdev->resuming_migf->buf); - if (ret) - return ERR_PTR(ret); + if (!MLX5VF_PRE_COPY_SUPP(mvdev)) { + ret = mlx5vf_cmd_load_vhca_state(mvdev, + mvdev->resuming_migf, + mvdev->resuming_migf->buf); + if (ret) + return ERR_PTR(ret); + } mlx5vf_disable_fds(mvdev); return NULL; } -- GitLab From d6e18a4bec431c181a60d32876c6c89955b2a4f8 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 6 Dec 2022 10:34:37 +0200 Subject: [PATCH 1338/1480] vfio/mlx5: Fallback to STOP_COPY upon specific PRE_COPY error Before a SAVE command is issued, a QUERY command is issued in order to know the device data size. In case PRE_COPY is used, the above commands are issued while the device is running. Thus, it is possible that between the QUERY and the SAVE commands the state of the device will be changed significantly and thus the SAVE will fail. Currently, if a SAVE command is failing, the driver will fail the migration. In the above case, don't fail the migration, but don't allow for new SAVEs to be executed while the device is in a RUNNING state. Once the device will be moved to STOP_COPY, SAVE can be executed again and the full device state will be read. Signed-off-by: Shay Drory Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-14-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 27 ++++++++++++++++++++++++++- drivers/vfio/pci/mlx5/cmd.h | 2 ++ drivers/vfio/pci/mlx5/main.c | 6 ++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 993749818d90f..01ef695e94418 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -84,6 +84,19 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, ret = wait_for_completion_interruptible(&mvdev->saving_migf->save_comp); if (ret) return ret; + if (mvdev->saving_migf->state == + MLX5_MIGF_STATE_PRE_COPY_ERROR) { + /* + * In case we had a PRE_COPY error, only query full + * image for final image + */ + if (!(query_flags & MLX5VF_QUERY_FINAL)) { + *state_size = 0; + complete(&mvdev->saving_migf->save_comp); + return 0; + } + query_flags &= ~MLX5VF_QUERY_INC; + } } MLX5_SET(query_vhca_migration_state_in, in, opcode, @@ -442,7 +455,10 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work) mlx5vf_put_data_buffer(async_data->buf); if (async_data->header_buf) mlx5vf_put_data_buffer(async_data->header_buf); - migf->state = MLX5_MIGF_STATE_ERROR; + if (async_data->status == MLX5_CMD_STAT_BAD_RES_STATE_ERR) + migf->state = MLX5_MIGF_STATE_PRE_COPY_ERROR; + else + migf->state = MLX5_MIGF_STATE_ERROR; wake_up_interruptible(&migf->poll_wait); } mutex_unlock(&migf->lock); @@ -511,6 +527,8 @@ err: * The error and the cleanup flows can't run from an * interrupt context */ + if (status == -EREMOTEIO) + status = MLX5_GET(save_vhca_state_out, async_data->out, status); async_data->status = status; queue_work(migf->mvdev->cb_wq, &async_data->work); } @@ -534,6 +552,13 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, if (err) return err; + if (migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR) + /* + * In case we had a PRE_COPY error, SAVE is triggered only for + * the final image, read device full image. + */ + inc = false; + MLX5_SET(save_vhca_state_in, in, opcode, MLX5_CMD_OP_SAVE_VHCA_STATE); MLX5_SET(save_vhca_state_in, in, op_mod, 0); diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 7729eac8c78c1..5483171d57ad3 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -17,6 +17,7 @@ enum mlx5_vf_migf_state { MLX5_MIGF_STATE_ERROR = 1, + MLX5_MIGF_STATE_PRE_COPY_ERROR, MLX5_MIGF_STATE_PRE_COPY, MLX5_MIGF_STATE_SAVE_LAST, MLX5_MIGF_STATE_COMPLETE, @@ -157,6 +158,7 @@ struct mlx5vf_pci_core_device { enum { MLX5VF_QUERY_INC = (1UL << 0), + MLX5VF_QUERY_FINAL = (1UL << 1), }; int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 5a669b73994a7..cd90eb86128c3 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -219,6 +219,7 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (wait_event_interruptible(migf->poll_wait, !list_empty(&migf->buf_list) || migf->state == MLX5_MIGF_STATE_ERROR || + migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR || migf->state == MLX5_MIGF_STATE_PRE_COPY || migf->state == MLX5_MIGF_STATE_COMPLETE)) return -ERESTARTSYS; @@ -238,7 +239,8 @@ static ssize_t mlx5vf_save_read(struct file *filp, char __user *buf, size_t len, if (first_loop_call) { first_loop_call = false; /* Temporary end of file as part of PRE_COPY */ - if (end_of_data && migf->state == MLX5_MIGF_STATE_PRE_COPY) { + if (end_of_data && (migf->state == MLX5_MIGF_STATE_PRE_COPY || + migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR)) { done = -ENOMSG; goto out_unlock; } @@ -431,7 +433,7 @@ static int mlx5vf_pci_save_device_inc_data(struct mlx5vf_pci_core_device *mvdev) return -ENODEV; ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &length, - MLX5VF_QUERY_INC); + MLX5VF_QUERY_INC | MLX5VF_QUERY_FINAL); if (ret) goto err; -- GitLab From ccc2a52e464d1c983efede1a6d44728c151cb2ed Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 6 Dec 2022 10:34:38 +0200 Subject: [PATCH 1339/1480] vfio/mlx5: Enable MIGRATION_PRE_COPY flag Now that everything has been set up for MIGRATION_PRE_COPY, enable it. Signed-off-by: Shay Drory Reviewed-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20221206083438.37807-15-yishaih@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/cmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 01ef695e94418..64e68d13cb98f 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -222,6 +222,11 @@ void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev, if (MLX5_CAP_GEN(mvdev->mdev, adv_virtualization)) mvdev->core_device.vdev.log_ops = log_ops; + if (MLX5_CAP_GEN_2(mvdev->mdev, migration_multi_load) && + MLX5_CAP_GEN_2(mvdev->mdev, migration_tracking_state)) + mvdev->core_device.vdev.migration_flags |= + VFIO_MIGRATION_PRE_COPY; + end: mlx5_vf_put_core_dev(mvdev->mdev); } -- GitLab From 64ffbbb1e948876dd9044c32a3ab8a790662b9bb Mon Sep 17 00:00:00 2001 From: Shameer Kolothum Date: Wed, 23 Nov 2022 11:32:33 +0000 Subject: [PATCH 1340/1480] hisi_acc_vfio_pci: Add support for precopy IOCTL PRECOPY IOCTL in the case of HiSiIicon ACC driver can be used to perform the device compatibility check earlier during migration. Signed-off-by: Shameer Kolothum Link: https://lore.kernel.org/r/20221123113236.896-2-shameerali.kolothum.thodi@huawei.com Signed-off-by: Alex Williamson --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 52 +++++++++++++++++++ .../vfio/pci/hisilicon/hisi_acc_vfio_pci.h | 1 + 2 files changed, 53 insertions(+) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 0c0c0c7f05215..f3b74a06edb68 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -764,9 +764,58 @@ hisi_acc_vf_pci_resume(struct hisi_acc_vf_core_device *hisi_acc_vdev) stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); + migf->hisi_acc_vdev = hisi_acc_vdev; return migf; } +static long hisi_acc_vf_precopy_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct hisi_acc_vf_migration_file *migf = filp->private_data; + struct hisi_acc_vf_core_device *hisi_acc_vdev = migf->hisi_acc_vdev; + loff_t *pos = &filp->f_pos; + struct vfio_precopy_info info; + unsigned long minsz; + int ret; + + if (cmd != VFIO_MIG_GET_PRECOPY_INFO) + return -ENOTTY; + + minsz = offsetofend(struct vfio_precopy_info, dirty_bytes); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + if (info.argsz < minsz) + return -EINVAL; + + mutex_lock(&hisi_acc_vdev->state_mutex); + if (hisi_acc_vdev->mig_state != VFIO_DEVICE_STATE_PRE_COPY) { + mutex_unlock(&hisi_acc_vdev->state_mutex); + return -EINVAL; + } + + mutex_lock(&migf->lock); + + if (migf->disabled) { + ret = -ENODEV; + goto out; + } + + if (*pos > migf->total_length) { + ret = -EINVAL; + goto out; + } + + info.dirty_bytes = 0; + info.initial_bytes = migf->total_length - *pos; + + ret = copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; +out: + mutex_unlock(&migf->lock); + mutex_unlock(&hisi_acc_vdev->state_mutex); + return ret; +} + static ssize_t hisi_acc_vf_save_read(struct file *filp, char __user *buf, size_t len, loff_t *pos) { @@ -807,6 +856,8 @@ out_unlock: static const struct file_operations hisi_acc_vf_save_fops = { .owner = THIS_MODULE, .read = hisi_acc_vf_save_read, + .unlocked_ioctl = hisi_acc_vf_precopy_ioctl, + .compat_ioctl = compat_ptr_ioctl, .release = hisi_acc_vf_release_file, .llseek = no_llseek, }; @@ -832,6 +883,7 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev) stream_open(migf->filp->f_inode, migf->filp); mutex_init(&migf->lock); + migf->hisi_acc_vdev = hisi_acc_vdev; ret = vf_qm_state_save(hisi_acc_vdev, migf); if (ret) { diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h index 67343325b3201..11d51345f5b51 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h @@ -91,6 +91,7 @@ struct hisi_acc_vf_migration_file { struct mutex lock; bool disabled; + struct hisi_acc_vf_core_device *hisi_acc_vdev; struct acc_vf_data vf_data; size_t total_length; }; -- GitLab From d9a871e4a143047d1d84a606772af319f11516f9 Mon Sep 17 00:00:00 2001 From: Shameer Kolothum Date: Wed, 23 Nov 2022 11:32:34 +0000 Subject: [PATCH 1341/1480] hisi_acc_vfio_pci: Introduce support for PRE_COPY state transitions The saving_migf is open in PRE_COPY state if it is supported and reads initial device match data. hisi_acc_vf_stop_copy() is refactored to make use of common code. Signed-off-by: Shameer Kolothum Link: https://lore.kernel.org/r/20221123113236.896-3-shameerali.kolothum.thodi@huawei.com Signed-off-by: Alex Williamson --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 74 ++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index f3b74a06edb68..c8658636a84c0 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -863,7 +863,7 @@ static const struct file_operations hisi_acc_vf_save_fops = { }; static struct hisi_acc_vf_migration_file * -hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev) +hisi_acc_open_saving_migf(struct hisi_acc_vf_core_device *hisi_acc_vdev) { struct hisi_acc_vf_migration_file *migf; int ret; @@ -885,7 +885,7 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev) mutex_init(&migf->lock); migf->hisi_acc_vdev = hisi_acc_vdev; - ret = vf_qm_state_save(hisi_acc_vdev, migf); + ret = vf_qm_get_match_data(hisi_acc_vdev, &migf->vf_data); if (ret) { fput(migf->filp); return ERR_PTR(ret); @@ -894,6 +894,44 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev) return migf; } +static struct hisi_acc_vf_migration_file * +hisi_acc_vf_pre_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev) +{ + struct hisi_acc_vf_migration_file *migf; + + migf = hisi_acc_open_saving_migf(hisi_acc_vdev); + if (IS_ERR(migf)) + return migf; + + migf->total_length = QM_MATCH_SIZE; + return migf; +} + +static struct hisi_acc_vf_migration_file * +hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev, bool open) +{ + int ret; + struct hisi_acc_vf_migration_file *migf = NULL; + + if (open) { + /* + * Userspace didn't use PRECOPY support. Hence saving_migf + * is not opened yet. + */ + migf = hisi_acc_open_saving_migf(hisi_acc_vdev); + if (IS_ERR(migf)) + return migf; + } else { + migf = hisi_acc_vdev->saving_migf; + } + + ret = vf_qm_state_save(hisi_acc_vdev, migf); + if (ret) + return ERR_PTR(ret); + + return open ? migf : NULL; +} + static int hisi_acc_vf_stop_device(struct hisi_acc_vf_core_device *hisi_acc_vdev) { struct device *dev = &hisi_acc_vdev->vf_dev->dev; @@ -921,6 +959,31 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev, u32 cur = hisi_acc_vdev->mig_state; int ret; + if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_PRE_COPY) { + struct hisi_acc_vf_migration_file *migf; + + migf = hisi_acc_vf_pre_copy(hisi_acc_vdev); + if (IS_ERR(migf)) + return ERR_CAST(migf); + get_file(migf->filp); + hisi_acc_vdev->saving_migf = migf; + return migf->filp; + } + + if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_STOP_COPY) { + struct hisi_acc_vf_migration_file *migf; + + ret = hisi_acc_vf_stop_device(hisi_acc_vdev); + if (ret) + return ERR_PTR(ret); + + migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, false); + if (IS_ERR(migf)) + return ERR_CAST(migf); + + return NULL; + } + if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_STOP) { ret = hisi_acc_vf_stop_device(hisi_acc_vdev); if (ret) @@ -931,7 +994,7 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev, if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_STOP_COPY) { struct hisi_acc_vf_migration_file *migf; - migf = hisi_acc_vf_stop_copy(hisi_acc_vdev); + migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, true); if (IS_ERR(migf)) return ERR_CAST(migf); get_file(migf->filp); @@ -963,6 +1026,11 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev, return NULL; } + if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) { + hisi_acc_vf_disable_fds(hisi_acc_vdev); + return NULL; + } + if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_RUNNING) { hisi_acc_vf_start_device(hisi_acc_vdev); return NULL; -- GitLab From 190125adcad4c5850fd74ecd697e20a446b74ed8 Mon Sep 17 00:00:00 2001 From: Shameer Kolothum Date: Wed, 23 Nov 2022 11:32:35 +0000 Subject: [PATCH 1342/1480] hisi_acc_vfio_pci: Move the dev compatibility tests for early check Instead of waiting till data transfer is complete to perform dev compatibility, do it as soon as we have enough data to perform the check. This will be useful when we enable the support for PRE_COPY. Signed-off-by: Shameer Kolothum Link: https://lore.kernel.org/r/20221123113236.896-4-shameerali.kolothum.thodi@huawei.com Signed-off-by: Alex Williamson --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 19 +++++++------------ .../vfio/pci/hisilicon/hisi_acc_vfio_pci.h | 1 + 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index c8658636a84c0..9a51f41e1d2aa 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -360,8 +360,8 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev, u32 que_iso_state; int ret; - if (migf->total_length < QM_MATCH_SIZE) - return -EINVAL; + if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done) + return 0; if (vf_data->acc_magic != ACC_DEV_MAGIC) { dev_err(dev, "failed to match ACC_DEV_MAGIC\n"); @@ -406,6 +406,7 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev, } hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state; + hisi_acc_vdev->match_done = true; return 0; } @@ -493,10 +494,6 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev, struct device *dev = &vf_qm->pdev->dev; int ret; - ret = vf_qm_get_match_data(hisi_acc_vdev, vf_data); - if (ret) - return ret; - if (unlikely(qm_wait_dev_not_ready(vf_qm))) { /* Update state and return with match data */ vf_data->vf_qm_state = QM_NOT_READY; @@ -673,12 +670,6 @@ static int hisi_acc_vf_load_state(struct hisi_acc_vf_core_device *hisi_acc_vdev) struct hisi_acc_vf_migration_file *migf = hisi_acc_vdev->resuming_migf; int ret; - /* Check dev compatibility */ - ret = vf_qm_check_match(hisi_acc_vdev, migf); - if (ret) { - dev_err(dev, "failed to match the VF!\n"); - return ret; - } /* Recover data to VF */ ret = vf_qm_load_data(hisi_acc_vdev, migf); if (ret) { @@ -732,6 +723,10 @@ static ssize_t hisi_acc_vf_resume_write(struct file *filp, const char __user *bu *pos += len; done = len; migf->total_length += len; + + ret = vf_qm_check_match(migf->hisi_acc_vdev, migf); + if (ret) + done = -EFAULT; out_unlock: mutex_unlock(&migf->lock); return done; diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h index 11d51345f5b51..dcabfeec6ca19 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h @@ -98,6 +98,7 @@ struct hisi_acc_vf_migration_file { struct hisi_acc_vf_core_device { struct vfio_pci_core_device core_device; + u8 match_done:1; u8 deferred_reset:1; /* For migration state */ struct mutex state_mutex; -- GitLab From f2240b4441cc5bd87820371ee79ad7c9125e76b6 Mon Sep 17 00:00:00 2001 From: Shameer Kolothum Date: Wed, 23 Nov 2022 11:32:36 +0000 Subject: [PATCH 1343/1480] hisi_acc_vfio_pci: Enable PRE_COPY flag Now that we have everything to support the PRE_COPY state, enable it. Signed-off-by: Shameer Kolothum Link: https://lore.kernel.org/r/20221123113236.896-5-shameerali.kolothum.thodi@huawei.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 9a51f41e1d2aa..51941bb4f31f0 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -1351,7 +1351,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev) hisi_acc_vdev->vf_dev = pdev; mutex_init(&hisi_acc_vdev->state_mutex); - core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY; + core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY; core_vdev->mig_ops = &hisi_acc_vfio_pci_migrn_state_ops; return vfio_pci_core_init_dev(core_vdev); -- GitLab From f18caf261398a7f2de4fa3f600deb87072fe7b8d Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 7 Dec 2022 15:22:18 +0400 Subject: [PATCH 1344/1480] device property: Fix documentation for fwnode_get_next_parent() Use fwnode_handle_put() on the node pointer to release the refcount. Change fwnode_handle_node() to fwnode_handle_put(). Fixes: 233872585de1 ("device property: Add fwnode_get_next_parent()") Reviewed-by: Andy Shevchenko Reviewed-by: Daniel Scally Acked-by: Sakari Ailus Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20221207112219.2652411-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index ed74083c179d8..bbb3e499ff4a5 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -609,7 +609,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_parent); * node's parents. * * Returns a node pointer with refcount incremented, use - * fwnode_handle_node() on it when done. + * fwnode_handle_put() on it when done. */ struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode) { -- GitLab From 3256412fc57b6cabbc1cf1317d020e42f6d7aeab Mon Sep 17 00:00:00 2001 From: Weilong Chen Date: Tue, 8 Nov 2022 09:58:11 +0800 Subject: [PATCH 1345/1480] i2c: hisi: Add support to get clock frequency from clock The clk_rate attribute is not generic device tree bindings for I2C busses described in Documentation/devicetree/bindings/i2c/i2c.txt. It can be managed by clock binding. Support the driver to obtain clock information by clk_rate or clock property. Find clock first, if not, fall back to clk_rate. Signed-off-by: Weilong Chen Acked-by: Yicong Yang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-hisi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c index bcc97e4fcb654..8c6c7075c765c 100644 --- a/drivers/i2c/busses/i2c-hisi.c +++ b/drivers/i2c/busses/i2c-hisi.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -88,6 +89,7 @@ struct hisi_i2c_controller { struct i2c_adapter adapter; void __iomem *iobase; struct device *dev; + struct clk *clk; int irq; /* Intermediates for recording the transfer process */ @@ -454,10 +456,15 @@ static int hisi_i2c_probe(struct platform_device *pdev) return ret; } - ret = device_property_read_u64(dev, "clk_rate", &clk_rate_hz); - if (ret) { - dev_err(dev, "failed to get clock frequency, ret = %d\n", ret); - return ret; + ctlr->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); + if (IS_ERR_OR_NULL(ctlr->clk)) { + ret = device_property_read_u64(dev, "clk_rate", &clk_rate_hz); + if (ret) { + dev_err(dev, "failed to get clock frequency, ret = %d\n", ret); + return ret; + } + } else { + clk_rate_hz = clk_get_rate(ctlr->clk); } ctlr->clk_rate_khz = DIV_ROUND_UP_ULL(clk_rate_hz, HZ_PER_KHZ); -- GitLab From 810199f7315604bd969409109f1c96b4ebe772ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 19 Oct 2022 22:28:08 +0200 Subject: [PATCH 1346/1480] i2c: xiic: Make sure to disable clock on .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If for whatever reasons pm_runtime_resume_and_get() failed, .remove() is exited early, the clock isn't freed and runtime PM state isn't reset. The right thing to do however is to free all resources that don't need HW access after a problem with runtime PM. Also issue a warning in that case and return 0 to suppress a less helpful warning by the driver core. Signed-off-by: Uwe Kleine-König Acked-by: Michal Simek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 277a02455cddd..bee5a2ef1f229 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -858,11 +858,14 @@ static int xiic_i2c_remove(struct platform_device *pdev) /* remove adapter & data */ i2c_del_adapter(&i2c->adap); - ret = pm_runtime_resume_and_get(i2c->dev); + ret = pm_runtime_get_sync(i2c->dev); + if (ret < 0) - return ret; + dev_warn(&pdev->dev, "Failed to activate device for removal (%pe)\n", + ERR_PTR(ret)); + else + xiic_deinit(i2c); - xiic_deinit(i2c); pm_runtime_put_sync(i2c->dev); clk_disable_unprepare(i2c->clk); pm_runtime_disable(&pdev->dev); -- GitLab From 2d47b79d2bd39cc6369eccf94a06568d84c906ae Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 29 Oct 2022 17:38:25 +0800 Subject: [PATCH 1347/1480] i2c: mux: reg: check return value after calling platform_get_resource() It will cause null-ptr-deref in resource_size(), if platform_get_resource() returns NULL, move calling resource_size() after devm_ioremap_resource() that will check 'res' to avoid null-ptr-deref. And use devm_platform_get_and_ioremap_resource() to simplify code. Fixes: b3fdd32799d8 ("i2c: mux: Add register-based mux i2c-mux-reg") Signed-off-by: Yang Yingliang Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-mux-reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c index 0e0679f65cf77..30a6de1694e07 100644 --- a/drivers/i2c/muxes/i2c-mux-reg.c +++ b/drivers/i2c/muxes/i2c-mux-reg.c @@ -183,13 +183,12 @@ static int i2c_mux_reg_probe(struct platform_device *pdev) if (!mux->data.reg) { dev_info(&pdev->dev, "Register not set, using platform resource\n"); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mux->data.reg_size = resource_size(res); - mux->data.reg = devm_ioremap_resource(&pdev->dev, res); + mux->data.reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(mux->data.reg)) { ret = PTR_ERR(mux->data.reg); goto err_put_parent; } + mux->data.reg_size = resource_size(res); } if (mux->data.reg_size != 4 && mux->data.reg_size != 2 && -- GitLab From 39244cc754829bf707dccd12e2ce37510f5b1f8d Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Fri, 29 Jul 2022 19:02:16 +0800 Subject: [PATCH 1348/1480] i2c: ismt: Fix an out-of-bounds bug in ismt_access() When the driver does not check the data from the user, the variable 'data->block[0]' may be very large to cause an out-of-bounds bug. The following log can reveal it: [ 33.995542] i2c i2c-1: ioctl, cmd=0x720, arg=0x7ffcb3dc3a20 [ 33.995978] ismt_smbus 0000:00:05.0: I2C_SMBUS_BLOCK_DATA: WRITE [ 33.996475] ================================================================== [ 33.996995] BUG: KASAN: out-of-bounds in ismt_access.cold+0x374/0x214b [ 33.997473] Read of size 18446744073709551615 at addr ffff88810efcfdb1 by task ismt_poc/485 [ 33.999450] Call Trace: [ 34.001849] memcpy+0x20/0x60 [ 34.002077] ismt_access.cold+0x374/0x214b [ 34.003382] __i2c_smbus_xfer+0x44f/0xfb0 [ 34.004007] i2c_smbus_xfer+0x10a/0x390 [ 34.004291] i2cdev_ioctl_smbus+0x2c8/0x710 [ 34.005196] i2cdev_ioctl+0x5ec/0x74c Fix this bug by checking the size of 'data->block[0]' first. Fixes: 13f35ac14cd0 ("i2c: Adding support for Intel iSMT SMBus 2.0 host controller") Signed-off-by: Zheyu Ma Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-ismt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index fe2349590f75e..c74985d77b0ec 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -509,6 +509,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, if (read_write == I2C_SMBUS_WRITE) { /* Block Write */ dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: WRITE\n"); + if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + dma_size = data->block[0] + 1; dma_direction = DMA_TO_DEVICE; desc->wr_len_cmd = dma_size; -- GitLab From 74d58cd48a8f5848dfda8bc09d11c90f3ea42b0e Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 8 Dec 2022 10:07:46 +0100 Subject: [PATCH 1349/1480] USB: sisusbvga: remove console support It was marked as BROKEN since commit 862ee699fefe (USB: sisusbvga: Make console support depend on BROKEN) 2 years ago. Since noone stepped up to fix it, remove it completely. Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Yoshinori Sato Cc: Rich Felker Cc: Thomas Winischhofer Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-usb@vger.kernel.org Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221208090749.28056-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/configs/ppc6xx_defconfig | 1 - arch/sh/configs/landisk_defconfig | 1 - drivers/usb/misc/sisusbvga/Kconfig | 34 - drivers/usb/misc/sisusbvga/Makefile | 1 - drivers/usb/misc/sisusbvga/sisusb.c | 276 +--- drivers/usb/misc/sisusbvga/sisusb.h | 21 - drivers/usb/misc/sisusbvga/sisusb_con.c | 1496 ---------------------- drivers/usb/misc/sisusbvga/sisusb_init.c | 955 -------------- drivers/usb/misc/sisusbvga/sisusb_init.h | 180 --- 9 files changed, 6 insertions(+), 2959 deletions(-) delete mode 100644 drivers/usb/misc/sisusbvga/sisusb_con.c delete mode 100644 drivers/usb/misc/sisusbvga/sisusb_init.c delete mode 100644 drivers/usb/misc/sisusbvga/sisusb_init.h diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index d23deb94b36e7..f73c98be56c8f 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -912,7 +912,6 @@ CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m CONFIG_USB_SISUSBVGA=m -CONFIG_USB_SISUSBVGA_CON=y CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_IOWARRIOR=m diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 492a0a2e0e367..7037320b654ad 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -92,7 +92,6 @@ CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_SISUSBVGA=m -CONFIG_USB_SISUSBVGA_CON=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set diff --git a/drivers/usb/misc/sisusbvga/Kconfig b/drivers/usb/misc/sisusbvga/Kconfig index c12cdd0154102..42f81c8eaa92c 100644 --- a/drivers/usb/misc/sisusbvga/Kconfig +++ b/drivers/usb/misc/sisusbvga/Kconfig @@ -3,7 +3,6 @@ config USB_SISUSBVGA tristate "USB 2.0 SVGA dongle support (Net2280/SiS315)" depends on (USB_MUSB_HDRC || USB_EHCI_HCD) - select FONT_SUPPORT if USB_SISUSBVGA_CON help Say Y here if you intend to attach a USB2VGA dongle based on a Net2280 and a SiS315 chip. @@ -13,36 +12,3 @@ config USB_SISUSBVGA To compile this driver as a module, choose M here; the module will be called sisusbvga. If unsure, say N. - -config USB_SISUSBVGA_CON - bool "Text console and mode switching support" if USB_SISUSBVGA - depends on VT && BROKEN - select FONT_8x16 - help - Say Y here if you want a VGA text console via the USB dongle or - want to support userland applications that utilize the driver's - display mode switching capabilities. - - Note that this console supports VGA/EGA text mode only. - - By default, the console part of the driver will not kick in when - the driver is initialized. If you want the driver to take over - one or more of the consoles, you need to specify the number of - the first and last consoles (starting at 1) as driver parameters. - - For example, if the driver is compiled as a module: - - modprobe sisusbvga first=1 last=5 - - If you use hotplug, add this to your modutils config files with - the "options" keyword, such as eg. - - options sisusbvga first=1 last=5 - - If the driver is compiled into the kernel image, the parameters - must be given in the kernel command like, such as - - sisusbvga.first=1 sisusbvga.last=5 - - - diff --git a/drivers/usb/misc/sisusbvga/Makefile b/drivers/usb/misc/sisusbvga/Makefile index 6551bce68ac5d..93265de80eb9f 100644 --- a/drivers/usb/misc/sisusbvga/Makefile +++ b/drivers/usb/misc/sisusbvga/Makefile @@ -6,4 +6,3 @@ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o sisusbvga-y := sisusb.o -sisusbvga-$(CONFIG_USB_SISUSBVGA_CON) += sisusb_con.o sisusb_init.o diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index f08de33d9ff38..a0d5ba8058f8f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -51,25 +51,11 @@ #include #include "sisusb.h" -#include "sisusb_init.h" - -#ifdef CONFIG_USB_SISUSBVGA_CON -#include -#endif #define SISUSB_DONTSYNC /* Forward declarations / clean-up routines */ -#ifdef CONFIG_USB_SISUSBVGA_CON -static int sisusb_first_vc; -static int sisusb_last_vc; -module_param_named(first, sisusb_first_vc, int, 0); -module_param_named(last, sisusb_last_vc, int, 0); -MODULE_PARM_DESC(first, "Number of first console to take over (1 - MAX_NR_CONSOLES)"); -MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES)"); -#endif - static struct usb_driver sisusb_driver; static void sisusb_free_buffers(struct sisusb_usb_data *sisusb) @@ -1198,19 +1184,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, /* High level: Gfx (indexed) register access */ -#ifdef CONFIG_USB_SISUSBVGA_CON -int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data) -{ - return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); -} - -int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data) -{ - return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); -} -#endif - -int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, +static int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 data) { int ret; @@ -1220,7 +1194,7 @@ int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, return ret; } -int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, +static int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 *data) { int ret; @@ -1230,7 +1204,7 @@ int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, return ret; } -int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, +static int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand, u8 myor) { int ret; @@ -1258,13 +1232,13 @@ static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb, return ret; } -int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, +static int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 myor) { return sisusb_setidxregandor(sisusb, port, index, 0xff, myor); } -int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, +static int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand) { return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00); @@ -1272,38 +1246,6 @@ int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, /* Write/read video ram */ -#ifdef CONFIG_USB_SISUSBVGA_CON -int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data) -{ - return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); -} - -int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) -{ - return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); -} - -int sisusb_copy_memory(struct sisusb_usb_data *sisusb, u8 *src, - u32 dest, int length) -{ - size_t dummy; - - return sisusb_write_mem_bulk(sisusb, dest, src, length, - NULL, 0, &dummy); -} - -#ifdef SISUSBENDIANTEST -static int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest, - u32 src, int length) -{ - size_t dummy; - - return sisusb_read_mem_bulk(sisusb, src, dest, length, - NULL, &dummy); -} -#endif -#endif - #ifdef SISUSBENDIANTEST static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb) { @@ -2252,131 +2194,6 @@ static int sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen) return ret; } - -#ifdef CONFIG_USB_SISUSBVGA_CON - -/* Set up default text mode: - * - Set text mode (0x03) - * - Upload default font - * - Upload user font (if available) - */ - -int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) -{ - int ret = 0, slot = sisusb->font_slot, i; - const struct font_desc *myfont; - u8 *tempbuf; - u16 *tempbufb; - static const char bootstring[] = - "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; - static const char bootlogo[] = "(o_ //\\ V_/_"; - - /* sisusb->lock is down */ - - if (!sisusb->SiS_Pr) - return 1; - - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; - sisusb->SiS_Pr->sisusb = (void *)sisusb; - - /* Set mode 0x03 */ - SiSUSBSetMode(sisusb->SiS_Pr, 0x03); - - myfont = find_font("VGA8x16"); - if (!myfont) - return 1; - - tempbuf = vmalloc(8192); - if (!tempbuf) - return 1; - - for (i = 0; i < 256; i++) - memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16); - - /* Upload default font */ - ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, - 0, 1, NULL, 16, 0); - - vfree(tempbuf); - - /* Upload user font (and reset current slot) */ - if (sisusb->font_backup) { - ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup, - 8192, sisusb->font_backup_512, 1, NULL, - sisusb->font_backup_height, 0); - if (slot != 2) - sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1, - NULL, 16, 0); - } - - if (init && !sisusb->scrbuf) { - - tempbuf = vmalloc(8192); - if (tempbuf) { - - i = 4096; - tempbufb = (u16 *)tempbuf; - while (i--) - *(tempbufb++) = 0x0720; - - i = 0; - tempbufb = (u16 *)tempbuf; - while (bootlogo[i]) { - *(tempbufb++) = 0x0700 | bootlogo[i++]; - if (!(i % 4)) - tempbufb += 76; - } - - i = 0; - tempbufb = (u16 *)tempbuf + 6; - while (bootstring[i]) - *(tempbufb++) = 0x0700 | bootstring[i++]; - - ret |= sisusb_copy_memory(sisusb, tempbuf, - sisusb->vrambase, 8192); - - vfree(tempbuf); - - } - - } else if (sisusb->scrbuf) { - ret |= sisusb_copy_memory(sisusb, (u8 *)sisusb->scrbuf, - sisusb->vrambase, sisusb->scrbuf_size); - } - - if (sisusb->sisusb_cursor_size_from >= 0 && - sisusb->sisusb_cursor_size_to >= 0) { - sisusb_setidxreg(sisusb, SISCR, 0x0a, - sisusb->sisusb_cursor_size_from); - sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, - sisusb->sisusb_cursor_size_to); - } else { - sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d); - sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e); - sisusb->sisusb_cursor_size_to = -1; - } - - slot = sisusb->sisusb_cursor_loc; - if (slot < 0) - slot = 0; - - sisusb->sisusb_cursor_loc = -1; - sisusb->bad_cursor_pos = 1; - - sisusb_set_cursor(sisusb, slot); - - sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8)); - sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff)); - - sisusb->textmodedestroyed = 0; - - /* sisusb->lock is down */ - - return ret; -} - -#endif - /* fops */ static int sisusb_open(struct inode *inode, struct file *file) @@ -2434,7 +2251,7 @@ static int sisusb_open(struct inode *inode, struct file *file) return 0; } -void sisusb_delete(struct kref *kref) +static void sisusb_delete(struct kref *kref) { struct sisusb_usb_data *sisusb = to_sisusb_dev(kref); @@ -2446,9 +2263,6 @@ void sisusb_delete(struct kref *kref) sisusb->sisusb_dev = NULL; sisusb_free_buffers(sisusb); sisusb_free_urbs(sisusb); -#ifdef CONFIG_USB_SISUSBVGA_CON - kfree(sisusb->SiS_Pr); -#endif kfree(sisusb); } @@ -2842,53 +2656,7 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, case SUCMD_HANDLETEXTMODE: retval = 0; -#ifdef CONFIG_USB_SISUSBVGA_CON - /* Gfx core must be initialized, SiS_Pr must exist */ - if (!sisusb->gfxinit || !sisusb->SiS_Pr) - return -ENODEV; - - switch (y->data0) { - case 0: - retval = sisusb_reset_text_mode(sisusb, 0); - break; - case 1: - sisusb->textmodedestroyed = 1; - break; - } -#endif - break; - -#ifdef CONFIG_USB_SISUSBVGA_CON - case SUCMD_SETMODE: - /* Gfx core must be initialized, SiS_Pr must exist */ - if (!sisusb->gfxinit || !sisusb->SiS_Pr) - return -ENODEV; - - retval = 0; - - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; - sisusb->SiS_Pr->sisusb = (void *)sisusb; - - if (SiSUSBSetMode(sisusb->SiS_Pr, y->data3)) - retval = -EINVAL; - - break; - - case SUCMD_SETVESAMODE: - /* Gfx core must be initialized, SiS_Pr must exist */ - if (!sisusb->gfxinit || !sisusb->SiS_Pr) - return -ENODEV; - - retval = 0; - - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; - sisusb->SiS_Pr->sisusb = (void *)sisusb; - - if (SiSUSBSetVESAMode(sisusb->SiS_Pr, y->data3)) - retval = -EINVAL; - break; -#endif default: retval = -EINVAL; @@ -2942,11 +2710,7 @@ static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) x.sisusb_vramsize = sisusb->vramsize; x.sisusb_minor = sisusb->minor; x.sisusb_fbdevactive = 0; -#ifdef CONFIG_USB_SISUSBVGA_CON - x.sisusb_conactive = sisusb->haveconsole ? 1 : 0; -#else x.sisusb_conactive = 0; -#endif memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); if (copy_to_user((void __user *)arg, &x, sizeof(x))) @@ -3090,15 +2854,6 @@ static int sisusb_probe(struct usb_interface *intf, dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs); -#ifdef CONFIG_USB_SISUSBVGA_CON - /* Allocate our SiS_Pr */ - sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL); - if (!sisusb->SiS_Pr) { - retval = -ENOMEM; - goto error_4; - } -#endif - /* Do remaining init stuff */ init_waitqueue_head(&sisusb->wait_q); @@ -3111,12 +2866,6 @@ static int sisusb_probe(struct usb_interface *intf, if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) { int initscreen = 1; -#ifdef CONFIG_USB_SISUSBVGA_CON - if (sisusb_first_vc > 0 && sisusb_last_vc > 0 && - sisusb_first_vc <= sisusb_last_vc && - sisusb_last_vc <= MAX_NR_CONSOLES) - initscreen = 0; -#endif if (sisusb_init_gfxdevice(sisusb, initscreen)) dev_err(&sisusb->sisusb_dev->dev, "Failed to early initialize device\n"); @@ -3133,10 +2882,6 @@ static int sisusb_probe(struct usb_interface *intf, dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); #endif -#ifdef CONFIG_USB_SISUSBVGA_CON - sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc); -#endif - return 0; error_4: @@ -3159,10 +2904,6 @@ static void sisusb_disconnect(struct usb_interface *intf) if (!sisusb) return; -#ifdef CONFIG_USB_SISUSBVGA_CON - sisusb_console_exit(sisusb); -#endif - usb_deregister_dev(intf, &usb_sisusb_class); mutex_lock(&sisusb->lock); @@ -3208,11 +2949,6 @@ static struct usb_driver sisusb_driver = { static int __init usb_sisusb_init(void) { - -#ifdef CONFIG_USB_SISUSBVGA_CON - sisusb_init_concode(); -#endif - return usb_register(&sisusb_driver); } diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index c0fb9e1c5361b..e5b1228655d08 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h @@ -48,7 +48,6 @@ /* Include console and mode switching code? */ -#include #include #include "sisusb_struct.h" @@ -126,26 +125,6 @@ struct sisusb_usb_data { unsigned char gfxinit; /* graphics core initialized? */ unsigned short chipid, chipvendor; unsigned short chiprevision; -#ifdef CONFIG_USB_SISUSBVGA_CON - struct SiS_Private *SiS_Pr; - unsigned long scrbuf; - unsigned int scrbuf_size; - int haveconsole, con_first, con_last; - int havethisconsole[MAX_NR_CONSOLES]; - int textmodedestroyed; - unsigned int sisusb_num_columns; /* real number, not vt's idea */ - int cur_start_addr, con_rolled_over; - int sisusb_cursor_loc, bad_cursor_pos; - int sisusb_cursor_size_from; - int sisusb_cursor_size_to; - int current_font_height, current_font_512; - int font_backup_size, font_backup_height, font_backup_512; - char *font_backup; - int font_slot; - struct vc_data *sisusb_display_fg; - int is_gfx; - int con_blanked; -#endif }; #define to_sisusb_dev(d) container_of(d, struct sisusb_usb_data, kref) diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c deleted file mode 100644 index fcb95fb639e00..0000000000000 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ /dev/null @@ -1,1496 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) -/* - * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles - * - * VGA text mode console part - * - * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria - * - * If distributed as part of the Linux kernel, this code is licensed under the - * terms of the GPL v2. - * - * Otherwise, the following license terms apply: - * - * * Redistribution and use in source and binary forms, with or without - * * modification, are permitted provided that the following conditions - * * are met: - * * 1) Redistributions of source code must retain the above copyright - * * notice, this list of conditions and the following disclaimer. - * * 2) Redistributions in binary form must reproduce the above copyright - * * notice, this list of conditions and the following disclaimer in the - * * documentation and/or other materials provided with the distribution. - * * 3) The name of the author may not be used to endorse or promote products - * * derived from this software without specific psisusbr written permission. - * * - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Thomas Winischhofer - * - * Portions based on vgacon.c which are - * Created 28 Sep 1997 by Geert Uytterhoeven - * Rewritten by Martin Mares , July 1998 - * based on code Copyright (C) 1991, 1992 Linus Torvalds - * 1995 Jay Estabrook - * - * A note on using in_atomic() in here: We can't handle console - * calls from non-schedulable context due to our USB-dependend - * nature. For now, this driver just ignores any calls if it - * detects this state. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sisusb.h" -#include "sisusb_init.h" - -/* vc_data -> sisusb conversion table */ -static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES]; - -/* Forward declaration */ -static const struct consw sisusb_con; - -static inline void -sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) -{ - memset16(s, c, count / 2); -} - -static inline void -sisusb_initialize(struct sisusb_usb_data *sisusb) -{ - /* Reset cursor and start address */ - if (sisusb_setidxreg(sisusb, SISCR, 0x0c, 0x00)) - return; - if (sisusb_setidxreg(sisusb, SISCR, 0x0d, 0x00)) - return; - if (sisusb_setidxreg(sisusb, SISCR, 0x0e, 0x00)) - return; - sisusb_setidxreg(sisusb, SISCR, 0x0f, 0x00); -} - -static inline void -sisusbcon_set_start_address(struct sisusb_usb_data *sisusb, struct vc_data *c) -{ - sisusb->cur_start_addr = (c->vc_visible_origin - sisusb->scrbuf) / 2; - - sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8)); - sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff)); -} - -void -sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location) -{ - if (sisusb->sisusb_cursor_loc == location) - return; - - sisusb->sisusb_cursor_loc = location; - - /* Hardware bug: Text cursor appears twice or not at all - * at some positions. Work around it with the cursor skew - * bits. - */ - - if ((location & 0x0007) == 0x0007) { - sisusb->bad_cursor_pos = 1; - location--; - if (sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0x1f, 0x20)) - return; - } else if (sisusb->bad_cursor_pos) { - if (sisusb_setidxregand(sisusb, SISCR, 0x0b, 0x1f)) - return; - sisusb->bad_cursor_pos = 0; - } - - if (sisusb_setidxreg(sisusb, SISCR, 0x0e, (location >> 8))) - return; - sisusb_setidxreg(sisusb, SISCR, 0x0f, (location & 0xff)); -} - -static inline struct sisusb_usb_data * -sisusb_get_sisusb(unsigned short console) -{ - return mysisusbs[console]; -} - -static inline int -sisusb_sisusb_valid(struct sisusb_usb_data *sisusb) -{ - if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) - return 0; - - return 1; -} - -static struct sisusb_usb_data * -sisusb_get_sisusb_lock_and_check(unsigned short console) -{ - struct sisusb_usb_data *sisusb; - - /* We can't handle console calls in non-schedulable - * context due to our locks and the USB transport. - * So we simply ignore them. This should only affect - * some calls to printk. - */ - if (in_atomic()) - return NULL; - - sisusb = sisusb_get_sisusb(console); - if (!sisusb) - return NULL; - - mutex_lock(&sisusb->lock); - - if (!sisusb_sisusb_valid(sisusb) || - !sisusb->havethisconsole[console]) { - mutex_unlock(&sisusb->lock); - return NULL; - } - - return sisusb; -} - -static int -sisusb_is_inactive(struct vc_data *c, struct sisusb_usb_data *sisusb) -{ - if (sisusb->is_gfx || - sisusb->textmodedestroyed || - c->vc_mode != KD_TEXT) - return 1; - - return 0; -} - -/* con_startup console interface routine */ -static const char * -sisusbcon_startup(void) -{ - return "SISUSBCON"; -} - -/* con_init console interface routine */ -static void -sisusbcon_init(struct vc_data *c, int init) -{ - struct sisusb_usb_data *sisusb; - int cols, rows; - - /* This is called by do_take_over_console(), - * ie by us/under our control. It is - * only called after text mode and fonts - * are set up/restored. - */ - - sisusb = sisusb_get_sisusb(c->vc_num); - if (!sisusb) - return; - - mutex_lock(&sisusb->lock); - - if (!sisusb_sisusb_valid(sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - c->vc_can_do_color = 1; - - c->vc_complement_mask = 0x7700; - - c->vc_hi_font_mask = sisusb->current_font_512 ? 0x0800 : 0; - - sisusb->haveconsole = 1; - - sisusb->havethisconsole[c->vc_num] = 1; - - /* We only support 640x400 */ - c->vc_scan_lines = 400; - - c->vc_font.height = sisusb->current_font_height; - - /* We only support width = 8 */ - cols = 80; - rows = c->vc_scan_lines / c->vc_font.height; - - /* Increment usage count for our sisusb. - * Doing so saves us from upping/downing - * the disconnect semaphore; we can't - * lose our sisusb until this is undone - * in con_deinit. For all other console - * interface functions, it suffices to - * use sisusb->lock and do a quick check - * of sisusb for device disconnection. - */ - kref_get(&sisusb->kref); - - if (!*c->uni_pagedict_loc) - con_set_default_unimap(c); - - mutex_unlock(&sisusb->lock); - - if (init) { - c->vc_cols = cols; - c->vc_rows = rows; - } else - vc_resize(c, cols, rows); -} - -/* con_deinit console interface routine */ -static void -sisusbcon_deinit(struct vc_data *c) -{ - struct sisusb_usb_data *sisusb; - int i; - - /* This is called by do_take_over_console() - * and others, ie not under our control. - */ - - sisusb = sisusb_get_sisusb(c->vc_num); - if (!sisusb) - return; - - mutex_lock(&sisusb->lock); - - /* Clear ourselves in mysisusbs */ - mysisusbs[c->vc_num] = NULL; - - sisusb->havethisconsole[c->vc_num] = 0; - - /* Free our font buffer if all consoles are gone */ - if (sisusb->font_backup) { - for(i = 0; i < MAX_NR_CONSOLES; i++) { - if (sisusb->havethisconsole[c->vc_num]) - break; - } - if (i == MAX_NR_CONSOLES) { - vfree(sisusb->font_backup); - sisusb->font_backup = NULL; - } - } - - mutex_unlock(&sisusb->lock); - - /* decrement the usage count on our sisusb */ - kref_put(&sisusb->kref, sisusb_delete); -} - -/* interface routine */ -static u8 -sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity, - bool blink, bool underline, bool reverse, - bool unused) -{ - u8 attr = color; - - if (underline) - attr = (attr & 0xf0) | c->vc_ulcolor; - else if (intensity == VCI_HALF_BRIGHT) - attr = (attr & 0xf0) | c->vc_halfcolor; - - if (reverse) - attr = ((attr) & 0x88) | - ((((attr) >> 4) | - ((attr) << 4)) & 0x77); - - if (blink) - attr ^= 0x80; - - if (intensity == VCI_BOLD) - attr ^= 0x08; - - return attr; -} - -/* Interface routine */ -static void -sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count) -{ - /* Invert a region. This is called with a pointer - * to the console's internal screen buffer. So we - * simply do the inversion there and rely on - * a call to putc(s) to update the real screen. - */ - - while (count--) { - u16 a = *p; - - *p++ = ((a) & 0x88ff) | - (((a) & 0x7000) >> 4) | - (((a) & 0x0700) << 4); - } -} - -static inline void *sisusb_vaddr(const struct sisusb_usb_data *sisusb, - const struct vc_data *c, unsigned int x, unsigned int y) -{ - return (u16 *)c->vc_origin + y * sisusb->sisusb_num_columns + x; -} - -static inline unsigned long sisusb_haddr(const struct sisusb_usb_data *sisusb, - const struct vc_data *c, unsigned int x, unsigned int y) -{ - unsigned long offset = c->vc_origin - sisusb->scrbuf; - - /* 2 bytes per each character */ - offset += 2 * (y * sisusb->sisusb_num_columns + x); - - return sisusb->vrambase + offset; -} - -/* Interface routine */ -static void -sisusbcon_putc(struct vc_data *c, int ch, int y, int x) -{ - struct sisusb_usb_data *sisusb; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), - sisusb_haddr(sisusb, c, x, y), 2); - - mutex_unlock(&sisusb->lock); -} - -/* Interface routine */ -static void -sisusbcon_putcs(struct vc_data *c, const unsigned short *s, - int count, int y, int x) -{ - struct sisusb_usb_data *sisusb; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - /* Need to put the characters into the buffer ourselves, - * because the vt does this AFTER calling us. - */ - - memcpy(sisusb_vaddr(sisusb, c, x, y), s, count * 2); - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), - sisusb_haddr(sisusb, c, x, y), count * 2); - - mutex_unlock(&sisusb->lock); -} - -/* Interface routine */ -static void -sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) -{ - struct sisusb_usb_data *sisusb; - u16 eattr = c->vc_video_erase_char; - int i, length, cols; - u16 *dest; - - if (width <= 0 || height <= 0) - return; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - /* Need to clear buffer ourselves, because the vt does - * this AFTER calling us. - */ - - dest = sisusb_vaddr(sisusb, c, x, y); - - cols = sisusb->sisusb_num_columns; - - if (width > cols) - width = cols; - - if (x == 0 && width >= c->vc_cols) { - - sisusbcon_memsetw(dest, eattr, height * cols * 2); - - } else { - - for (i = height; i > 0; i--, dest += cols) - sisusbcon_memsetw(dest, eattr, width * 2); - - } - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - length = ((height * cols) - x - (cols - width - x)) * 2; - - - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), - sisusb_haddr(sisusb, c, x, y), length); - - mutex_unlock(&sisusb->lock); -} - -/* interface routine */ -static int -sisusbcon_switch(struct vc_data *c) -{ - struct sisusb_usb_data *sisusb; - int length; - - /* Returnvalue 0 means we have fully restored screen, - * and vt doesn't need to call do_update_region(). - * Returnvalue != 0 naturally means the opposite. - */ - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return 0; - - /* sisusb->lock is down */ - - /* Don't write to screen if in gfx mode */ - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return 0; - } - - /* That really should not happen. It would mean we are - * being called while the vc is using its private buffer - * as origin. - */ - if (c->vc_origin == (unsigned long)c->vc_screenbuf) { - mutex_unlock(&sisusb->lock); - dev_dbg(&sisusb->sisusb_dev->dev, "ASSERT ORIGIN != SCREENBUF!\n"); - return 0; - } - - /* Check that we don't copy too much */ - length = min((int)c->vc_screenbuf_size, - (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); - - /* Restore the screen contents */ - memcpy((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); - - sisusb_copy_memory(sisusb, (u8 *)c->vc_origin, - sisusb_haddr(sisusb, c, 0, 0), length); - - mutex_unlock(&sisusb->lock); - - return 0; -} - -/* interface routine */ -static void -sisusbcon_save_screen(struct vc_data *c) -{ - struct sisusb_usb_data *sisusb; - int length; - - /* Save the current screen contents to vc's private - * buffer. - */ - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - /* Check that we don't copy too much */ - length = min((int)c->vc_screenbuf_size, - (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); - - /* Save the screen contents to vc's private buffer */ - memcpy((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); - - mutex_unlock(&sisusb->lock); -} - -/* interface routine */ -static void -sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) -{ - struct sisusb_usb_data *sisusb; - int i, j; - - /* Return value not used by vt */ - - if (!con_is_visible(c)) - return; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - for (i = j = 0; i < 16; i++) { - if (sisusb_setreg(sisusb, SISCOLIDX, table[i])) - break; - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) - break; - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) - break; - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) - break; - } - - mutex_unlock(&sisusb->lock); -} - -/* interface routine */ -static int -sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) -{ - struct sisusb_usb_data *sisusb; - u8 sr1, cr17, pmreg, cr63; - int ret = 0; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return 0; - - /* sisusb->lock is down */ - - if (mode_switch) - sisusb->is_gfx = blank ? 1 : 0; - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return 0; - } - - switch (blank) { - - case 1: /* Normal blanking: Clear screen */ - case -1: - sisusbcon_memsetw((u16 *)c->vc_origin, - c->vc_video_erase_char, - c->vc_screenbuf_size); - sisusb_copy_memory(sisusb, (u8 *)c->vc_origin, - sisusb_haddr(sisusb, c, 0, 0), - c->vc_screenbuf_size); - sisusb->con_blanked = 1; - ret = 1; - break; - - default: /* VESA blanking */ - switch (blank) { - case 0: /* Unblank */ - sr1 = 0x00; - cr17 = 0x80; - pmreg = 0x00; - cr63 = 0x00; - ret = 1; - sisusb->con_blanked = 0; - break; - case VESA_VSYNC_SUSPEND + 1: - sr1 = 0x20; - cr17 = 0x80; - pmreg = 0x80; - cr63 = 0x40; - break; - case VESA_HSYNC_SUSPEND + 1: - sr1 = 0x20; - cr17 = 0x80; - pmreg = 0x40; - cr63 = 0x40; - break; - case VESA_POWERDOWN + 1: - sr1 = 0x20; - cr17 = 0x00; - pmreg = 0xc0; - cr63 = 0x40; - break; - default: - mutex_unlock(&sisusb->lock); - return -EINVAL; - } - - sisusb_setidxregandor(sisusb, SISSR, 0x01, ~0x20, sr1); - sisusb_setidxregandor(sisusb, SISCR, 0x17, 0x7f, cr17); - sisusb_setidxregandor(sisusb, SISSR, 0x1f, 0x3f, pmreg); - sisusb_setidxregandor(sisusb, SISCR, 0x63, 0xbf, cr63); - - } - - mutex_unlock(&sisusb->lock); - - return ret; -} - -/* interface routine */ -static void -sisusbcon_scrolldelta(struct vc_data *c, int lines) -{ - struct sisusb_usb_data *sisusb; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - vc_scrolldelta_helper(c, lines, sisusb->con_rolled_over, - (void *)sisusb->scrbuf, sisusb->scrbuf_size); - - sisusbcon_set_start_address(sisusb, c); - - mutex_unlock(&sisusb->lock); -} - -/* Interface routine */ -static void -sisusbcon_cursor(struct vc_data *c, int mode) -{ - struct sisusb_usb_data *sisusb; - int from, to, baseline; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return; - } - - if (c->vc_origin != c->vc_visible_origin) { - c->vc_visible_origin = c->vc_origin; - sisusbcon_set_start_address(sisusb, c); - } - - if (mode == CM_ERASE) { - sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20); - sisusb->sisusb_cursor_size_to = -1; - mutex_unlock(&sisusb->lock); - return; - } - - sisusb_set_cursor(sisusb, (c->vc_pos - sisusb->scrbuf) / 2); - - baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2); - - switch (CUR_SIZE(c->vc_cursor_type)) { - case CUR_BLOCK: from = 1; - to = c->vc_font.height; - break; - case CUR_TWO_THIRDS: from = c->vc_font.height / 3; - to = baseline; - break; - case CUR_LOWER_HALF: from = c->vc_font.height / 2; - to = baseline; - break; - case CUR_LOWER_THIRD: from = (c->vc_font.height * 2) / 3; - to = baseline; - break; - case CUR_NONE: from = 31; - to = 30; - break; - default: - case CUR_UNDERLINE: from = baseline - 1; - to = baseline; - break; - } - - if (sisusb->sisusb_cursor_size_from != from || - sisusb->sisusb_cursor_size_to != to) { - - sisusb_setidxreg(sisusb, SISCR, 0x0a, from); - sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, to); - - sisusb->sisusb_cursor_size_from = from; - sisusb->sisusb_cursor_size_to = to; - } - - mutex_unlock(&sisusb->lock); -} - -static bool -sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, - unsigned int t, unsigned int b, enum con_scroll dir, - unsigned int lines) -{ - int cols = sisusb->sisusb_num_columns; - int length = ((b - t) * cols) * 2; - u16 eattr = c->vc_video_erase_char; - - /* sisusb->lock is down */ - - /* Scroll an area which does not match the - * visible screen's dimensions. This needs - * to be done separately, as it does not - * use hardware panning. - */ - - switch (dir) { - - case SM_UP: - memmove(sisusb_vaddr(sisusb, c, 0, t), - sisusb_vaddr(sisusb, c, 0, t + lines), - (b - t - lines) * cols * 2); - sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, b - lines), - eattr, lines * cols * 2); - break; - - case SM_DOWN: - memmove(sisusb_vaddr(sisusb, c, 0, t + lines), - sisusb_vaddr(sisusb, c, 0, t), - (b - t - lines) * cols * 2); - sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, t), eattr, - lines * cols * 2); - break; - } - - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, 0, t), - sisusb_haddr(sisusb, c, 0, t), length); - - mutex_unlock(&sisusb->lock); - - return true; -} - -/* Interface routine */ -static bool -sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, - enum con_scroll dir, unsigned int lines) -{ - struct sisusb_usb_data *sisusb; - u16 eattr = c->vc_video_erase_char; - int copyall = 0; - unsigned long oldorigin; - unsigned int delta = lines * c->vc_size_row; - - /* Returning != 0 means we have done the scrolling successfully. - * Returning 0 makes vt do the scrolling on its own. - * Note that con_scroll is only called if the console is - * visible. In that case, the origin should be our buffer, - * not the vt's private one. - */ - - if (!lines) - return true; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return false; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); - return false; - } - - /* Special case */ - if (t || b != c->vc_rows) - return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines); - - if (c->vc_origin != c->vc_visible_origin) { - c->vc_visible_origin = c->vc_origin; - sisusbcon_set_start_address(sisusb, c); - } - - /* limit amount to maximum realistic size */ - if (lines > c->vc_rows) - lines = c->vc_rows; - - oldorigin = c->vc_origin; - - switch (dir) { - - case SM_UP: - - if (c->vc_scr_end + delta >= - sisusb->scrbuf + sisusb->scrbuf_size) { - memcpy((u16 *)sisusb->scrbuf, - (u16 *)(oldorigin + delta), - c->vc_screenbuf_size - delta); - c->vc_origin = sisusb->scrbuf; - sisusb->con_rolled_over = oldorigin - sisusb->scrbuf; - copyall = 1; - } else - c->vc_origin += delta; - - sisusbcon_memsetw( - (u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), - eattr, delta); - - break; - - case SM_DOWN: - - if (oldorigin - delta < sisusb->scrbuf) { - memmove((void *)sisusb->scrbuf + sisusb->scrbuf_size - - c->vc_screenbuf_size + delta, - (u16 *)oldorigin, - c->vc_screenbuf_size - delta); - c->vc_origin = sisusb->scrbuf + - sisusb->scrbuf_size - - c->vc_screenbuf_size; - sisusb->con_rolled_over = 0; - copyall = 1; - } else - c->vc_origin -= delta; - - c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; - - scr_memsetw((u16 *)(c->vc_origin), eattr, delta); - - break; - } - - if (copyall) - sisusb_copy_memory(sisusb, - (u8 *)c->vc_origin, - sisusb_haddr(sisusb, c, 0, 0), - c->vc_screenbuf_size); - else if (dir == SM_UP) - sisusb_copy_memory(sisusb, - (u8 *)c->vc_origin + c->vc_screenbuf_size - delta, - sisusb_haddr(sisusb, c, 0, 0) + - c->vc_screenbuf_size - delta, - delta); - else - sisusb_copy_memory(sisusb, - (u8 *)c->vc_origin, - sisusb_haddr(sisusb, c, 0, 0), - delta); - - c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; - c->vc_visible_origin = c->vc_origin; - - sisusbcon_set_start_address(sisusb, c); - - c->vc_pos = c->vc_pos - oldorigin + c->vc_origin; - - mutex_unlock(&sisusb->lock); - - return true; -} - -/* Interface routine */ -static int -sisusbcon_set_origin(struct vc_data *c) -{ - struct sisusb_usb_data *sisusb; - - /* Returning != 0 means we were successful. - * Returning 0 will vt make to use its own - * screenbuffer as the origin. - */ - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return 0; - - /* sisusb->lock is down */ - - if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) { - mutex_unlock(&sisusb->lock); - return 0; - } - - c->vc_origin = c->vc_visible_origin = sisusb->scrbuf; - - sisusbcon_set_start_address(sisusb, c); - - sisusb->con_rolled_over = 0; - - mutex_unlock(&sisusb->lock); - - return true; -} - -/* Interface routine */ -static int -sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows, - unsigned int user) -{ - struct sisusb_usb_data *sisusb; - int fh; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return -ENODEV; - - fh = sisusb->current_font_height; - - mutex_unlock(&sisusb->lock); - - /* We are quite unflexible as regards resizing. The vt code - * handles sizes where the line length isn't equal the pitch - * quite badly. As regards the rows, our panning tricks only - * work well if the number of rows equals the visible number - * of rows. - */ - - if (newcols != 80 || c->vc_scan_lines / fh != newrows) - return -EINVAL; - - return 0; -} - -int -sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, - u8 *arg, int cmapsz, int ch512, int dorecalc, - struct vc_data *c, int fh, int uplock) -{ - int font_select = 0x00, i, err = 0; - u32 offset = 0; - u8 dummy; - - /* sisusb->lock is down */ - - /* - * The default font is kept in slot 0. - * A user font is loaded in slot 2 (256 ch) - * or 2+3 (512 ch). - */ - - if ((slot != 0 && slot != 2) || !fh) { - if (uplock) - mutex_unlock(&sisusb->lock); - return -EINVAL; - } - - if (set) - sisusb->font_slot = slot; - - /* Default font is always 256 */ - if (slot == 0) - ch512 = 0; - else - offset = 4 * cmapsz; - - font_select = (slot == 0) ? 0x00 : (ch512 ? 0x0e : 0x0a); - - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */ - err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x04); /* Write to plane 2 */ - err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x07); /* Memory mode a0-bf */ - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset */ - - if (err) - goto font_op_error; - - err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x03); /* Select plane read 2 */ - err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x00); /* Disable odd/even */ - err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x00); /* Address range a0-bf */ - - if (err) - goto font_op_error; - - if (arg) { - if (set) - for (i = 0; i < cmapsz; i++) { - err |= sisusb_writeb(sisusb, - sisusb->vrambase + offset + i, - arg[i]); - if (err) - break; - } - else - for (i = 0; i < cmapsz; i++) { - err |= sisusb_readb(sisusb, - sisusb->vrambase + offset + i, - &arg[i]); - if (err) - break; - } - - /* - * In 512-character mode, the character map is not contiguous if - * we want to remain EGA compatible -- which we do - */ - - if (ch512) { - if (set) - for (i = 0; i < cmapsz; i++) { - err |= sisusb_writeb(sisusb, - sisusb->vrambase + offset + - (2 * cmapsz) + i, - arg[cmapsz + i]); - if (err) - break; - } - else - for (i = 0; i < cmapsz; i++) { - err |= sisusb_readb(sisusb, - sisusb->vrambase + offset + - (2 * cmapsz) + i, - &arg[cmapsz + i]); - if (err) - break; - } - } - } - - if (err) - goto font_op_error; - - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */ - err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x03); /* Write to planes 0+1 */ - err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x03); /* Memory mode a0-bf */ - if (set) - sisusb_setidxreg(sisusb, SISSR, 0x03, font_select); - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset end */ - - if (err) - goto font_op_error; - - err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x00); /* Select plane read 0 */ - err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x10); /* Enable odd/even */ - err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x06); /* Address range b8-bf */ - - if (err) - goto font_op_error; - - if ((set) && (ch512 != sisusb->current_font_512)) { - - /* Font is shared among all our consoles. - * And so is the hi_font_mask. - */ - for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct vc_data *d = vc_cons[i].d; - if (d && d->vc_sw == &sisusb_con) - d->vc_hi_font_mask = ch512 ? 0x0800 : 0; - } - - sisusb->current_font_512 = ch512; - - /* color plane enable register: - 256-char: enable intensity bit - 512-char: disable intensity bit */ - sisusb_getreg(sisusb, SISINPSTAT, &dummy); - sisusb_setreg(sisusb, SISAR, 0x12); - sisusb_setreg(sisusb, SISAR, ch512 ? 0x07 : 0x0f); - - sisusb_getreg(sisusb, SISINPSTAT, &dummy); - sisusb_setreg(sisusb, SISAR, 0x20); - sisusb_getreg(sisusb, SISINPSTAT, &dummy); - } - - if (dorecalc) { - - /* - * Adjust the screen to fit a font of a certain height - */ - - unsigned char ovr, vde, fsr; - int rows = 0, maxscan = 0; - - if (c) { - - /* Number of video rows */ - rows = c->vc_scan_lines / fh; - /* Scan lines to actually display-1 */ - maxscan = rows * fh - 1; - - /*printk(KERN_DEBUG "sisusb recalc rows %d maxscan %d fh %d sl %d\n", - rows, maxscan, fh, c->vc_scan_lines);*/ - - sisusb_getidxreg(sisusb, SISCR, 0x07, &ovr); - vde = maxscan & 0xff; - ovr = (ovr & 0xbd) | - ((maxscan & 0x100) >> 7) | - ((maxscan & 0x200) >> 3); - sisusb_setidxreg(sisusb, SISCR, 0x07, ovr); - sisusb_setidxreg(sisusb, SISCR, 0x12, vde); - - } - - sisusb_getidxreg(sisusb, SISCR, 0x09, &fsr); - fsr = (fsr & 0xe0) | (fh - 1); - sisusb_setidxreg(sisusb, SISCR, 0x09, fsr); - sisusb->current_font_height = fh; - - sisusb->sisusb_cursor_size_from = -1; - sisusb->sisusb_cursor_size_to = -1; - - } - - if (uplock) - mutex_unlock(&sisusb->lock); - - if (dorecalc && c) { - int rows = c->vc_scan_lines / fh; - - /* Now adjust our consoles' size */ - - for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct vc_data *vc = vc_cons[i].d; - - if (vc && vc->vc_sw == &sisusb_con) { - if (con_is_visible(vc)) { - vc->vc_sw->con_cursor(vc, CM_DRAW); - } - vc->vc_font.height = fh; - vc_resize(vc, 0, rows); - } - } - } - - return 0; - -font_op_error: - if (uplock) - mutex_unlock(&sisusb->lock); - - return -EIO; -} - -/* Interface routine */ -static int -sisusbcon_font_set(struct vc_data *c, struct console_font *font, - unsigned int flags) -{ - struct sisusb_usb_data *sisusb; - unsigned charcount = font->charcount; - - if (font->width != 8 || (charcount != 256 && charcount != 512)) - return -EINVAL; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return -ENODEV; - - /* sisusb->lock is down */ - - /* Save the user-provided font into a buffer. This - * is used for restoring text mode after quitting - * from X and for the con_getfont routine. - */ - if (sisusb->font_backup) { - if (sisusb->font_backup_size < charcount) { - vfree(sisusb->font_backup); - sisusb->font_backup = NULL; - } - } - - if (!sisusb->font_backup) - sisusb->font_backup = vmalloc(array_size(charcount, 32)); - - if (sisusb->font_backup) { - memcpy(sisusb->font_backup, font->data, array_size(charcount, 32)); - sisusb->font_backup_size = charcount; - sisusb->font_backup_height = font->height; - sisusb->font_backup_512 = (charcount == 512) ? 1 : 0; - } - - /* do_font_op ups sisusb->lock */ - - return sisusbcon_do_font_op(sisusb, 1, 2, font->data, - 8192, (charcount == 512), - (!(flags & KD_FONT_FLAG_DONT_RECALC)) ? 1 : 0, - c, font->height, 1); -} - -/* Interface routine */ -static int -sisusbcon_font_get(struct vc_data *c, struct console_font *font) -{ - struct sisusb_usb_data *sisusb; - - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); - if (!sisusb) - return -ENODEV; - - /* sisusb->lock is down */ - - font->width = 8; - font->height = c->vc_font.height; - font->charcount = 256; - - if (!font->data) { - mutex_unlock(&sisusb->lock); - return 0; - } - - if (!sisusb->font_backup) { - mutex_unlock(&sisusb->lock); - return -ENODEV; - } - - /* Copy 256 chars only, like vgacon */ - memcpy(font->data, sisusb->font_backup, 256 * 32); - - mutex_unlock(&sisusb->lock); - - return 0; -} - -/* - * The console `switch' structure for the sisusb console - */ - -static const struct consw sisusb_con = { - .owner = THIS_MODULE, - .con_startup = sisusbcon_startup, - .con_init = sisusbcon_init, - .con_deinit = sisusbcon_deinit, - .con_clear = sisusbcon_clear, - .con_putc = sisusbcon_putc, - .con_putcs = sisusbcon_putcs, - .con_cursor = sisusbcon_cursor, - .con_scroll = sisusbcon_scroll, - .con_switch = sisusbcon_switch, - .con_blank = sisusbcon_blank, - .con_font_set = sisusbcon_font_set, - .con_font_get = sisusbcon_font_get, - .con_set_palette = sisusbcon_set_palette, - .con_scrolldelta = sisusbcon_scrolldelta, - .con_build_attr = sisusbcon_build_attr, - .con_invert_region = sisusbcon_invert_region, - .con_set_origin = sisusbcon_set_origin, - .con_save_screen = sisusbcon_save_screen, - .con_resize = sisusbcon_resize, -}; - -/* Our very own dummy console driver */ - -static const char *sisusbdummycon_startup(void) -{ - return "SISUSBVGADUMMY"; -} - -static void sisusbdummycon_init(struct vc_data *vc, int init) -{ - vc->vc_can_do_color = 1; - if (init) { - vc->vc_cols = 80; - vc->vc_rows = 25; - } else - vc_resize(vc, 80, 25); -} - -static void sisusbdummycon_deinit(struct vc_data *vc) { } -static void sisusbdummycon_clear(struct vc_data *vc, int sy, int sx, - int height, int width) { } -static void sisusbdummycon_putc(struct vc_data *vc, int c, int ypos, - int xpos) { } -static void sisusbdummycon_putcs(struct vc_data *vc, const unsigned short *s, - int count, int ypos, int xpos) { } -static void sisusbdummycon_cursor(struct vc_data *vc, int mode) { } - -static bool sisusbdummycon_scroll(struct vc_data *vc, unsigned int top, - unsigned int bottom, enum con_scroll dir, - unsigned int lines) -{ - return false; -} - -static int sisusbdummycon_switch(struct vc_data *vc) -{ - return 0; -} - -static int sisusbdummycon_blank(struct vc_data *vc, int blank, int mode_switch) -{ - return 0; -} - -static const struct consw sisusb_dummy_con = { - .owner = THIS_MODULE, - .con_startup = sisusbdummycon_startup, - .con_init = sisusbdummycon_init, - .con_deinit = sisusbdummycon_deinit, - .con_clear = sisusbdummycon_clear, - .con_putc = sisusbdummycon_putc, - .con_putcs = sisusbdummycon_putcs, - .con_cursor = sisusbdummycon_cursor, - .con_scroll = sisusbdummycon_scroll, - .con_switch = sisusbdummycon_switch, - .con_blank = sisusbdummycon_blank, -}; - -int -sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) -{ - int i, ret; - - mutex_lock(&sisusb->lock); - - /* Erm.. that should not happen */ - if (sisusb->haveconsole || !sisusb->SiS_Pr) { - mutex_unlock(&sisusb->lock); - return 1; - } - - sisusb->con_first = first; - sisusb->con_last = last; - - if (first > last || - first > MAX_NR_CONSOLES || - last > MAX_NR_CONSOLES) { - mutex_unlock(&sisusb->lock); - return 1; - } - - /* If gfxcore not initialized or no consoles given, quit graciously */ - if (!sisusb->gfxinit || first < 1 || last < 1) { - mutex_unlock(&sisusb->lock); - return 0; - } - - sisusb->sisusb_cursor_loc = -1; - sisusb->sisusb_cursor_size_from = -1; - sisusb->sisusb_cursor_size_to = -1; - - /* Set up text mode (and upload default font) */ - if (sisusb_reset_text_mode(sisusb, 1)) { - mutex_unlock(&sisusb->lock); - dev_err(&sisusb->sisusb_dev->dev, "Failed to set up text mode\n"); - return 1; - } - - /* Initialize some gfx registers */ - sisusb_initialize(sisusb); - - for (i = first - 1; i <= last - 1; i++) { - /* Save sisusb for our interface routines */ - mysisusbs[i] = sisusb; - } - - /* Initial console setup */ - sisusb->sisusb_num_columns = 80; - - /* Use a 32K buffer (matches b8000-bffff area) */ - sisusb->scrbuf_size = 32 * 1024; - - /* Allocate screen buffer */ - if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { - mutex_unlock(&sisusb->lock); - dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate screen buffer\n"); - return 1; - } - - mutex_unlock(&sisusb->lock); - - /* Now grab the desired console(s) */ - console_lock(); - ret = do_take_over_console(&sisusb_con, first - 1, last - 1, 0); - console_unlock(); - if (!ret) - sisusb->haveconsole = 1; - else { - for (i = first - 1; i <= last - 1; i++) - mysisusbs[i] = NULL; - } - - return ret; -} - -void -sisusb_console_exit(struct sisusb_usb_data *sisusb) -{ - int i; - - /* This is called if the device is disconnected - * and while disconnect and lock semaphores - * are up. This should be save because we - * can't lose our sisusb any other way but by - * disconnection (and hence, the disconnect - * sema is for protecting all other access - * functions from disconnection, not the - * other way round). - */ - - /* Now what do we do in case of disconnection: - * One alternative would be to simply call - * give_up_console(). Nah, not a good idea. - * give_up_console() is obviously buggy as it - * only discards the consw pointer from the - * driver_map, but doesn't adapt vc->vc_sw - * of the affected consoles. Hence, the next - * call to any of the console functions will - * eventually take a trip to oops county. - * Also, give_up_console for some reason - * doesn't decrement our module refcount. - * Instead, we switch our consoles to a private - * dummy console. This, of course, keeps our - * refcount up as well, but it works perfectly. - */ - - if (sisusb->haveconsole) { - for (i = 0; i < MAX_NR_CONSOLES; i++) - if (sisusb->havethisconsole[i]) { - console_lock(); - do_take_over_console(&sisusb_dummy_con, i, i, 0); - console_unlock(); - /* At this point, con_deinit for all our - * consoles is executed by do_take_over_console(). - */ - } - sisusb->haveconsole = 0; - } - - vfree((void *)sisusb->scrbuf); - sisusb->scrbuf = 0; - - vfree(sisusb->font_backup); - sisusb->font_backup = NULL; -} - -void __init sisusb_init_concode(void) -{ - int i; - - for (i = 0; i < MAX_NR_CONSOLES; i++) - mysisusbs[i] = NULL; -} diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c deleted file mode 100644 index 7c11198d5dda0..0000000000000 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ /dev/null @@ -1,955 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) -/* - * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles - * - * Display mode initializing code - * - * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria - * - * If distributed as part of the Linux kernel, this code is licensed under the - * terms of the GPL v2. - * - * Otherwise, the following license terms apply: - * - * * Redistribution and use in source and binary forms, with or without - * * modification, are permitted provided that the following conditions - * * are met: - * * 1) Redistributions of source code must retain the above copyright - * * notice, this list of conditions and the following disclaimer. - * * 2) Redistributions in binary form must reproduce the above copyright - * * notice, this list of conditions and the following disclaimer in the - * * documentation and/or other materials provided with the distribution. - * * 3) The name of the author may not be used to endorse or promote products - * * derived from this software without specific prior written permission. - * * - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Thomas Winischhofer - * - */ - -#include -#include -#include -#include -#include - -#include "sisusb.h" -#include "sisusb_init.h" -#include "sisusb_tables.h" - -/*********************************************/ -/* POINTER INITIALIZATION */ -/*********************************************/ - -static void SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) -{ - SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; - SiS_Pr->SiS_StandTable = SiSUSB_StandTable; - - SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; - SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; - SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; - SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; - - SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; -} - -/*********************************************/ -/* HELPER: SetReg, GetReg */ -/*********************************************/ - -static void -SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, - unsigned short index, unsigned short data) -{ - sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); -} - -static void -SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, - unsigned short data) -{ - sisusb_setreg(SiS_Pr->sisusb, port, data); -} - -static unsigned char -SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index) -{ - u8 data; - - sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data); - - return data; -} - -static unsigned char -SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port) -{ - u8 data; - - sisusb_getreg(SiS_Pr->sisusb, port, &data); - - return data; -} - -static void -SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, - unsigned short index, unsigned short DataAND, - unsigned short DataOR) -{ - sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); -} - -static void -SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, - unsigned short index, unsigned short DataAND) -{ - sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); -} - -static void -SiS_SetRegOR(struct SiS_Private *SiS_Pr, unsigned long port, - unsigned short index, unsigned short DataOR) -{ - sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); -} - -/*********************************************/ -/* HELPER: DisplayOn, DisplayOff */ -/*********************************************/ - -static void SiS_DisplayOn(struct SiS_Private *SiS_Pr) -{ - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); -} - -/*********************************************/ -/* HELPER: Init Port Addresses */ -/*********************************************/ - -static void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) -{ - SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; - SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; - SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; - SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; - SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; - SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; - SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; - SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; - SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; - SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; - SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; - SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; - SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; - SiS_Pr->SiS_P3da = BaseAddr + 0x2a; - SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; -} - -/*********************************************/ -/* HELPER: GetSysFlags */ -/*********************************************/ - -static void SiS_GetSysFlags(struct SiS_Private *SiS_Pr) -{ - SiS_Pr->SiS_MyCR63 = 0x63; -} - -/*********************************************/ -/* HELPER: Init PCI & Engines */ -/*********************************************/ - -static void SiSInitPCIetc(struct SiS_Private *SiS_Pr) -{ - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); - /* - Enable 2D (0x40) - * - Enable 3D (0x02) - * - Enable 3D vertex command fetch (0x10) - * - Enable 3D command parser (0x08) - * - Enable 3D G/L transformation engine (0x80) - */ - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA); -} - -/*********************************************/ -/* HELPER: SET SEGMENT REGISTERS */ -/*********************************************/ - -static void SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) -{ - unsigned short temp; - - value &= 0x00ff; - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0; - temp |= (value >> 4); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0; - temp |= (value & 0x0f); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); -} - -static void SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) -{ - unsigned short temp; - - value &= 0x00ff; - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f; - temp |= (value & 0xf0); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f; - temp |= (value << 4); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); -} - -static void SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) -{ - SiS_SetSegRegLower(SiS_Pr, value); - SiS_SetSegRegUpper(SiS_Pr, value); -} - -static void SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) -{ - SiS_SetSegmentReg(SiS_Pr, 0); -} - -static void -SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) -{ - unsigned short temp = value >> 8; - - temp &= 0x07; - temp |= (temp << 4); - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp); - SiS_SetSegmentReg(SiS_Pr, value); -} - -static void SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) -{ - SiS_SetSegmentRegOver(SiS_Pr, 0); -} - -static void SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) -{ - SiS_ResetSegmentReg(SiS_Pr); - SiS_ResetSegmentRegOver(SiS_Pr); -} - -/*********************************************/ -/* HELPER: SearchModeID */ -/*********************************************/ - -static int -SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, - unsigned short *ModeIdIndex) -{ - if ((*ModeNo) <= 0x13) { - - if ((*ModeNo) != 0x03) - return 0; - - (*ModeIdIndex) = 0; - - } else { - - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - - if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == - (*ModeNo)) - break; - - if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == - 0xFF) - return 0; - } - - } - - return 1; -} - -/*********************************************/ -/* HELPER: ENABLE CRT1 */ -/*********************************************/ - -static void SiS_HandleCRT1(struct SiS_Private *SiS_Pr) -{ - /* Enable CRT1 gating */ - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); -} - -/*********************************************/ -/* HELPER: GetColorDepth */ -/*********************************************/ - -static unsigned short -SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex) -{ - static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; - unsigned short modeflag; - short index; - - if (ModeNo <= 0x13) { - modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } - - index = (modeflag & ModeTypeMask) - ModeEGA; - if (index < 0) - index = 0; - return ColorDepth[index]; -} - -/*********************************************/ -/* HELPER: GetOffset */ -/*********************************************/ - -static unsigned short -SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex, unsigned short rrti) -{ - unsigned short xres, temp, colordepth, infoflag; - - infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; - xres = SiS_Pr->SiS_RefIndex[rrti].XRes; - - colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); - - temp = xres / 16; - - if (infoflag & InterlaceMode) - temp <<= 1; - - temp *= colordepth; - - if (xres % 16) - temp += (colordepth >> 1); - - return temp; -} - -/*********************************************/ -/* SEQ */ -/*********************************************/ - -static void -SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) -{ - unsigned char SRdata; - int i; - - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03); - - SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); - - for (i = 2; i <= 4; i++) { - SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); - } -} - -/*********************************************/ -/* MISC */ -/*********************************************/ - -static void -SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) -{ - unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; - - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata); -} - -/*********************************************/ -/* CRTC */ -/*********************************************/ - -static void -SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) -{ - unsigned char CRTCdata; - unsigned short i; - - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); - - for (i = 0; i <= 0x18; i++) { - CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); - } -} - -/*********************************************/ -/* ATT */ -/*********************************************/ - -static void -SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) -{ - unsigned char ARdata; - unsigned short i; - - for (i = 0; i <= 0x13; i++) { - ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata); - } - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00); - - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20); - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); -} - -/*********************************************/ -/* GRC */ -/*********************************************/ - -static void -SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) -{ - unsigned char GRdata; - unsigned short i; - - for (i = 0; i <= 0x08; i++) { - GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); - } - - if (SiS_Pr->SiS_ModeType > ModeVGA) { - /* 256 color disable */ - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce, 0x05, 0xBF); - } -} - -/*********************************************/ -/* CLEAR EXTENDED REGISTERS */ -/*********************************************/ - -static void SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) -{ - int i; - - for (i = 0x0A; i <= 0x0E; i++) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); - } - - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x37, 0xFE); -} - -/*********************************************/ -/* Get rate index */ -/*********************************************/ - -static unsigned short -SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex) -{ - unsigned short rrti, i, index, temp; - - if (ModeNo <= 0x13) - return 0xFFFF; - - index = SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x33) & 0x0F; - if (index > 0) - index--; - - rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; - ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; - - i = 0; - do { - if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) - break; - - temp = - SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; - if (temp < SiS_Pr->SiS_ModeType) - break; - - i++; - index--; - } while (index != 0xFFFF); - - i--; - - return (rrti + i); -} - -/*********************************************/ -/* SYNC */ -/*********************************************/ - -static void SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) -{ - unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; - sync &= 0xC0; - sync |= 0x2f; - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, sync); -} - -/*********************************************/ -/* CRTC/2 */ -/*********************************************/ - -static void -SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex, unsigned short rrti) -{ - unsigned char index; - unsigned short temp, i, j, modeflag; - - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); - - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; - - for (i = 0, j = 0; i <= 7; i++, j++) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, - SiS_Pr->SiS_CRT1Table[index].CR[i]); - } - for (j = 0x10; i <= 10; i++, j++) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, - SiS_Pr->SiS_CRT1Table[index].CR[i]); - } - for (j = 0x15; i <= 12; i++, j++) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, - SiS_Pr->SiS_CRT1Table[index].CR[i]); - } - for (j = 0x0A; i <= 15; i++, j++) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, - SiS_Pr->SiS_CRT1Table[index].CR[i]); - } - - temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, temp); - - temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; - if (modeflag & DoubleScanMode) - temp |= 0x80; - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); - - if (SiS_Pr->SiS_ModeType > ModeVGA) - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x14, 0x4F); -} - -/*********************************************/ -/* OFFSET & PITCH */ -/*********************************************/ -/* (partly overruled by SetPitch() in XF86) */ -/*********************************************/ - -static void -SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex, unsigned short rrti) -{ - unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); - unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; - unsigned short temp; - - temp = (du >> 8) & 0x0f; - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, 0xF0, temp); - - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); - - if (infoflag & InterlaceMode) - du >>= 1; - - du <<= 5; - temp = (du >> 8) & 0xff; - if (du & 0xff) - temp++; - temp++; - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); -} - -/*********************************************/ -/* VCLK */ -/*********************************************/ - -static void -SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short rrti) -{ - unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; - unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; - unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; - - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xCF); - - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2B, clka); - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2C, clkb); - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2D, 0x01); -} - -/*********************************************/ -/* FIFO */ -/*********************************************/ - -static void -SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short mi) -{ - unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; - - /* disable auto-threshold */ - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0xFE); - - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0xAE); - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x09, 0xF0); - - if (ModeNo <= 0x13) - return; - - if ((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0x34); - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0x01); - } -} - -/*********************************************/ -/* MODE REGISTERS */ -/*********************************************/ - -static void -SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short rrti) -{ - unsigned short data = 0, VCLK = 0, index = 0; - - if (ModeNo > 0x13) { - index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; - VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; - } - - if (VCLK >= 166) - data |= 0x0c; - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); - - if (VCLK >= 166) - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1f, 0xe7); - - /* DAC speed */ - data = 0x03; - if (VCLK >= 260) - data = 0x00; - else if (VCLK >= 160) - data = 0x01; - else if (VCLK >= 135) - data = 0x02; - - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x07, 0xF8, data); -} - -static void -SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex, unsigned short rrti) -{ - unsigned short data, infoflag = 0, modeflag; - - if (ModeNo <= 0x13) - modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; - else { - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; - } - - /* Disable DPMS */ - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1F, 0x3F); - - data = 0; - if (ModeNo > 0x13) { - if (SiS_Pr->SiS_ModeType > ModeEGA) { - data |= 0x02; - data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); - } - if (infoflag & InterlaceMode) - data |= 0x20; - } - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); - - data = 0; - if (infoflag & InterlaceMode) { - /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ - unsigned short hrs = - (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | - ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) - - 3; - unsigned short hto = - (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | - ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) - + 5; - data = hrs - (hto >> 1) + 3; - } - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x1a, 0xFC, (data >> 8)); - - if (modeflag & HalfDCLK) - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0x08); - - data = 0; - if (modeflag & LineCompareOff) - data = 0x08; - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0xB7, data); - - if ((SiS_Pr->SiS_ModeType == ModeEGA) && (ModeNo > 0x13)) - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0x40); - - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xfb); - - data = 0x60; - if (SiS_Pr->SiS_ModeType != ModeText) { - data ^= 0x60; - if (SiS_Pr->SiS_ModeType != ModeEGA) - data ^= 0xA0; - } - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x21, 0x1F, data); - - SiS_SetVCLKState(SiS_Pr, ModeNo, rrti); - - if (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x31) & 0x40) - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x2c); - else - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x6c); -} - -/*********************************************/ -/* LOAD DAC */ -/*********************************************/ - -static void -SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, - unsigned short shiftflag, unsigned short dl, unsigned short ah, - unsigned short al, unsigned short dh) -{ - unsigned short d1, d2, d3; - - switch (dl) { - case 0: - d1 = dh; - d2 = ah; - d3 = al; - break; - case 1: - d1 = ah; - d2 = al; - d3 = dh; - break; - default: - d1 = al; - d2 = dh; - d3 = ah; - } - SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); - SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); - SiS_SetRegByte(SiS_Pr, DACData, (d3 << shiftflag)); -} - -static void -SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short mi) -{ - unsigned short data, data2, time, i, j, k, m, n, o; - unsigned short si, di, bx, sf; - unsigned long DACAddr, DACData; - const unsigned char *table = NULL; - - if (ModeNo < 0x13) - data = SiS_Pr->SiS_SModeIDTable[mi].St_ModeFlag; - else - data = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; - - data &= DACInfoFlag; - - j = time = 64; - if (data == 0x00) - table = SiS_MDA_DAC; - else if (data == 0x08) - table = SiS_CGA_DAC; - else if (data == 0x10) - table = SiS_EGA_DAC; - else { - j = 16; - time = 256; - table = SiS_VGA_DAC; - } - - DACAddr = SiS_Pr->SiS_P3c8; - DACData = SiS_Pr->SiS_P3c9; - sf = 0; - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF); - - SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); - - for (i = 0; i < j; i++) { - data = table[i]; - for (k = 0; k < 3; k++) { - data2 = 0; - if (data & 0x01) - data2 += 0x2A; - if (data & 0x02) - data2 += 0x15; - SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); - data >>= 2; - } - } - - if (time == 256) { - for (i = 16; i < 32; i++) { - data = table[i] << sf; - for (k = 0; k < 3; k++) - SiS_SetRegByte(SiS_Pr, DACData, data); - } - si = 32; - for (m = 0; m < 9; m++) { - di = si; - bx = si + 4; - for (n = 0; n < 3; n++) { - for (o = 0; o < 5; o++) { - SiS_WriteDAC(SiS_Pr, DACData, sf, n, - table[di], table[bx], - table[si]); - si++; - } - si -= 2; - for (o = 0; o < 3; o++) { - SiS_WriteDAC(SiS_Pr, DACData, sf, n, - table[di], table[si], - table[bx]); - si--; - } - } - si += 5; - } - } -} - -/*********************************************/ -/* SET CRT1 REGISTER GROUP */ -/*********************************************/ - -static void -SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, - unsigned short ModeIdIndex) -{ - unsigned short StandTableIndex, rrti; - - SiS_Pr->SiS_CRT1Mode = ModeNo; - - if (ModeNo <= 0x13) - StandTableIndex = 0; - else - StandTableIndex = 1; - - SiS_ResetSegmentRegisters(SiS_Pr); - SiS_SetSeqRegs(SiS_Pr, StandTableIndex); - SiS_SetMiscRegs(SiS_Pr, StandTableIndex); - SiS_SetCRTCRegs(SiS_Pr, StandTableIndex); - SiS_SetATTRegs(SiS_Pr, StandTableIndex); - SiS_SetGRCRegs(SiS_Pr, StandTableIndex); - SiS_ClearExt1Regs(SiS_Pr, ModeNo); - - rrti = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); - - if (rrti != 0xFFFF) { - SiS_SetCRT1Sync(SiS_Pr, rrti); - SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, rrti); - SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, rrti); - SiS_SetCRT1VCLK(SiS_Pr, ModeNo, rrti); - } - - SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex); - - SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, rrti); - - SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); - - SiS_DisplayOn(SiS_Pr); -} - -/*********************************************/ -/* SiSSetMode() */ -/*********************************************/ - -int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) -{ - unsigned short ModeIdIndex; - unsigned long BaseAddr = SiS_Pr->IOAddress; - - SiSUSB_InitPtr(SiS_Pr); - SiSUSBRegInit(SiS_Pr, BaseAddr); - SiS_GetSysFlags(SiS_Pr); - - if (!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) - return 0; - - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x05, 0x86); - - SiSInitPCIetc(SiS_Pr); - - ModeNo &= 0x7f; - - SiS_Pr->SiS_ModeType = - SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; - - SiS_Pr->SiS_SetFlag = LowModeTests; - - /* Set mode on CRT1 */ - SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); - - SiS_HandleCRT1(SiS_Pr); - - SiS_DisplayOn(SiS_Pr); - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF); - - /* Store mode number */ - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x34, ModeNo); - - return 1; -} - -int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) -{ - unsigned short ModeNo = 0; - int i; - - SiSUSB_InitPtr(SiS_Pr); - - if (VModeNo == 0x03) { - - ModeNo = 0x03; - - } else { - - i = 0; - do { - - if (SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID == VModeNo) { - ModeNo = SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID; - break; - } - - } while (SiS_Pr->SiS_EModeIDTable[i++].Ext_ModeID != 0xff); - - } - - if (!ModeNo) - return 0; - - return SiSUSBSetMode(SiS_Pr, ModeNo); -} diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h deleted file mode 100644 index b5cd77ae941d7..0000000000000 --- a/drivers/usb/misc/sisusbvga/sisusb_init.h +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -/* $XFree86$ */ -/* $XdotOrg$ */ -/* - * Data and prototypes for init.c - * - * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria - * - * If distributed as part of the Linux kernel, the following license terms - * apply: - * - * * This program is free software; you can redistribute it and/or modify - * * it under the terms of the GNU General Public License as published by - * * the Free Software Foundation; either version 2 of the named License, - * * or any later version. - * * - * * This program is distributed in the hope that it will be useful, - * * but WITHOUT ANY WARRANTY; without even the implied warranty of - * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * * GNU General Public License for more details. - * * - * * You should have received a copy of the GNU General Public License - * * along with this program; if not, write to the Free Software - * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - * - * Otherwise, the following license terms apply: - * - * * Redistribution and use in source and binary forms, with or without - * * modification, are permitted provided that the following conditions - * * are met: - * * 1) Redistributions of source code must retain the above copyright - * * notice, this list of conditions and the following disclaimer. - * * 2) Redistributions in binary form must reproduce the above copyright - * * notice, this list of conditions and the following disclaimer in the - * * documentation and/or other materials provided with the distribution. - * * 3) The name of the author may not be used to endorse or promote products - * * derived from this software without specific prior written permission. - * * - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Thomas Winischhofer - * - */ - -#ifndef _SISUSB_INIT_H_ -#define _SISUSB_INIT_H_ - -/* SiS_ModeType */ -#define ModeText 0x00 -#define ModeCGA 0x01 -#define ModeEGA 0x02 -#define ModeVGA 0x03 -#define Mode15Bpp 0x04 -#define Mode16Bpp 0x05 -#define Mode24Bpp 0x06 -#define Mode32Bpp 0x07 - -#define ModeTypeMask 0x07 -#define IsTextMode 0x07 - -#define DACInfoFlag 0x0018 -#define MemoryInfoFlag 0x01E0 -#define MemorySizeShift 5 - -/* modeflag */ -#define Charx8Dot 0x0200 -#define LineCompareOff 0x0400 -#define CRT2Mode 0x0800 -#define HalfDCLK 0x1000 -#define NoSupportSimuTV 0x2000 -#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ -#define DoubleScanMode 0x8000 - -/* Infoflag */ -#define SupportTV 0x0008 -#define SupportTV1024 0x0800 -#define SupportCHTV 0x0800 -#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ -#define SupportHiVision 0x0010 -#define SupportYPbPr750p 0x1000 -#define SupportLCD 0x0020 -#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ -#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ -#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ -#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ -#define InterlaceMode 0x0080 -#define SyncPP 0x0000 -#define SyncPN 0x4000 -#define SyncNP 0x8000 -#define SyncNN 0xc000 - -/* SetFlag */ -#define ProgrammingCRT2 0x0001 -#define LowModeTests 0x0002 -#define LCDVESATiming 0x0008 -#define EnableLVDSDDA 0x0010 -#define SetDispDevSwitchFlag 0x0020 -#define CheckWinDos 0x0040 -#define SetDOSMode 0x0080 - -/* Index in ModeResInfo table */ -#define SIS_RI_320x200 0 -#define SIS_RI_320x240 1 -#define SIS_RI_320x400 2 -#define SIS_RI_400x300 3 -#define SIS_RI_512x384 4 -#define SIS_RI_640x400 5 -#define SIS_RI_640x480 6 -#define SIS_RI_800x600 7 -#define SIS_RI_1024x768 8 -#define SIS_RI_1280x1024 9 -#define SIS_RI_1600x1200 10 -#define SIS_RI_1920x1440 11 -#define SIS_RI_2048x1536 12 -#define SIS_RI_720x480 13 -#define SIS_RI_720x576 14 -#define SIS_RI_1280x960 15 -#define SIS_RI_800x480 16 -#define SIS_RI_1024x576 17 -#define SIS_RI_1280x720 18 -#define SIS_RI_856x480 19 -#define SIS_RI_1280x768 20 -#define SIS_RI_1400x1050 21 -#define SIS_RI_1152x864 22 /* Up to here SiS conforming */ -#define SIS_RI_848x480 23 -#define SIS_RI_1360x768 24 -#define SIS_RI_1024x600 25 -#define SIS_RI_1152x768 26 -#define SIS_RI_768x576 27 -#define SIS_RI_1360x1024 28 -#define SIS_RI_1680x1050 29 -#define SIS_RI_1280x800 30 -#define SIS_RI_1920x1080 31 -#define SIS_RI_960x540 32 -#define SIS_RI_960x600 33 - -#define SIS_VIDEO_CAPTURE 0x00 - 0x30 -#define SIS_VIDEO_PLAYBACK 0x02 - 0x30 -#define SIS_CRT2_PORT_04 0x04 - 0x30 - -int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); -int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); - -extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data); -extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data); -extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, - u8 index, u8 data); -extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, - u8 index, u8 * data); -extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, - u8 idx, u8 myand, u8 myor); -extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, - u8 index, u8 myor); -extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, - u8 idx, u8 myand); - -void sisusb_delete(struct kref *kref); -int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); -int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); -int sisusb_copy_memory(struct sisusb_usb_data *sisusb, u8 *src, - u32 dest, int length); -int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); -int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, - u8 * arg, int cmapsz, int ch512, int dorecalc, - struct vc_data *c, int fh, int uplock); -void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); -int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); -void sisusb_console_exit(struct sisusb_usb_data *sisusb); -void sisusb_init_concode(void); - -#endif -- GitLab From a2f3d83cd74eb7cfc69c92d086ec4509cd9c58fb Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 8 Dec 2022 10:07:47 +0100 Subject: [PATCH 1350/1480] USB: sisusbvga: rename sisusb.c to sisusbvga.c As it's the only source for the sisusbvga module, there is no need for a 2-steps build. Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Yoshinori Sato Cc: Rich Felker Cc: Thomas Winischhofer Cc: Greg Kroah-Hartman Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-usb@vger.kernel.org Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221208090749.28056-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/Makefile | 2 -- drivers/usb/misc/sisusbvga/{sisusb.c => sisusbvga.c} | 0 2 files changed, 2 deletions(-) rename drivers/usb/misc/sisusbvga/{sisusb.c => sisusbvga.c} (100%) diff --git a/drivers/usb/misc/sisusbvga/Makefile b/drivers/usb/misc/sisusbvga/Makefile index 93265de80eb9f..28aa1e6ef823f 100644 --- a/drivers/usb/misc/sisusbvga/Makefile +++ b/drivers/usb/misc/sisusbvga/Makefile @@ -4,5 +4,3 @@ # obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o - -sisusbvga-y := sisusb.o diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusbvga.c similarity index 100% rename from drivers/usb/misc/sisusbvga/sisusb.c rename to drivers/usb/misc/sisusbvga/sisusbvga.c -- GitLab From 4b6be020bd6b126112c06648de17ead360919ab4 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 8 Dec 2022 10:07:48 +0100 Subject: [PATCH 1351/1480] USB: sisusbvga: use module_usb_driver() Now, that we only do usb_register() and usb_sisusb_exit() in module_init() and module_exit() respectivelly, we can simply use module_usb_driver(). Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Yoshinori Sato Cc: Rich Felker Cc: Thomas Winischhofer Cc: Greg Kroah-Hartman Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-usb@vger.kernel.org Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20221208090749.28056-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusbvga.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusbvga.c b/drivers/usb/misc/sisusbvga/sisusbvga.c index a0d5ba8058f8f..654a79fd3231e 100644 --- a/drivers/usb/misc/sisusbvga/sisusbvga.c +++ b/drivers/usb/misc/sisusbvga/sisusbvga.c @@ -2947,18 +2947,7 @@ static struct usb_driver sisusb_driver = { .id_table = sisusb_table, }; -static int __init usb_sisusb_init(void) -{ - return usb_register(&sisusb_driver); -} - -static void __exit usb_sisusb_exit(void) -{ - usb_deregister(&sisusb_driver); -} - -module_init(usb_sisusb_init); -module_exit(usb_sisusb_exit); +module_usb_driver(sisusb_driver); MODULE_AUTHOR("Thomas Winischhofer "); MODULE_DESCRIPTION("sisusbvga - Driver for Net2280/SiS315-based USB2VGA dongles"); -- GitLab From c35ca10f53c51eeb610d3f8fbc6dd6d511b58a58 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 8 Dec 2022 19:00:58 +0800 Subject: [PATCH 1352/1480] usb: storage: Add check for kcalloc As kcalloc may return NULL pointer, the return value should be checked and return error if fails as same as the ones in alauda_read_map. Fixes: e80b0fade09e ("[PATCH] USB Storage: add alauda support") Acked-by: Alan Stern Signed-off-by: Jiasheng Jiang Link: https://lore.kernel.org/r/20221208110058.12983-1-jiasheng@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/alauda.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 747be69e5e699..5e912dd29b4c9 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -438,6 +438,8 @@ static int alauda_init_media(struct us_data *us) + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); + if (MEDIA_INFO(us).pba_to_lba == NULL || MEDIA_INFO(us).lba_to_pba == NULL) + return USB_STOR_TRANSPORT_ERROR; if (alauda_reset_media(us) != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; -- GitLab From dc18a4c7b3bd447cef2395deeb1f6ac16dfaca0e Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 3 Dec 2022 15:10:27 +0800 Subject: [PATCH 1353/1480] usb: typec: wusb3801: fix fwnode refcount leak in wusb3801_probe() I got the following report while doing fault injection test: OF: ERROR: memory leak, expected refcount 1 instead of 4, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node /i2c/tcpc@60/connector If wusb3801_hw_init() fails, fwnode_handle_put() needs be called to avoid refcount leak. Fixes: d016cbe4d7ac ("usb: typec: Support the WUSB3801 port controller") Reviewed-by: Heikki Krogerus Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221203071027.3808308-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/wusb3801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/wusb3801.c b/drivers/usb/typec/wusb3801.c index 3cc7a15ecbd31..a43a18d4b02ed 100644 --- a/drivers/usb/typec/wusb3801.c +++ b/drivers/usb/typec/wusb3801.c @@ -364,7 +364,7 @@ static int wusb3801_probe(struct i2c_client *client) /* Initialize the hardware with the devicetree settings. */ ret = wusb3801_hw_init(wusb3801); if (ret) - return ret; + goto err_put_connector; wusb3801->cap.revision = USB_TYPEC_REV_1_2; wusb3801->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO; -- GitLab From 97a48da1619ba6bd42a0e5da0a03aa490a9496b1 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Tue, 6 Dec 2022 12:17:31 +0400 Subject: [PATCH 1354/1480] usb: dwc3: qcom: Fix memory leak in dwc3_qcom_interconnect_init of_icc_get() alloc resources for path handle, we should release it when not need anymore. Like the release in dwc3_qcom_interconnect_exit() function. Add icc_put() in error handling to fix this. Fixes: bea46b981515 ("usb: dwc3: qcom: Add interconnect support in dwc3 driver") Cc: stable Acked-by: Thinh Nguyen Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20221206081731.818107-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-qcom.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 7c40f3ffc0544..b0a0351d2d8b5 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -261,7 +261,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) if (IS_ERR(qcom->icc_path_apps)) { dev_err(dev, "failed to get apps-usb path: %ld\n", PTR_ERR(qcom->icc_path_apps)); - return PTR_ERR(qcom->icc_path_apps); + ret = PTR_ERR(qcom->icc_path_apps); + goto put_path_ddr; } max_speed = usb_get_maximum_speed(&qcom->dwc3->dev); @@ -274,16 +275,22 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) } if (ret) { dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret); - return ret; + goto put_path_apps; } ret = icc_set_bw(qcom->icc_path_apps, APPS_USB_AVG_BW, APPS_USB_PEAK_BW); if (ret) { dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret); - return ret; + goto put_path_apps; } return 0; + +put_path_apps: + icc_put(qcom->icc_path_apps); +put_path_ddr: + icc_put(qcom->icc_path_ddr); + return ret; } /** -- GitLab From 4c92670b16727365699fe4b19ed32013bab2c107 Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Tue, 6 Dec 2022 15:13:01 +0100 Subject: [PATCH 1355/1480] usb: gadget: uvc: Prevent buffer overflow in setup handler Setup function uvc_function_setup permits control transfer requests with up to 64 bytes of payload (UVC_MAX_REQUEST_SIZE), data stage handler for OUT transfer uses memcpy to copy req->actual bytes to uvc_event->data.data array of size 60. This may result in an overflow of 4 bytes. Fixes: cdda479f15cd ("USB gadget: video class function driver") Cc: stable Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Scally Signed-off-by: Szymon Heidrich Link: https://lore.kernel.org/r/20221206141301.51305-1-szymon.heidrich@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_uvc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 6e131624011a5..32f2c16454670 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -213,8 +213,9 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_DATA; - uvc_event->data.length = req->actual; - memcpy(&uvc_event->data.data, req->buf, req->actual); + uvc_event->data.length = min_t(unsigned int, req->actual, + sizeof(uvc_event->data.data)); + memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length); v4l2_event_queue(&uvc->vdev, &v4l2_event); } } -- GitLab From ecec4b20d29c3d6922dafe7d2555254a454272d2 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Fri, 25 Nov 2022 20:21:15 +0200 Subject: [PATCH 1356/1480] usb: musb: remove extra check in musb_gadget_vbus_draw The checks for musb->xceiv and musb->xceiv->set_power duplicate those in usb_phy_set_power(), so there is no need of them. Moreover, not calling usb_phy_set_power() results in usb_phy_set_charger_current() not being called, so current USB config max current is not propagated through USB charger framework and charger drivers may try to draw more current than allowed or possible. Fix that by removing those extra checks and calling usb_phy_set_power() directly. Tested on Motorola Droid4 and Nokia N900 Fixes: a9081a008f84 ("usb: phy: Add USB charger support") Cc: stable Signed-off-by: Ivaylo Dimitrov Link: https://lore.kernel.org/r/1669400475-4762-1-git-send-email-ivo.g.dimitrov.75@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6cb9514ef3405..31c44325e8287 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1630,8 +1630,6 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) { struct musb *musb = gadget_to_musb(gadget); - if (!musb->xceiv || !musb->xceiv->set_power) - return -EOPNOTSUPP; return usb_phy_set_power(musb->xceiv, mA); } -- GitLab From 6f1f0ad910f73f5533b65e1748448d334e0ec697 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 25 Nov 2022 17:04:44 +0100 Subject: [PATCH 1357/1480] usb: gadget: udc: drop obsolete dependencies on COMPILE_TEST Since commit 0166dc11be91 ("of: make CONFIG_OF user selectable"), it is possible to test-build any driver which depends on OF on any architecture by explicitly selecting OF. Therefore depending on COMPILE_TEST as an alternative is no longer needed. It is actually better to always build such drivers with OF enabled, so that the test builds are closer to how each driver will actually be built on its intended target. Building them without OF may not test much as the compiler will optimize out potentially large parts of the code. In the worst case, this could even pop false positive warnings. Dropping COMPILE_TEST here improves the quality of our testing and avoids wasting time on non-existent issues. Cc: Greg Kroah-Hartman Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: Michal Simek Acked-by: Nicolas Ferre Signed-off-by: Jean Delvare Link: https://lore.kernel.org/r/20221125170444.36620123@endymion.delvare Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 16243964b1cd1..b3006d8b04ab3 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -33,7 +33,7 @@ menu "USB Peripheral Controller" config USB_AT91 tristate "Atmel AT91 USB Device Port" depends on ARCH_AT91 - depends on OF || COMPILE_TEST + depends on OF help Many Atmel AT91 processors (such as the AT91RM2000) have a full speed USB Device Port with support for five configurable @@ -419,7 +419,7 @@ config USB_EG20T config USB_GADGET_XILINX tristate "Xilinx USB Driver" depends on HAS_DMA - depends on OF || COMPILE_TEST + depends on OF help USB peripheral controller driver for Xilinx USB2 device. Xilinx USB2 device is a soft IP which supports both full -- GitLab From 59d54aa09020fe52061d4cda51d474f5bd5e6be1 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Mon, 28 Nov 2022 17:23:04 +0100 Subject: [PATCH 1358/1480] usb: typec: tipd: Set mode of operation for USB Type-C connector Forward the mode of operation to the typec subsystem such that it can configure the mux correctly. Reviewed-by: Heikki Krogerus Signed-off-by: Sven Peter Link: https://lore.kernel.org/r/20221128162304.80125-1-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tipd/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 982bd2cad931d..46a4d8b128f0e 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "tps6598x.h" @@ -257,6 +258,7 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status) typec_set_orientation(tps->port, TYPEC_ORIENTATION_REVERSE); else typec_set_orientation(tps->port, TYPEC_ORIENTATION_NORMAL); + typec_set_mode(tps->port, TYPEC_STATE_USB); tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), true); tps->partner = typec_register_partner(tps->port, &desc); @@ -280,6 +282,7 @@ static void tps6598x_disconnect(struct tps6598x *tps, u32 status) typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(status)); typec_set_vconn_role(tps->port, TPS_STATUS_TO_TYPEC_VCONN(status)); typec_set_orientation(tps->port, TYPEC_ORIENTATION_NONE); + typec_set_mode(tps->port, TYPEC_STATE_SAFE); tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), false); power_supply_changed(tps->psy); -- GitLab From 0cd142b4665ee3133cd80539b5a430be5fd326c6 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Fri, 2 Dec 2022 09:21:26 +0800 Subject: [PATCH 1359/1480] usb: fotg210-udc: fix potential memory leak in fotg210_udc_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In fotg210_udc_probe(), if devm_clk_get() or clk_prepare_enable() fails, 'fotg210' will not be freed, which will lead to a memory leak. Fix it by moving kfree() to a proper location. In addition,we can use "return -ENOMEM" instead of "goto err" to simplify the code. Fixes: 718a38d092ec ("fotg210-udc: Handle PCLK") Reviewed-by: Andrzej Pietrasiewicz Reviewed-by: Linus Walleij Signed-off-by: Yi Yang Link: https://lore.kernel.org/r/20221202012126.246953-1-yiyang13@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/fotg210/fotg210-udc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index b9ea6c6d931c6..66e1b7ee3346e 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -1163,12 +1163,10 @@ int fotg210_udc_probe(struct platform_device *pdev) return -ENODEV; } - ret = -ENOMEM; - /* initialize udc */ fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); if (fotg210 == NULL) - goto err; + return -ENOMEM; fotg210->dev = dev; @@ -1178,7 +1176,7 @@ int fotg210_udc_probe(struct platform_device *pdev) ret = clk_prepare_enable(fotg210->pclk); if (ret) { dev_err(dev, "failed to enable PCLK\n"); - return ret; + goto err; } } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) { /* @@ -1302,8 +1300,7 @@ err_pclk: if (!IS_ERR(fotg210->pclk)) clk_disable_unprepare(fotg210->pclk); - kfree(fotg210); - err: + kfree(fotg210); return ret; } -- GitLab From 38cea8e31e9ef143187135d714aed4d7bd18463c Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 6 Dec 2022 13:52:23 +0800 Subject: [PATCH 1360/1480] dt-bindings: vendor-prefixes: add Genesys Logic Genesys Logic, Inc. is a manufacturer for interface chips, especially USB hubs. https://www.genesyslogic.com.tw/ Signed-off-by: Icenowy Zheng Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221206055228.306074-2-uwu@icenowy.me Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6e323a380294a..43359c0ccaf53 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -488,6 +488,8 @@ patternProperties: description: GE Fanuc Intelligent Platforms Embedded Systems, Inc. "^gemei,.*": description: Gemei Digital Technology Co., Ltd. + "^genesys,.*": + description: Genesys Logic, Inc. "^geniatech,.*": description: Geniatech, Inc. "^giantec,.*": -- GitLab From 4e3a4fcd871274c0233ea498c685b118a21ff3d0 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 6 Dec 2022 13:52:24 +0800 Subject: [PATCH 1361/1480] dt-bindings: usb: Add binding for Genesys Logic GL850G hub controller The Genesys Logic GL850G is a USB 2.0 Single TT hub controller that features 4 downstream ports, an internal 5V-to-3.3V LDO regulator (can be bypassed) and an external reset pin. Add a device tree binding for its USB protocol part. The internal LDO is not covered by this and can just be modelled as a fixed regulator. Signed-off-by: Icenowy Zheng Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221206055228.306074-3-uwu@icenowy.me Signed-off-by: Greg Kroah-Hartman --- .../bindings/usb/genesys,gl850g.yaml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/genesys,gl850g.yaml diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml new file mode 100644 index 0000000000000..a9f831448ccae --- /dev/null +++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/genesys,gl850g.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Genesys Logic GL850G USB 2.0 hub controller + +maintainers: + - Icenowy Zheng + +allOf: + - $ref: usb-device.yaml# + +properties: + compatible: + enum: + - usb5e3,608 + + reg: true + + reset-gpios: + description: GPIO controlling the RESET# pin. + + vdd-supply: + description: + the regulator that provides 3.3V core power to the hub. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + usb { + dr_mode = "host"; + #address-cells = <1>; + #size-cells = <0>; + + hub: hub@1 { + compatible = "usb5e3,608"; + reg = <1>; + reset-gpios = <&pio 7 2 GPIO_ACTIVE_LOW>; + }; + }; -- GitLab From 9bae996ffa28ac03b6d95382a2a082eb219e745a Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 6 Dec 2022 13:52:25 +0800 Subject: [PATCH 1362/1480] usb: misc: onboard_usb_hub: add Genesys Logic GL850G hub support Genesys Logic GL850G is a 4-port USB 2.0 STT hub that has a reset pin to toggle and a 3.3V core supply exported (although an integrated LDO is available for powering it with 5V). Add the support for this hub, for controlling the reset pin and the core power supply. Signed-off-by: Icenowy Zheng Acked-by: Matthias Kaehlcke Link: https://lore.kernel.org/r/20221206055228.306074-4-uwu@icenowy.me Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/onboard_usb_hub.c | 2 ++ drivers/usb/misc/onboard_usb_hub.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c index d63c63942af1b..94e7966e199d1 100644 --- a/drivers/usb/misc/onboard_usb_hub.c +++ b/drivers/usb/misc/onboard_usb_hub.c @@ -331,6 +331,7 @@ static struct platform_driver onboard_hub_driver = { /************************** USB driver **************************/ +#define VENDOR_ID_GENESYS 0x05e3 #define VENDOR_ID_MICROCHIP 0x0424 #define VENDOR_ID_REALTEK 0x0bda #define VENDOR_ID_TI 0x0451 @@ -407,6 +408,7 @@ static void onboard_hub_usbdev_disconnect(struct usb_device *udev) } static const struct usb_device_id onboard_hub_id_table[] = { + { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */ { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */ { USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */ diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_hub.h index 34beab8bce3d6..62129a6a1ba5a 100644 --- a/drivers/usb/misc/onboard_usb_hub.h +++ b/drivers/usb/misc/onboard_usb_hub.h @@ -22,10 +22,15 @@ static const struct onboard_hub_pdata ti_tusb8041_data = { .reset_us = 3000, }; +static const struct onboard_hub_pdata genesys_gl850g_data = { + .reset_us = 3, +}; + static const struct of_device_id onboard_hub_match[] = { { .compatible = "usb424,2514", .data = µchip_usb424_data, }, { .compatible = "usb451,8140", .data = &ti_tusb8041_data, }, { .compatible = "usb451,8142", .data = &ti_tusb8041_data, }, + { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,414", .data = &realtek_rts5411_data, }, -- GitLab From 8a7b31d545d3a15f0e6f5984ae16f0ca4fd76aac Mon Sep 17 00:00:00 2001 From: Ferry Toth Date: Mon, 5 Dec 2022 21:15:26 +0100 Subject: [PATCH 1363/1480] usb: ulpi: defer ulpi_register on ulpi_read_id timeout Since commit 0f0101719138 ("usb: dwc3: Don't switch OTG -> peripheral if extcon is present") Dual Role support on Intel Merrifield platform broke due to rearranging the call to dwc3_get_extcon(). It appears to be caused by ulpi_read_id() on the first test write failing with -ETIMEDOUT. Currently ulpi_read_id() expects to discover the phy via DT when the test write fails and returns 0 in that case, even if DT does not provide the phy. As a result usb probe completes without phy. Make ulpi_read_id() return -ETIMEDOUT to its user if the first test write fails. The user should then handle it appropriately. A follow up patch will make dwc3_core_init() set -EPROBE_DEFER in this case and bail out. Fixes: ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT") Cc: stable@vger.kernel.org Acked-by: Heikki Krogerus Signed-off-by: Ferry Toth Link: https://lore.kernel.org/r/20221205201527.13525-2-ftoth@exalondelft.nl Signed-off-by: Greg Kroah-Hartman --- drivers/usb/common/ulpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index d7c8461976ce0..60e8174686a17 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -207,7 +207,7 @@ static int ulpi_read_id(struct ulpi *ulpi) /* Test the interface */ ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); if (ret < 0) - goto err; + return ret; ret = ulpi_read(ulpi, ULPI_SCRATCH); if (ret < 0) -- GitLab From 63130462c919ece0ad0d9bb5a1f795ef8d79687e Mon Sep 17 00:00:00 2001 From: Ferry Toth Date: Mon, 5 Dec 2022 21:15:27 +0100 Subject: [PATCH 1364/1480] usb: dwc3: core: defer probe on ulpi_read_id timeout Since commit 0f0101719138 ("usb: dwc3: Don't switch OTG -> peripheral if extcon is present"), Dual Role support on Intel Merrifield platform broke due to rearranging the call to dwc3_get_extcon(). It appears to be caused by ulpi_read_id() masking the timeout on the first test write. In the past dwc3 probe continued by calling dwc3_core_soft_reset() followed by dwc3_get_extcon() which happend to return -EPROBE_DEFER. On deferred probe ulpi_read_id() finally succeeded. Due to above mentioned rearranging -EPROBE_DEFER is not returned and probe completes without phy. On Intel Merrifield the timeout on the first test write issue is reproducible but it is difficult to find the root cause. Using a mainline kernel and rootfs with buildroot ulpi_read_id() succeeds. As soon as adding ftrace / bootconfig to find out why, ulpi_read_id() fails and we can't analyze the flow. Using another rootfs ulpi_read_id() fails even without adding ftrace. We suspect the issue is some kind of timing / race, but merely retrying ulpi_read_id() does not resolve the issue. As we now changed ulpi_read_id() to return -ETIMEDOUT in this case, we need to handle the error by calling dwc3_core_soft_reset() and request -EPROBE_DEFER. On deferred probe ulpi_read_id() is retried and succeeds. Fixes: ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT") Cc: stable@vger.kernel.org Acked-by: Thinh Nguyen Signed-off-by: Ferry Toth Link: https://lore.kernel.org/r/20221205201527.13525-3-ftoth@exalondelft.nl Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fc38a8b13efa6..476b636185116 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1100,8 +1100,13 @@ static int dwc3_core_init(struct dwc3 *dwc) if (!dwc->ulpi_ready) { ret = dwc3_core_ulpi_init(dwc); - if (ret) + if (ret) { + if (ret == -ETIMEDOUT) { + dwc3_core_soft_reset(dwc); + ret = -EPROBE_DEFER; + } goto err0; + } dwc->ulpi_ready = true; } -- GitLab From 2a81a7aa420b80865fdd82ec383fe365e18f922b Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Sun, 27 Nov 2022 12:41:36 +0100 Subject: [PATCH 1365/1480] dt-bindings: usb: mtk-xhci: add support for mt7986 Add compatible string for mt7986. Signed-off-by: Frank Wunderlich Acked-by: Krzysztof Kozlowski Reviewed-by: Chunfeng Yun Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Matthias Brugger Link: https://lore.kernel.org/r/20221127114142.156573-3-linux@fw-web.de Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml index 939623867a646..a3c37944c6305 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml @@ -28,6 +28,7 @@ properties: - mediatek,mt7622-xhci - mediatek,mt7623-xhci - mediatek,mt7629-xhci + - mediatek,mt7986-xhci - mediatek,mt8173-xhci - mediatek,mt8183-xhci - mediatek,mt8186-xhci -- GitLab From 42a317d076b58f08413219b1679d211783c2e5f3 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 7 Dec 2022 14:19:16 +0100 Subject: [PATCH 1366/1480] usb: dwc2: disable lpm feature on Rockchip SoCs LPM feature of DWC2 module integrated in Rockchip SoCs doesn't work properly or needs some additional handling, so disable it for now. Without disabling LPM feature, the USB ADB communication fail with the following error log: dwc2 ff580000.usb: new address 27 dwc2 ff580000.usb: Failed to exit L1 sleep state in 200us. dwc2 ff580000.usb: dwc2_hsotg_send_reply: cannot queue req dwc2 ff580000.usb: dwc2_hsotg_process_req_status: failed to send reply dwc2 ff580000.usb: dwc2_hsotg_enqueue_setup: failed queue (-11) dwc2 ff580000.usb: Failed to exit L1 sleep state in 200us. [diff vs vendor kernel: added lpm_clock_gating, besl and hird_threshold_en settings as seen in commit 53febc956900 ("usb: dwc2: disable Link Power Management on STM32MP15 HS OTG")] Signed-off-by: William Wu Signed-off-by: Frank Wang Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20221206-dwc2-gadget-dual-role-v1-1-36515e1092cd@theobroma-systems.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/params.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 8eab5f38b1101..9ed9fd9569404 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -113,6 +113,10 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg) p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT; p->power_down = DWC2_POWER_DOWN_PARAM_NONE; + p->lpm = false; + p->lpm_clock_gating = false; + p->besl = false; + p->hird_threshold_en = false; } static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg) -- GitLab From ade23d7b7ec5c38bd43ec44ccb753cb7ea8ac08a Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 7 Dec 2022 14:19:17 +0100 Subject: [PATCH 1367/1480] usb: dwc2: power on/off phy for peripheral mode in dual-role mode The PHY power is handled for peripheral mode but only when the device is forced into this peripheral mode. It is missing when the device is operating in peripheral mode when dual-role mode is enabled, so let's update the condition to match this scenario. Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20221206-dwc2-gadget-dual-role-v1-2-36515e1092cd@theobroma-systems.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/gadget.c | 6 ++++-- drivers/usb/dwc2/platform.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8b15742d9e8aa..62fa6378d2d73 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4549,7 +4549,8 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed = USB_SPEED_UNKNOWN; - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || + (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) { ret = dwc2_lowlevel_hw_enable(hsotg); if (ret) goto err; @@ -4611,7 +4612,8 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) if (!IS_ERR_OR_NULL(hsotg->uphy)) otg_set_peripheral(hsotg->uphy->otg, NULL); - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || + (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) dwc2_lowlevel_hw_disable(hsotg); return 0; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 262c13b6362ac..23ef759968231 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -576,7 +576,8 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_debugfs_init(hsotg); /* Gadget code manages lowlevel hw on its own */ - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || + (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) dwc2_lowlevel_hw_disable(hsotg); #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ -- GitLab From 0bf588274f73b29d7058042a6b7cc2b764502cc1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Nov 2022 17:51:21 +0100 Subject: [PATCH 1368/1480] Fix path in cifs/usage.rst /sys/module/... not /proc/module/... Signed-off-by: Volker Lendecke Signed-off-by: Steve French --- Documentation/admin-guide/cifs/usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/admin-guide/cifs/usage.rst b/Documentation/admin-guide/cifs/usage.rst index 3766bf8a1c20e..ed3b8dc854ecf 100644 --- a/Documentation/admin-guide/cifs/usage.rst +++ b/Documentation/admin-guide/cifs/usage.rst @@ -858,7 +858,7 @@ CIFS kernel module parameters These module parameters can be specified or modified either during the time of module loading or during the runtime by using the interface:: - /proc/module/cifs/parameters/ + /sys/module/cifs/parameters/ i.e.:: -- GitLab From 83fb8abec29383eb0cf35495d21669e38548771b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Nov 2022 12:26:00 +0100 Subject: [PATCH 1369/1480] cifs: Add "extbuf" and "extbuflen" args to smb2_compound_op() Will carry the variable-sized reply from SMB_FIND_FILE_POSIX_INFO Signed-off-by: Volker Lendecke Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/smb2inode.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 68e08c85fbb87..1be86ba950b35 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -59,6 +59,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, __u32 desired_access, __u32 create_disposition, __u32 create_options, umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile, + __u8 **extbuf, size_t *extbuflen, struct kvec *err_iov, int *err_buftype) { struct cop_vars *vars = NULL; @@ -539,7 +540,7 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile, - err_iov, err_buftype); + NULL, NULL, err_iov, err_buftype); if (rc == -EOPNOTSUPP) { if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE && @@ -555,7 +556,7 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, - SMB2_OP_QUERY_INFO, cfile, NULL, NULL); + SMB2_OP_QUERY_INFO, cfile, NULL, NULL, NULL, NULL); } out: @@ -589,7 +590,7 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, - err_iov, err_buftype); + NULL, NULL, err_iov, err_buftype); if (rc == -EOPNOTSUPP) { /* BB TODO: When support for special files added to Samba re-verify this path */ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && @@ -606,7 +607,7 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, - SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL); + SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL, NULL, NULL); } out: @@ -624,7 +625,7 @@ smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, return smb2_compound_op(xid, tcon, cifs_sb, name, FILE_WRITE_ATTRIBUTES, FILE_CREATE, CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); } void @@ -646,7 +647,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, FILE_WRITE_ATTRIBUTES, FILE_CREATE, CREATE_NOT_FILE, ACL_NO_MODE, - &data, SMB2_OP_SET_INFO, cfile, NULL, NULL); + &data, SMB2_OP_SET_INFO, cfile, NULL, NULL, NULL, NULL); if (tmprc == 0) cifs_i->cifsAttrs = dosattrs; } @@ -658,7 +659,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, drop_cached_dir_by_name(xid, tcon, name, cifs_sb); return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, CREATE_NOT_FILE, ACL_NO_MODE, - NULL, SMB2_OP_RMDIR, NULL, NULL, NULL); + NULL, SMB2_OP_RMDIR, NULL, NULL, NULL, NULL, NULL); } int @@ -667,7 +668,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, { return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, - ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL); + ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL, NULL, NULL); } static int @@ -686,7 +687,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, } rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name, - command, cfile, NULL, NULL); + command, cfile, NULL, NULL, NULL, NULL); smb2_rename_path: kfree(smb2_to_name); return rc; @@ -727,7 +728,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); return smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE, - &eof, SMB2_OP_SET_EOF, cfile, NULL, NULL); + &eof, SMB2_OP_SET_EOF, cfile, NULL, NULL, NULL, NULL); } int @@ -754,7 +755,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path, rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile, - NULL, NULL); + NULL, NULL, NULL, NULL); cifs_put_tlink(tlink); return rc; } -- GitLab From 64ce47cb1b29d7d6aab6dcc287ae1fddb4876bd5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Nov 2022 12:37:44 +0100 Subject: [PATCH 1370/1480] cifs: Parse owner/group for stat in smb311 posix extensions stat was returning default owner and group (unlike readdir) for SMB3.1.1 POSIX extensions Signed-off-by: Volker Lendecke Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/inode.c | 13 ++++++++---- fs/cifs/smb2inode.c | 49 ++++++++++++++++++++++++++++++++++++++++++--- fs/cifs/smb2proto.h | 5 ++++- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 4e2ca3c6e5c00..286a5400b94e5 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -632,6 +632,8 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, /* Fill a cifs_fattr struct with info from POSIX info struct */ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, + struct cifs_sid *owner, + struct cifs_sid *group, struct super_block *sb, bool adjust_tz, bool symlink) { struct smb311_posix_qinfo *info = &data->posix_fi; @@ -680,8 +682,8 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope } /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */ - fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */ - fattr->cf_gid = cifs_sb->ctx->linux_gid; + sid_to_id(cifs_sb, owner, fattr, SIDOWNER); + sid_to_id(cifs_sb, group, fattr, SIDGROUP); cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n", fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); @@ -1175,6 +1177,7 @@ smb311_posix_get_inode_info(struct inode **inode, struct cifs_fattr fattr = {0}; bool symlink = false; struct cifs_open_info_data data = {}; + struct cifs_sid owner, group; int rc = 0; int tmprc = 0; @@ -1192,7 +1195,8 @@ smb311_posix_get_inode_info(struct inode **inode, goto out; } - rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz, + rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, + &owner, &group, &adjust_tz, &symlink); /* @@ -1201,7 +1205,8 @@ smb311_posix_get_inode_info(struct inode **inode, switch (rc) { case 0: - smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink); + smb311_posix_info_to_fattr(&fattr, &data, &owner, &group, + sb, adjust_tz, symlink); break; case -EREMOTE: /* DFS link, no metadata available on this server */ diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 1be86ba950b35..fbd46db1023ae 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -431,6 +431,21 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, &rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */, (char *)&idata->posix_fi); } + if (rc == 0) { + unsigned int length = le32_to_cpu(qi_rsp->OutputBufferLength); + + if (length > sizeof(idata->posix_fi)) { + char *base = (char *)rsp_iov[1].iov_base + + le16_to_cpu(qi_rsp->OutputBufferOffset) + + sizeof(idata->posix_fi); + *extbuflen = length - sizeof(idata->posix_fi); + *extbuf = kmemdup(base, *extbuflen, GFP_KERNEL); + if (!*extbuf) + rc = -ENOMEM; + } else { + rc = -EINVAL; + } + } if (rqst[1].rq_iov) SMB2_query_info_free(&rqst[1]); if (rqst[2].rq_iov) @@ -569,13 +584,20 @@ out: int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse) + struct cifs_open_info_data *data, + struct cifs_sid *owner, + struct cifs_sid *group, + bool *adjust_tz, bool *reparse) { int rc; __u32 create_options = 0; struct cifsFileInfo *cfile; struct kvec err_iov[3] = {}; int err_buftype[3] = {}; + __u8 *sidsbuf = NULL; + __u8 *sidsbuf_end = NULL; + size_t sidsbuflen = 0; + size_t owner_len, group_len; *adjust_tz = false; *reparse = false; @@ -590,7 +612,7 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, - NULL, NULL, err_iov, err_buftype); + &sidsbuf, &sidsbuflen, err_iov, err_buftype); if (rc == -EOPNOTSUPP) { /* BB TODO: When support for special files added to Samba re-verify this path */ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && @@ -607,10 +629,31 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, - SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL, NULL, NULL); + SMB2_OP_POSIX_QUERY_INFO, cfile, + &sidsbuf, &sidsbuflen, NULL, NULL); + } + + if (rc == 0) { + sidsbuf_end = sidsbuf + sidsbuflen; + + owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end); + if (owner_len == -1) { + rc = -EINVAL; + goto out; + } + memcpy(owner, sidsbuf, owner_len); + + group_len = posix_info_sid_size( + sidsbuf + owner_len, sidsbuf_end); + if (group_len == -1) { + rc = -EINVAL; + goto out; + } + memcpy(group, sidsbuf + owner_len, group_len); } out: + kfree(sidsbuf); free_rsp_buf(err_buftype[0], err_iov[0].iov_base); free_rsp_buf(err_buftype[1], err_iov[1].iov_base); free_rsp_buf(err_buftype[2], err_iov[2].iov_base); diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index be21b5d26f67e..d5d7ffb7711c4 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -277,7 +277,10 @@ extern int smb2_query_info_compound(const unsigned int xid, /* query path info from the server using SMB311 POSIX extensions*/ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); + struct cifs_open_info_data *data, + struct cifs_sid *owner, + struct cifs_sid *group, + bool *adjust_tz, bool *reparse); int posix_info_parse(const void *beg, const void *end, struct smb2_posix_info_parsed *out); int posix_info_sid_size(const void *beg, const void *end); -- GitLab From 9381666e289852f93be9d7f4f7844017e04f6315 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 16 Nov 2022 14:18:33 +0100 Subject: [PATCH 1371/1480] cifs: wire up >migrate_folio CIFS does not use page private data that needs migration, so it can just wire up filemap_migrate_folio. This prepares for removing ->writepage, which is used as a fallback if no migrate_folio method is set. Signed-off-by: Christoph Hellwig Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/file.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cd96982099309..6be924caed393 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -5240,10 +5240,10 @@ const struct address_space_operations cifs_addr_ops = { .direct_IO = cifs_direct_io, .invalidate_folio = cifs_invalidate_folio, .launder_folio = cifs_launder_folio, + .migrate_folio = filemap_migrate_folio, /* - * TODO: investigate and if useful we could add an cifs_migratePage - * helper (under an CONFIG_MIGRATION) in the future, and also - * investigate and add an is_dirty_writeback helper if needed + * TODO: investigate and if useful we could add an is_dirty_writeback + * helper if needed */ .swap_activate = cifs_swap_activate, .swap_deactivate = cifs_swap_deactivate, @@ -5264,4 +5264,5 @@ const struct address_space_operations cifs_addr_ops_smallbuf = { .release_folio = cifs_release_folio, .invalidate_folio = cifs_invalidate_folio, .launder_folio = cifs_launder_folio, + .migrate_folio = filemap_migrate_folio, }; -- GitLab From bff9018d3a52c45711bd63c446a2c80c0275e935 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 16 Nov 2022 14:18:34 +0100 Subject: [PATCH 1372/1480] cifs: stop using generic_writepages generic_writepages is just a wrapper that calls ->writepages on a range, and thus in the way of eventually removing ->writepage. Switch cifs to just open code it in preparation of removing ->writepage. [note: I suspect just integrating the small wsize case with the rest of the writeback code might be a better idea here, but that needs someone more familiar with the code] Signed-off-by: Christoph Hellwig Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/file.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6be924caed393..ec14e38411a13 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2646,6 +2646,21 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, return rc; } +static int +cifs_writepage_locked(struct page *page, struct writeback_control *wbc); + +static int cifs_write_one_page(struct page *page, struct writeback_control *wbc, + void *data) +{ + struct address_space *mapping = data; + int ret; + + ret = cifs_writepage_locked(page, wbc); + unlock_page(page); + mapping_set_error(mapping, ret); + return ret; +} + static int cifs_writepages(struct address_space *mapping, struct writeback_control *wbc) { @@ -2662,10 +2677,11 @@ static int cifs_writepages(struct address_space *mapping, /* * If wsize is smaller than the page cache size, default to writing - * one page at a time via cifs_writepage + * one page at a time. */ if (cifs_sb->ctx->wsize < PAGE_SIZE) - return generic_writepages(mapping, wbc); + return write_cache_pages(mapping, wbc, cifs_write_one_page, + mapping); xid = get_xid(); if (wbc->range_cyclic) { -- GitLab From ebaad77c89921c8237ca17791d5462bd289052d0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 16 Nov 2022 14:18:35 +0100 Subject: [PATCH 1373/1480] cifs: remove ->writepage ->writepage is a very inefficient method to write back data, and only used through write_cache_pages or a a fallback when no ->migrate_folio method is present. Now that cifs implements ->migrate_folio and doesn't call generic_writepages, the writepage method can be removed. Signed-off-by: Christoph Hellwig Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/file.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ec14e38411a13..6701257541ab2 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2868,13 +2868,6 @@ retry_write: return rc; } -static int cifs_writepage(struct page *page, struct writeback_control *wbc) -{ - int rc = cifs_writepage_locked(page, wbc); - unlock_page(page); - return rc; -} - static int cifs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) @@ -5247,7 +5240,6 @@ static bool cifs_dirty_folio(struct address_space *mapping, struct folio *folio) const struct address_space_operations cifs_addr_ops = { .read_folio = cifs_read_folio, .readahead = cifs_readahead, - .writepage = cifs_writepage, .writepages = cifs_writepages, .write_begin = cifs_write_begin, .write_end = cifs_write_end, @@ -5272,7 +5264,6 @@ const struct address_space_operations cifs_addr_ops = { */ const struct address_space_operations cifs_addr_ops_smallbuf = { .read_folio = cifs_read_folio, - .writepage = cifs_writepage, .writepages = cifs_writepages, .write_begin = cifs_write_begin, .write_end = cifs_write_end, -- GitLab From d406d26745aba3365ab9171b2d5cbea9c1757305 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Mon, 5 Dec 2022 23:31:53 -0300 Subject: [PATCH 1374/1480] cifs: skip alloc when request has no pages When smb3_init_transform_rq() was being called with requests (@old_rq) which had no pages, it was unnecessarily allocating a single page for every request in @new_rq. Fix this by skipping page array allocation when requests have no pages (e.g. !smb_rqst::rq_npages). Also get rid of deprecated kmap() and use kmap_local_page() instead while we're at it. Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index bfaafd02fb1f2..72b22d033ed56 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4445,21 +4445,27 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, int rc = -ENOMEM; for (i = 1; i < num_rqst; i++) { - npages = old_rq[i - 1].rq_npages; + struct smb_rqst *old = &old_rq[i - 1]; + struct smb_rqst *new = &new_rq[i]; + + orig_len += smb_rqst_len(server, old); + new->rq_iov = old->rq_iov; + new->rq_nvec = old->rq_nvec; + + npages = old->rq_npages; + if (!npages) + continue; + pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!pages) goto err_free; - new_rq[i].rq_pages = pages; - new_rq[i].rq_npages = npages; - new_rq[i].rq_offset = old_rq[i - 1].rq_offset; - new_rq[i].rq_pagesz = old_rq[i - 1].rq_pagesz; - new_rq[i].rq_tailsz = old_rq[i - 1].rq_tailsz; - new_rq[i].rq_iov = old_rq[i - 1].rq_iov; - new_rq[i].rq_nvec = old_rq[i - 1].rq_nvec; - - orig_len += smb_rqst_len(server, &old_rq[i - 1]); + new->rq_pages = pages; + new->rq_npages = npages; + new->rq_offset = old->rq_offset; + new->rq_pagesz = old->rq_pagesz; + new->rq_tailsz = old->rq_tailsz; for (j = 0; j < npages; j++) { pages[j] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); @@ -4472,14 +4478,14 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, char *dst, *src; unsigned int offset, len; - rqst_page_get_length(&new_rq[i], j, &len, &offset); + rqst_page_get_length(new, j, &len, &offset); - dst = (char *) kmap(new_rq[i].rq_pages[j]) + offset; - src = (char *) kmap(old_rq[i - 1].rq_pages[j]) + offset; + dst = kmap_local_page(new->rq_pages[j]) + offset; + src = kmap_local_page(old->rq_pages[j]) + offset; memcpy(dst, src, len); - kunmap(new_rq[i].rq_pages[j]); - kunmap(old_rq[i - 1].rq_pages[j]); + kunmap(new->rq_pages[j]); + kunmap(old->rq_pages[j]); } } -- GitLab From 81c25247a2a03a0f97e4805d7aff7541ccff6baa Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Tue, 6 Dec 2022 16:12:03 +0000 Subject: [PATCH 1375/1480] usb: gadget: uvc: Rename bmInterfaceFlags -> bmInterlaceFlags In the specification documents for the Uncompressed and MJPEG USB Video Payloads, the field name is bmInterlaceFlags - it has been misnamed within the kernel. Although renaming the field does break the kernel's interface to userspace it should be low-risk in this instance. The field is read only and hardcoded to 0, so there was never any value in anyone reading it. A search of the uvc-gadget application and all the forks that I could find for it did not reveal any users either. Fixes: cdda479f15cd ("USB gadget: video class function driver") Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Daniel Scally Link: https://lore.kernel.org/r/20221206161203.1562827-1-dan.scally@ideasonboard.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/configfs-usb-gadget-uvc | 4 ++-- drivers/usb/gadget/function/uvc_configfs.c | 12 ++++++------ drivers/usb/gadget/legacy/webcam.c | 4 ++-- include/uapi/linux/usb/video.h | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc index 611b23e6488d9..f00cff6d8c5cb 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uvc +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc @@ -197,7 +197,7 @@ Description: Specific MJPEG format descriptors read-only bmaControls this format's data for bmaControls in the streaming header - bmInterfaceFlags specifies interlace information, + bmInterlaceFlags specifies interlace information, read-only bAspectRatioY the X dimension of the picture aspect ratio, read-only @@ -253,7 +253,7 @@ Description: Specific uncompressed format descriptors read-only bmaControls this format's data for bmaControls in the streaming header - bmInterfaceFlags specifies interlace information, + bmInterlaceFlags specifies interlace information, read-only bAspectRatioY the X dimension of the picture aspect ratio, read-only diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 4303a3283ba0a..76cb60d13049f 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -1512,7 +1512,7 @@ UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8); UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); -UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); +UVCG_UNCOMPRESSED_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8); #undef UVCG_UNCOMPRESSED_ATTR #undef UVCG_UNCOMPRESSED_ATTR_RO @@ -1541,7 +1541,7 @@ static struct configfs_attribute *uvcg_uncompressed_attrs[] = { &uvcg_uncompressed_attr_b_default_frame_index, &uvcg_uncompressed_attr_b_aspect_ratio_x, &uvcg_uncompressed_attr_b_aspect_ratio_y, - &uvcg_uncompressed_attr_bm_interface_flags, + &uvcg_uncompressed_attr_bm_interlace_flags, &uvcg_uncompressed_attr_bma_controls, NULL, }; @@ -1574,7 +1574,7 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group, h->desc.bDefaultFrameIndex = 1; h->desc.bAspectRatioX = 0; h->desc.bAspectRatioY = 0; - h->desc.bmInterfaceFlags = 0; + h->desc.bmInterlaceFlags = 0; h->desc.bCopyProtect = 0; INIT_LIST_HEAD(&h->fmt.frames); @@ -1700,7 +1700,7 @@ UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8); UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); -UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); +UVCG_MJPEG_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8); #undef UVCG_MJPEG_ATTR #undef UVCG_MJPEG_ATTR_RO @@ -1728,7 +1728,7 @@ static struct configfs_attribute *uvcg_mjpeg_attrs[] = { &uvcg_mjpeg_attr_bm_flags, &uvcg_mjpeg_attr_b_aspect_ratio_x, &uvcg_mjpeg_attr_b_aspect_ratio_y, - &uvcg_mjpeg_attr_bm_interface_flags, + &uvcg_mjpeg_attr_bm_interlace_flags, &uvcg_mjpeg_attr_bma_controls, NULL, }; @@ -1755,7 +1755,7 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group, h->desc.bDefaultFrameIndex = 1; h->desc.bAspectRatioX = 0; h->desc.bAspectRatioY = 0; - h->desc.bmInterfaceFlags = 0; + h->desc.bmInterlaceFlags = 0; h->desc.bCopyProtect = 0; INIT_LIST_HEAD(&h->fmt.frames); diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index 94e22867da1d0..53e38f87472b0 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -171,7 +171,7 @@ static const struct uvc_format_uncompressed uvc_format_yuv = { .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, - .bmInterfaceFlags = 0, + .bmInterlaceFlags = 0, .bCopyProtect = 0, }; @@ -222,7 +222,7 @@ static const struct uvc_format_mjpeg uvc_format_mjpg = { .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, - .bmInterfaceFlags = 0, + .bmInterlaceFlags = 0, .bCopyProtect = 0, }; diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index bfdae12cdacf8..6e8e572c2980a 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -466,7 +466,7 @@ struct uvc_format_uncompressed { __u8 bDefaultFrameIndex; __u8 bAspectRatioX; __u8 bAspectRatioY; - __u8 bmInterfaceFlags; + __u8 bmInterlaceFlags; __u8 bCopyProtect; } __attribute__((__packed__)); @@ -522,7 +522,7 @@ struct uvc_format_mjpeg { __u8 bDefaultFrameIndex; __u8 bAspectRatioX; __u8 bAspectRatioY; - __u8 bmInterfaceFlags; + __u8 bmInterlaceFlags; __u8 bCopyProtect; } __attribute__((__packed__)); -- GitLab From c7912f27dedd874d49eadf78b5b6fbfdec52c7c3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 7 Dec 2022 09:33:31 +0000 Subject: [PATCH 1376/1480] staging: rtl8192e: Fix spelling mistake "ContryIE" -> "CountryIE" There is a spelling mistake in a netdev_info message. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221207093331.2280355-1-colin.i.king@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index f8965afab7678..669e74a67190d 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1776,7 +1776,7 @@ static inline void rtllib_extract_country_ie( if (rtllib_act_scanning(ieee, false) && ieee->FirstIe_InScan) netdev_info(ieee->dev, - "Received beacon ContryIE, SSID: <%s>\n", + "Received beacon CountryIE, SSID: <%s>\n", network->ssid); dot11d_update_country(ieee, addr2, info_element->len, -- GitLab From 37aa6b98237082a4bf882b4d986329b94ebd447d Mon Sep 17 00:00:00 2001 From: Chen Zhongjin Date: Tue, 6 Dec 2022 09:50:33 +0800 Subject: [PATCH 1377/1480] vme: Use root_device_register() not underlined version root_device_register and __root_device_register have exactly same effect. Use the not underlined version to keep usage consistency. Signed-off-by: Chen Zhongjin Link: https://lore.kernel.org/r/20221206015033.125827-1-chenzhongjin@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme_user/vme_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index 6454ccf6e5b4b..f5d2c345978ac 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -1069,7 +1069,7 @@ static int __init fake_init(void) struct vme_lm_resource *lm; /* We need a fake parent device */ - vme_root = __root_device_register("vme", THIS_MODULE); + vme_root = root_device_register("vme"); if (IS_ERR(vme_root)) return PTR_ERR(vme_root); -- GitLab From fd3dc56253acbe9c641a66d312d8393cd55eb04c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Fri, 9 Dec 2022 10:52:47 -0500 Subject: [PATCH 1378/1480] ftrace/x86: Add back ftrace_expected for ftrace bug reports After someone reported a bug report with a failed modification due to the expected value not matching what was found, it came to my attention that the ftrace_expected is no longer set when that happens. This makes for debugging the issue a bit more difficult. Set ftrace_expected to the expected code before calling ftrace_bug, so that it shows what was expected and why it failed. Link: https://lore.kernel.org/all/CA+wXwBQ-VhK+hpBtYtyZP-NiX4g8fqRRWithFOHQW-0coQ3vLg@mail.gmail.com/ Link: https://lore.kernel.org/linux-trace-kernel/20221209105247.01d4e51d@gandalf.local.home Cc: Masami Hiramatsu Cc: Andrew Morton Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: "x86@kernel.org" Cc: Borislav Petkov Cc: Ingo Molnar Cc: stable@vger.kernel.org Fixes: 768ae4406a5c ("x86/ftrace: Use text_poke()") Signed-off-by: Steven Rostedt (Google) --- arch/x86/kernel/ftrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index bd165004776d9..e07234ec7e237 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -217,7 +217,9 @@ void ftrace_replace_code(int enable) ret = ftrace_verify_code(rec->ip, old); if (ret) { + ftrace_expected = old; ftrace_bug(ret, rec); + ftrace_expected = NULL; return; } } -- GitLab From 5f2e094ed2592abb3d1f49e263957188e121c2ac Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Thu, 20 Oct 2022 00:31:55 +0900 Subject: [PATCH 1379/1480] tracing: Allow multiple hitcount values in histograms The hitcount is treated specially in the histograms - since it's always expected to be there regardless of whether the user specified anything or not, it's always added as the first histogram value. Currently the code doesn't allow it to be added more than once as a value, which is inconsistent with all the other possible values. It would seem to be a pointless thing to want to do, but other features being added such as percent and graph modifiers don't work properly with the current hitcount restrictions. Fix this by allowing multiple hitcounts to be added. Link: https://lore.kernel.org/linux-trace-kernel/166610812248.56030.16754785928712505251.stgit@devnote2 Signed-off-by: Tom Zanussi Signed-off-by: Masami Hiramatsu (Google) Tested-by: Tom Zanussi --- kernel/trace/trace_events_hist.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 1c82478e8dffe..31d58ddcc1d9e 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -1356,6 +1356,8 @@ static const char *hist_field_name(struct hist_field *field, field_name = field->name; } else if (field->flags & HIST_FIELD_FL_TIMESTAMP) field_name = "common_timestamp"; + else if (field->flags & HIST_FIELD_FL_HITCOUNT) + field_name = "hitcount"; if (field_name == NULL) field_name = ""; @@ -2328,6 +2330,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, hist_data->attrs->ts_in_usecs = true; } else if (strcmp(field_name, "common_cpu") == 0) *flags |= HIST_FIELD_FL_CPU; + else if (strcmp(field_name, "hitcount") == 0) + *flags |= HIST_FIELD_FL_HITCOUNT; else { field = trace_find_event_field(file->event_call, field_name); if (!field || !field->size) { @@ -4328,8 +4332,8 @@ static int create_var_field(struct hist_trigger_data *hist_data, static int create_val_fields(struct hist_trigger_data *hist_data, struct trace_event_file *file) { + unsigned int i, j = 1, n_hitcount = 0; char *fields_str, *field_str; - unsigned int i, j = 1; int ret; ret = create_hitcount_val(hist_data); @@ -4346,8 +4350,10 @@ static int create_val_fields(struct hist_trigger_data *hist_data, if (!field_str) break; - if (strcmp(field_str, "hitcount") == 0) - continue; + if (strcmp(field_str, "hitcount") == 0) { + if (!n_hitcount++) + continue; + } ret = create_val_field(hist_data, j++, file, field_str); if (ret) -- GitLab From abaa5258ce5e5887a9de049f50a85dc023391a1c Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 20 Oct 2022 00:31:55 +0900 Subject: [PATCH 1380/1480] tracing: Add .percent suffix option to histogram values Add .percent suffix option to show the histogram values in percentage. This feature is useful when we need yo undersntand the overall trend for the histograms of large values. E.g. this shows the runtime percentage for each tasks. ------ # cd /sys/kernel/debug/tracing/ # echo hist:keys=pid:vals=hitcount,runtime.percent:sort=pid > \ events/sched/sched_stat_runtime/trigger # sleep 10 # cat events/sched/sched_stat_runtime/hist # event histogram # # trigger info: hist:keys=pid:vals=hitcount,runtime.percent:sort=pid:size=2048 [active] # { pid: 8 } hitcount: 7 runtime (%): 4.14 { pid: 14 } hitcount: 5 runtime (%): 3.69 { pid: 16 } hitcount: 11 runtime (%): 3.41 { pid: 61 } hitcount: 41 runtime (%): 19.75 { pid: 65 } hitcount: 4 runtime (%): 1.48 { pid: 70 } hitcount: 6 runtime (%): 3.60 { pid: 72 } hitcount: 2 runtime (%): 1.10 { pid: 144 } hitcount: 10 runtime (%): 32.01 { pid: 151 } hitcount: 8 runtime (%): 22.66 { pid: 152 } hitcount: 2 runtime (%): 8.10 Totals: Hits: 96 Entries: 10 Dropped: 0 ----- Link: https://lore.kernel.org/linux-trace-kernel/166610813077.56030.4238090506973562347.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Tested-by: Tom Zanussi --- kernel/trace/trace.c | 3 +- kernel/trace/trace_events_hist.c | 90 +++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 93a75a97118f1..08e9568849b1a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5724,7 +5724,8 @@ static const char readme_msg[] = "\t .syscall display a syscall id as a syscall name\n" "\t .log2 display log2 value rather than raw number\n" "\t .buckets=size display values in groups of size rather than raw number\n" - "\t .usecs display a common_timestamp in microseconds\n\n" + "\t .usecs display a common_timestamp in microseconds\n" + "\t .percent display a number of percentage value\n\n" "\t The 'pause' parameter can be used to pause an existing hist\n" "\t trigger or to start a hist trigger but not log any events\n" "\t until told to do so. 'continue' can be used to start or\n" diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 31d58ddcc1d9e..35b0e956f06ef 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -506,6 +506,7 @@ enum hist_field_flags { HIST_FIELD_FL_ALIAS = 1 << 16, HIST_FIELD_FL_BUCKET = 1 << 17, HIST_FIELD_FL_CONST = 1 << 18, + HIST_FIELD_FL_PERCENT = 1 << 19, }; struct var_defs { @@ -1707,6 +1708,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) flags_str = "buckets"; else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS) flags_str = "usecs"; + else if (hist_field->flags & HIST_FIELD_FL_PERCENT) + flags_str = "percent"; return flags_str; } @@ -2315,6 +2318,10 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, if (ret || !(*buckets)) goto error; *flags |= HIST_FIELD_FL_BUCKET; + } else if (strncmp(modifier, "percent", 7) == 0) { + if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY)) + goto error; + *flags |= HIST_FIELD_FL_PERCENT; } else { error: hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier)); @@ -5291,33 +5298,69 @@ static void hist_trigger_print_key(struct seq_file *m, seq_puts(m, "}"); } +/* Get the 100 times of the percentage of @val in @total */ +static inline unsigned int __get_percentage(u64 val, u64 total) +{ + if (!total) + goto div0; + + if (val < (U64_MAX / 10000)) + return (unsigned int)div64_ul(val * 10000, total); + + total = div64_u64(total, 10000); + if (!total) + goto div0; + + return (unsigned int)div64_ul(val, total); +div0: + return val ? UINT_MAX : 0; +} + +static void hist_trigger_print_val(struct seq_file *m, unsigned int idx, + const char *field_name, unsigned long flags, + u64 *totals, struct tracing_map_elt *elt) +{ + u64 val = tracing_map_read_sum(elt, idx); + unsigned int pc; + + if (flags & HIST_FIELD_FL_PERCENT) { + pc = __get_percentage(val, totals[idx]); + if (pc == UINT_MAX) + seq_printf(m, " %s (%%):[ERROR]", field_name); + else + seq_printf(m, " %s (%%): %3u.%02u", field_name, + pc / 100, pc % 100); + } else if (flags & HIST_FIELD_FL_HEX) { + seq_printf(m, " %s: %10llx", field_name, val); + } else { + seq_printf(m, " %s: %10llu", field_name, val); + } +} + static void hist_trigger_entry_print(struct seq_file *m, struct hist_trigger_data *hist_data, + u64 *totals, void *key, struct tracing_map_elt *elt) { const char *field_name; - unsigned int i; + unsigned int i = HITCOUNT_IDX; + unsigned long flags; hist_trigger_print_key(m, hist_data, key, elt); - seq_printf(m, " hitcount: %10llu", - tracing_map_read_sum(elt, HITCOUNT_IDX)); + /* At first, show the raw hitcount always */ + hist_trigger_print_val(m, i, "hitcount", 0, totals, elt); for (i = 1; i < hist_data->n_vals; i++) { field_name = hist_field_name(hist_data->fields[i], 0); + flags = hist_data->fields[i]->flags; - if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR || - hist_data->fields[i]->flags & HIST_FIELD_FL_EXPR) + if (flags & HIST_FIELD_FL_VAR || flags & HIST_FIELD_FL_EXPR) continue; - if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) { - seq_printf(m, " %s: %10llx", field_name, - tracing_map_read_sum(elt, i)); - } else { - seq_printf(m, " %s: %10llu", field_name, - tracing_map_read_sum(elt, i)); - } + seq_puts(m, " "); + hist_trigger_print_val(m, i, field_name, flags, totals, elt); } print_actions(m, hist_data, elt); @@ -5330,7 +5373,8 @@ static int print_entries(struct seq_file *m, { struct tracing_map_sort_entry **sort_entries = NULL; struct tracing_map *map = hist_data->map; - int i, n_entries; + int i, j, n_entries; + u64 *totals = NULL; n_entries = tracing_map_sort_entries(map, hist_data->sort_keys, hist_data->n_sort_keys, @@ -5338,11 +5382,29 @@ static int print_entries(struct seq_file *m, if (n_entries < 0) return n_entries; + for (j = 0; j < hist_data->n_vals; j++) { + if (!(hist_data->fields[j]->flags & HIST_FIELD_FL_PERCENT)) + continue; + if (!totals) { + totals = kcalloc(hist_data->n_vals, sizeof(u64), + GFP_KERNEL); + if (!totals) { + n_entries = -ENOMEM; + goto out; + } + } + for (i = 0; i < n_entries; i++) + totals[j] += tracing_map_read_sum( + sort_entries[i]->elt, j); + } + for (i = 0; i < n_entries; i++) - hist_trigger_entry_print(m, hist_data, + hist_trigger_entry_print(m, hist_data, totals, sort_entries[i]->key, sort_entries[i]->elt); + kfree(totals); +out: tracing_map_destroy_sort_entries(sort_entries, n_entries); return n_entries; -- GitLab From a2c54256dec7510477e2b4f4db187e638f7cac37 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 20 Oct 2022 00:31:55 +0900 Subject: [PATCH 1381/1480] tracing: Add .graph suffix option to histogram value Add the .graph suffix which shows the bar graph of the histogram value. For example, the below example shows that the bar graph of the histogram of the runtime for each tasks. ------ # cd /sys/kernel/debug/tracing/ # echo hist:keys=pid:vals=runtime.graph:sort=pid > \ events/sched/sched_stat_runtime/trigger # sleep 10 # cat events/sched/sched_stat_runtime/hist # event histogram # # trigger info: hist:keys=pid:vals=hitcount,runtime.graph:sort=pid:size=2048 [active] # { pid: 14 } hitcount: 2 runtime: { pid: 16 } hitcount: 8 runtime: { pid: 26 } hitcount: 1 runtime: { pid: 57 } hitcount: 3 runtime: { pid: 61 } hitcount: 20 runtime: ### { pid: 66 } hitcount: 2 runtime: { pid: 70 } hitcount: 3 runtime: { pid: 72 } hitcount: 2 runtime: { pid: 145 } hitcount: 14 runtime: #################### { pid: 152 } hitcount: 5 runtime: ####### { pid: 153 } hitcount: 2 runtime: #### Totals: Hits: 62 Entries: 11 Dropped: 0 ------- Link: https://lore.kernel.org/linux-trace-kernel/166610813953.56030.10944148382315789485.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Tested-by: Tom Zanussi --- kernel/trace/trace.c | 3 +- kernel/trace/trace_events_hist.c | 77 +++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 08e9568849b1a..55aec4616d8b7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5725,7 +5725,8 @@ static const char readme_msg[] = "\t .log2 display log2 value rather than raw number\n" "\t .buckets=size display values in groups of size rather than raw number\n" "\t .usecs display a common_timestamp in microseconds\n" - "\t .percent display a number of percentage value\n\n" + "\t .percent display a number of percentage value\n" + "\t .graph display a bar-graph of a value\n\n" "\t The 'pause' parameter can be used to pause an existing hist\n" "\t trigger or to start a hist trigger but not log any events\n" "\t until told to do so. 'continue' can be used to start or\n" diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 35b0e956f06ef..946b2b8f0f2ca 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -507,6 +507,7 @@ enum hist_field_flags { HIST_FIELD_FL_BUCKET = 1 << 17, HIST_FIELD_FL_CONST = 1 << 18, HIST_FIELD_FL_PERCENT = 1 << 19, + HIST_FIELD_FL_GRAPH = 1 << 20, }; struct var_defs { @@ -1710,6 +1711,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) flags_str = "usecs"; else if (hist_field->flags & HIST_FIELD_FL_PERCENT) flags_str = "percent"; + else if (hist_field->flags & HIST_FIELD_FL_GRAPH) + flags_str = "graph"; return flags_str; } @@ -2322,6 +2325,10 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY)) goto error; *flags |= HIST_FIELD_FL_PERCENT; + } else if (strncmp(modifier, "graph", 5) == 0) { + if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY)) + goto error; + *flags |= HIST_FIELD_FL_GRAPH; } else { error: hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier)); @@ -5316,20 +5323,52 @@ div0: return val ? UINT_MAX : 0; } +#define BAR_CHAR '#' + +static inline const char *__fill_bar_str(char *buf, int size, u64 val, u64 max) +{ + unsigned int len = __get_percentage(val, max); + int i; + + if (len == UINT_MAX) { + snprintf(buf, size, "[ERROR]"); + return buf; + } + + len = len * size / 10000; + for (i = 0; i < len && i < size; i++) + buf[i] = BAR_CHAR; + while (i < size) + buf[i++] = ' '; + buf[size] = '\0'; + + return buf; +} + +struct hist_val_stat { + u64 max; + u64 total; +}; + static void hist_trigger_print_val(struct seq_file *m, unsigned int idx, const char *field_name, unsigned long flags, - u64 *totals, struct tracing_map_elt *elt) + struct hist_val_stat *stats, + struct tracing_map_elt *elt) { u64 val = tracing_map_read_sum(elt, idx); unsigned int pc; + char bar[21]; if (flags & HIST_FIELD_FL_PERCENT) { - pc = __get_percentage(val, totals[idx]); + pc = __get_percentage(val, stats[idx].total); if (pc == UINT_MAX) seq_printf(m, " %s (%%):[ERROR]", field_name); else seq_printf(m, " %s (%%): %3u.%02u", field_name, pc / 100, pc % 100); + } else if (flags & HIST_FIELD_FL_GRAPH) { + seq_printf(m, " %s: %20s", field_name, + __fill_bar_str(bar, 20, val, stats[idx].max)); } else if (flags & HIST_FIELD_FL_HEX) { seq_printf(m, " %s: %10llx", field_name, val); } else { @@ -5339,7 +5378,7 @@ static void hist_trigger_print_val(struct seq_file *m, unsigned int idx, static void hist_trigger_entry_print(struct seq_file *m, struct hist_trigger_data *hist_data, - u64 *totals, + struct hist_val_stat *stats, void *key, struct tracing_map_elt *elt) { @@ -5350,7 +5389,7 @@ static void hist_trigger_entry_print(struct seq_file *m, hist_trigger_print_key(m, hist_data, key, elt); /* At first, show the raw hitcount always */ - hist_trigger_print_val(m, i, "hitcount", 0, totals, elt); + hist_trigger_print_val(m, i, "hitcount", 0, stats, elt); for (i = 1; i < hist_data->n_vals; i++) { field_name = hist_field_name(hist_data->fields[i], 0); @@ -5360,7 +5399,7 @@ static void hist_trigger_entry_print(struct seq_file *m, continue; seq_puts(m, " "); - hist_trigger_print_val(m, i, field_name, flags, totals, elt); + hist_trigger_print_val(m, i, field_name, flags, stats, elt); } print_actions(m, hist_data, elt); @@ -5374,7 +5413,8 @@ static int print_entries(struct seq_file *m, struct tracing_map_sort_entry **sort_entries = NULL; struct tracing_map *map = hist_data->map; int i, j, n_entries; - u64 *totals = NULL; + struct hist_val_stat *stats = NULL; + u64 val; n_entries = tracing_map_sort_entries(map, hist_data->sort_keys, hist_data->n_sort_keys, @@ -5382,28 +5422,33 @@ static int print_entries(struct seq_file *m, if (n_entries < 0) return n_entries; + /* Calculate the max and the total for each field if needed. */ for (j = 0; j < hist_data->n_vals; j++) { - if (!(hist_data->fields[j]->flags & HIST_FIELD_FL_PERCENT)) + if (!(hist_data->fields[j]->flags & + (HIST_FIELD_FL_PERCENT | HIST_FIELD_FL_GRAPH))) continue; - if (!totals) { - totals = kcalloc(hist_data->n_vals, sizeof(u64), - GFP_KERNEL); - if (!totals) { + if (!stats) { + stats = kcalloc(hist_data->n_vals, sizeof(*stats), + GFP_KERNEL); + if (!stats) { n_entries = -ENOMEM; goto out; } } - for (i = 0; i < n_entries; i++) - totals[j] += tracing_map_read_sum( - sort_entries[i]->elt, j); + for (i = 0; i < n_entries; i++) { + val = tracing_map_read_sum(sort_entries[i]->elt, j); + stats[j].total += val; + if (stats[j].max < val) + stats[j].max = val; + } } for (i = 0; i < n_entries; i++) - hist_trigger_entry_print(m, hist_data, totals, + hist_trigger_entry_print(m, hist_data, stats, sort_entries[i]->key, sort_entries[i]->elt); - kfree(totals); + kfree(stats); out: tracing_map_destroy_sort_entries(sort_entries, n_entries); -- GitLab From ccf47f5cc4cebdba7444cf1c04fc1b02d4b3cd15 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 20 Oct 2022 00:31:55 +0900 Subject: [PATCH 1382/1480] tracing: Add nohitcount option for suppressing display of raw hitcount Add 'nohitcount' ('NOHC' for short) option for suppressing display of the raw hitcount column in the histogram. Note that you must specify at least one value except raw 'hitcount' when you specify this nohitcount option. # cd /sys/kernel/debug/tracing/ # echo hist:keys=pid:vals=runtime.percent,runtime.graph:sort=pid:NOHC > \ events/sched/sched_stat_runtime/trigger # sleep 10 # cat events/sched/sched_stat_runtime/hist # event histogram # # trigger info: hist:keys=pid:vals=runtime.percent,runtime.graph:sort=pid:size=2048:nohitcount [active] # { pid: 8 } runtime (%): 3.02 runtime: # { pid: 14 } runtime (%): 2.25 runtime: { pid: 16 } runtime (%): 2.25 runtime: { pid: 26 } runtime (%): 0.17 runtime: { pid: 61 } runtime (%): 11.52 runtime: #### { pid: 67 } runtime (%): 1.56 runtime: { pid: 68 } runtime (%): 0.84 runtime: { pid: 76 } runtime (%): 0.92 runtime: { pid: 117 } runtime (%): 2.50 runtime: # { pid: 146 } runtime (%): 49.88 runtime: #################### { pid: 157 } runtime (%): 16.63 runtime: ###### { pid: 158 } runtime (%): 8.38 runtime: ### Link: https://lore.kernel.org/linux-trace-kernel/166610814787.56030.4980636083486339906.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Tested-by: Tom Zanussi --- kernel/trace/trace.c | 3 +++ kernel/trace/trace_events_hist.c | 34 ++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 55aec4616d8b7..948f321b9df17 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5678,6 +5678,7 @@ static const char readme_msg[] = "\t [:size=#entries]\n" "\t [:pause][:continue][:clear]\n" "\t [:name=histname1]\n" + "\t [:nohitcount]\n" "\t [:.]\n" "\t [if ]\n\n" "\t Note, special fields can be used as well:\n" @@ -5734,6 +5735,8 @@ static const char readme_msg[] = "\t The 'clear' parameter will clear the contents of a running\n" "\t hist trigger and leave its current paused/active state\n" "\t unchanged.\n\n" + "\t The 'nohitcount' (or NOHC) parameter will suppress display of\n" + "\t raw hitcount in the histogram.\n\n" "\t The enable_hist and disable_hist triggers can be used to\n" "\t have one event conditionally start and stop another event's\n" "\t already-attached hist trigger. The syntax is analogous to\n" diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 946b2b8f0f2ca..a0cd118af5272 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -69,7 +69,8 @@ C(INVALID_STR_OPERAND, "String type can not be an operand in expression"), \ C(EXPECT_NUMBER, "Expecting numeric literal"), \ C(UNARY_MINUS_SUBEXPR, "Unary minus not supported in sub-expressions"), \ - C(DIVISION_BY_ZERO, "Division by zero"), + C(DIVISION_BY_ZERO, "Division by zero"), \ + C(NEED_NOHC_VAL, "Non-hitcount value is required for 'nohitcount'"), #undef C #define C(a, b) HIST_ERR_##a @@ -526,6 +527,7 @@ struct hist_trigger_attrs { bool cont; bool clear; bool ts_in_usecs; + bool no_hitcount; unsigned int map_bits; char *assignment_str[TRACING_MAP_VARS_MAX]; @@ -1550,7 +1552,10 @@ parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str) ret = parse_assignment(tr, str, attrs); if (ret) goto free; - } else if (strcmp(str, "pause") == 0) + } else if (strcmp(str, "nohitcount") == 0 || + strcmp(str, "NOHC") == 0) + attrs->no_hitcount = true; + else if (strcmp(str, "pause") == 0) attrs->pause = true; else if ((strcmp(str, "cont") == 0) || (strcmp(str, "continue") == 0)) @@ -4377,6 +4382,12 @@ static int create_val_fields(struct hist_trigger_data *hist_data, if (fields_str && (strcmp(fields_str, "hitcount") != 0)) ret = -EINVAL; out: + /* There is only raw hitcount but nohitcount suppresses it. */ + if (j == 1 && hist_data->attrs->no_hitcount) { + hist_err(hist_data->event_file->tr, HIST_ERR_NEED_NOHC_VAL, 0); + ret = -ENOENT; + } + return ret; } @@ -5388,13 +5399,13 @@ static void hist_trigger_entry_print(struct seq_file *m, hist_trigger_print_key(m, hist_data, key, elt); - /* At first, show the raw hitcount always */ - hist_trigger_print_val(m, i, "hitcount", 0, stats, elt); + /* At first, show the raw hitcount if !nohitcount */ + if (!hist_data->attrs->no_hitcount) + hist_trigger_print_val(m, i, "hitcount", 0, stats, elt); for (i = 1; i < hist_data->n_vals; i++) { field_name = hist_field_name(hist_data->fields[i], 0); flags = hist_data->fields[i]->flags; - if (flags & HIST_FIELD_FL_VAR || flags & HIST_FIELD_FL_EXPR) continue; @@ -5839,6 +5850,7 @@ static int event_hist_trigger_print(struct seq_file *m, struct hist_trigger_data *hist_data = data->private_data; struct hist_field *field; bool have_var = false; + bool show_val = false; unsigned int i; seq_puts(m, HIST_PREFIX); @@ -5869,12 +5881,16 @@ static int event_hist_trigger_print(struct seq_file *m, continue; } - if (i == HITCOUNT_IDX) + if (i == HITCOUNT_IDX) { + if (hist_data->attrs->no_hitcount) + continue; seq_puts(m, "hitcount"); - else { - seq_puts(m, ","); + } else { + if (show_val) + seq_puts(m, ","); hist_field_print(m, field); } + show_val = true; } if (have_var) { @@ -5925,6 +5941,8 @@ static int event_hist_trigger_print(struct seq_file *m, seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits)); if (hist_data->enable_timestamps) seq_printf(m, ":clock=%s", hist_data->attrs->clock); + if (hist_data->attrs->no_hitcount) + seq_puts(m, ":nohitcount"); print_actions_spec(m, hist_data); -- GitLab From 8c2b99790196d34a58a2b00a4c9862d2de3af3e2 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 20 Oct 2022 00:31:56 +0900 Subject: [PATCH 1383/1480] tracing: docs: Update histogram doc for .percent/.graph and 'nohitcount' Update histogram document for .percent/.graph suffixes and 'nohitcount' option. Link: https://lore.kernel.org/linux-trace-kernel/166610815604.56030.4124933216911828519.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Tested-by: Tom Zanussi --- Documentation/trace/histogram.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst index 87bd772836c0c..f95459aa984f3 100644 --- a/Documentation/trace/histogram.rst +++ b/Documentation/trace/histogram.rst @@ -25,7 +25,7 @@ Documentation written by Tom Zanussi hist:keys=[:values=] [:sort=][:size=#entries][:pause][:continue] - [:clear][:name=histname1][:.] [if ] + [:clear][:name=histname1][:nohitcount][:.] [if ] When a matching event is hit, an entry is added to a hash table using the key(s) and value(s) named. Keys and values correspond to @@ -79,6 +79,8 @@ Documentation written by Tom Zanussi .log2 display log2 value rather than raw number .buckets=size display grouping of values rather than raw number .usecs display a common_timestamp in microseconds + .percent display a number of percentage value + .graph display a bar-graph of a value ============= ================================================= Note that in general the semantics of a given field aren't @@ -137,6 +139,12 @@ Documentation written by Tom Zanussi existing trigger, rather than via the '>' operator, which will cause the trigger to be removed through truncation. + The 'nohitcount' (or NOHC) parameter will suppress display of + raw hitcount in the histogram. This option requires at least one + value field which is not a 'raw hitcount'. For example, + 'hist:...:vals=hitcount:nohitcount' is rejected, but + 'hist:...:vals=hitcount.percent:nohitcount' is OK. + - enable_hist/disable_hist The enable_hist and disable_hist triggers can be used to have one -- GitLab From fff1787adaeebe66f27c01d5c40d8d2e4d79d5ee Mon Sep 17 00:00:00 2001 From: Song Chen Date: Wed, 19 Oct 2022 10:11:18 +0800 Subject: [PATCH 1384/1480] trace/kprobe: remove duplicated calls of ring_buffer_event_data Function __kprobe_trace_func calls ring_buffer_event_data to get a ring buffer, however, it has been done in above call trace_event_buffer_reserve. So does __kretprobe_trace_func. This patch removes those duplicated calls. Link: https://lore.kernel.org/all/1666145478-4706-1-git-send-email-chensong_2000@189.cn/ Reviewed-by: Steven Rostedt (Google) Acked-by: Masami Hiramatsu (Google) Signed-off-by: Song Chen Signed-off-by: Masami Hiramatsu (Google) --- kernel/trace/trace_kprobe.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5a75b039e5860..ee77c8203bd58 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1344,7 +1344,6 @@ __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs, return; fbuffer.regs = regs; - entry = fbuffer.entry = ring_buffer_event_data(fbuffer.event); entry->ip = (unsigned long)tk->rp.kp.addr; store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize); @@ -1385,7 +1384,6 @@ __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, return; fbuffer.regs = regs; - entry = fbuffer.entry = ring_buffer_event_data(fbuffer.event); entry->func = (unsigned long)tk->rp.kp.addr; entry->ret_ip = get_kretprobe_retaddr(ri); store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize); -- GitLab From 575b76cb885532aae13a9d979fd476bb2b156cb9 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 22 Nov 2022 12:23:45 -0500 Subject: [PATCH 1385/1480] tracing/probes: Handle system names with hyphens When creating probe names, a check is done to make sure it matches basic C standard variable naming standards. Basically, starts with alphabetic or underline, and then the rest of the characters have alpha-numeric or underline in them. But system names do not have any true naming conventions, as they are created by the TRACE_SYSTEM macro and nothing tests to see what they are. The "xhci-hcd" trace events has a '-' in the system name. When trying to attach a eprobe to one of these trace points, it fails because the system name does not follow the variable naming convention because of the hyphen, and the eprobe checks fail on this. Allow hyphens in the system name so that eprobes can attach to the "xhci-hcd" trace events. Link: https://lore.kernel.org/all/Y3eJ8GiGnEvVd8%2FN@macondo/ Link: https://lore.kernel.org/linux-trace-kernel/20221122122345.160f5077@gandalf.local.home Cc: Masami Hiramatsu Cc: stable@vger.kernel.org Fixes: 5b7a96220900e ("tracing/probe: Check event/group naming rule at parsing") Reported-by: Rafael Mendonca Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 19 ++++++++++++++++--- kernel/trace/trace_probe.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 48643f07bc018..8f37ff032b4f8 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1954,17 +1954,30 @@ static __always_inline void trace_iterator_reset(struct trace_iterator *iter) } /* Check the name is good for event/group/fields */ -static inline bool is_good_name(const char *name) +static inline bool __is_good_name(const char *name, bool hash_ok) { - if (!isalpha(*name) && *name != '_') + if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-')) return false; while (*++name != '\0') { - if (!isalpha(*name) && !isdigit(*name) && *name != '_') + if (!isalpha(*name) && !isdigit(*name) && *name != '_' && + (!hash_ok || *name != '-')) return false; } return true; } +/* Check the name is good for event/group/fields */ +static inline bool is_good_name(const char *name) +{ + return __is_good_name(name, false); +} + +/* Check the name is good for system */ +static inline bool is_good_system_name(const char *name) +{ + return __is_good_name(name, true); +} + /* Convert certain expected symbols into '_' when generating event names */ static inline void sanitize_event_name(char *name) { diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 36dff277de464..bb2f95d7175c2 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup, return -EINVAL; } strlcpy(buf, event, slash - event + 1); - if (!is_good_name(buf)) { + if (!is_good_system_name(buf)) { trace_probe_log_err(offset, BAD_GROUP_NAME); return -EINVAL; } -- GitLab From e25e43a4e5d8cb2323553d8b6a7ba08d2ebab21f Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Tue, 6 Dec 2022 23:18:01 +0900 Subject: [PATCH 1386/1480] tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE Both CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER partially enables the CONFIG_TRACER_MAX_TRACE code, but that is complicated and has introduced a bug; It declares tracing_max_lat_fops data structure outside of #ifdefs, but since it is defined only when CONFIG_TRACER_MAX_TRACE=y or CONFIG_HWLAT_TRACER=y, if only CONFIG_OSNOISE_TRACER=y, that declaration comes to a definition(!). To fix this issue, and do not repeat the similar problem, makes CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER enables the CONFIG_TRACER_MAX_TRACE always. It has there benefits; - Fix the tracing_max_lat_fops bug - Simplify the #ifdefs - CONFIG_TRACER_MAX_TRACE code is fully enabled, or not. Link: https://lore.kernel.org/linux-trace-kernel/167033628155.4111793.12185405690820208159.stgit@devnote3 Fixes: 424b650f35c7 ("tracing: Fix missing osnoise tracer on max_latency") Cc: Daniel Bristot de Oliveira Cc: stable@vger.kernel.org Reported-by: David Howells Reported-by: kernel test robot Signed-off-by: Masami Hiramatsu (Google) Link: https://lore.kernel.org/all/166992525941.1716618.13740663757583361463.stgit@warthog.procyon.org.uk/ (original thread and v1) Link: https://lore.kernel.org/all/202212052253.VuhZ2ulJ-lkp@intel.com/T/#u (v1 error report) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/Kconfig | 2 ++ kernel/trace/trace.c | 23 +++++++++++++---------- kernel/trace/trace.h | 8 +++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e9e95c790b8ee..93d7249962833 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -375,6 +375,7 @@ config SCHED_TRACER config HWLAT_TRACER bool "Tracer to detect hardware latencies (like SMIs)" select GENERIC_TRACER + select TRACER_MAX_TRACE help This tracer, when enabled will create one or more kernel threads, depending on what the cpumask file is set to, which each thread @@ -410,6 +411,7 @@ config HWLAT_TRACER config OSNOISE_TRACER bool "OS Noise tracer" select GENERIC_TRACER + select TRACER_MAX_TRACE help In the context of high-performance computing (HPC), the Operating System Noise (osnoise) refers to the interference experienced by an diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 948f321b9df17..664619b3f1e17 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1421,6 +1421,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr) return false; } EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable); +#define free_snapshot(tr) do { } while (0) #endif /* CONFIG_TRACER_SNAPSHOT */ void tracer_tracing_off(struct trace_array *tr) @@ -1692,6 +1693,8 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) } unsigned long __read_mostly tracing_thresh; + +#ifdef CONFIG_TRACER_MAX_TRACE static const struct file_operations tracing_max_lat_fops; #ifdef LATENCY_FS_NOTIFY @@ -1748,18 +1751,14 @@ void latency_fsnotify(struct trace_array *tr) irq_work_queue(&tr->fsnotify_irqwork); } -#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \ - || defined(CONFIG_OSNOISE_TRACER) +#else /* !LATENCY_FS_NOTIFY */ #define trace_create_maxlat_file(tr, d_tracer) \ trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ d_tracer, &tr->max_latency, &tracing_max_lat_fops) -#else -#define trace_create_maxlat_file(tr, d_tracer) do { } while (0) #endif -#ifdef CONFIG_TRACER_MAX_TRACE /* * Copy the new maximum trace into the separate maximum-trace * structure. (this way the maximum trace is permanently saved, @@ -1834,14 +1833,15 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu, ring_buffer_record_off(tr->max_buffer.buffer); #ifdef CONFIG_TRACER_SNAPSHOT - if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) - goto out_unlock; + if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) { + arch_spin_unlock(&tr->max_lock); + return; + } #endif swap(tr->array_buffer.buffer, tr->max_buffer.buffer); __update_max_tr(tr, tsk, cpu); - out_unlock: arch_spin_unlock(&tr->max_lock); } @@ -1888,6 +1888,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) __update_max_tr(tr, tsk, cpu); arch_spin_unlock(&tr->max_lock); } + #endif /* CONFIG_TRACER_MAX_TRACE */ static int wait_on_pipe(struct trace_iterator *iter, int full) @@ -6577,7 +6578,7 @@ out: return ret; } -#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) +#ifdef CONFIG_TRACER_MAX_TRACE static ssize_t tracing_max_lat_read(struct file *filp, char __user *ubuf, @@ -7592,7 +7593,7 @@ static const struct file_operations tracing_thresh_fops = { .llseek = generic_file_llseek, }; -#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) +#ifdef CONFIG_TRACER_MAX_TRACE static const struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read, @@ -9606,7 +9607,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) create_trace_options_dir(tr); +#ifdef CONFIG_TRACER_MAX_TRACE trace_create_maxlat_file(tr, d_tracer); +#endif if (ftrace_create_function_files(tr, d_tracer)) MEM_FAIL(1, "Could not allocate function filter files"); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8f37ff032b4f8..9dc920b01c17f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -308,8 +308,7 @@ struct trace_array { struct array_buffer max_buffer; bool allocated_snapshot; #endif -#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \ - || defined(CONFIG_OSNOISE_TRACER) +#ifdef CONFIG_TRACER_MAX_TRACE unsigned long max_latency; #ifdef CONFIG_FSNOTIFY struct dentry *d_max_latency; @@ -688,12 +687,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu, void *cond_data); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); -#endif /* CONFIG_TRACER_MAX_TRACE */ -#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \ - || defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY) +#ifdef CONFIG_FSNOTIFY #define LATENCY_FS_NOTIFY #endif +#endif /* CONFIG_TRACER_MAX_TRACE */ #ifdef LATENCY_FS_NOTIFY void latency_fsnotify(struct trace_array *tr); -- GitLab From 4994e387d7332f03cd4eab55f7896ddf04cab1c0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 6 Dec 2022 14:12:02 -0500 Subject: [PATCH 1387/1480] x86/mm/kmmio: Switch to arch_spin_lock() The mmiotrace tracer is "special". The purpose is to help reverse engineer binary drivers by removing the memory allocated by the driver and when the driver goes to access it, a fault occurs, the mmiotracer will record what the driver was doing and then do the work on its behalf by single stepping through the process. But to achieve this ability, it must do some special things. One is it needs to grab a lock while in the breakpoint handler. This is considered an NMI state, and then lockdep warns that the lock is being held in both an NMI state (really a breakpoint handler) and also in normal context. As the breakpoint/NMI state only happens when the driver is accessing memory, there's no concern of a race condition against the setup and tear-down of mmiotracer. To make lockdep and mmiotrace work together, convert the locks used in the breakpoint handler into arch_spin_lock(). Link: https://lkml.kernel.org/r/20221206191229.656244029@goodmis.org Link: https://lore.kernel.org/lkml/20221201213126.620b7dd3@gandalf.local.home/ Cc: Masami Hiramatsu Cc: Andrew Morton Cc: Karol Herbst Cc: Pekka Paalanen Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Borislav Petkov Suggested-by: Thomas Gleixner Signed-off-by: Steven Rostedt (Google) --- arch/x86/mm/kmmio.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index d3efbc5b34498..edb4864501582 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -62,7 +62,13 @@ struct kmmio_context { int active; }; -static DEFINE_SPINLOCK(kmmio_lock); +/* + * The kmmio_lock is taken in int3 context, which is treated as NMI context. + * This causes lockdep to complain about it bein in both NMI and normal + * context. Hide it from lockdep, as it should not have any other locks + * taken under it, and this is only enabled for debugging mmio anyway. + */ +static arch_spinlock_t kmmio_lock = __ARCH_SPIN_LOCK_UNLOCKED; /* Protected by kmmio_lock */ unsigned int kmmio_count; @@ -346,10 +352,10 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) ctx->probe->post_handler(ctx->probe, condition, regs); /* Prevent racing against release_kmmio_fault_page(). */ - spin_lock(&kmmio_lock); + arch_spin_lock(&kmmio_lock); if (ctx->fpage->count) arm_kmmio_fault_page(ctx->fpage); - spin_unlock(&kmmio_lock); + arch_spin_unlock(&kmmio_lock); regs->flags &= ~X86_EFLAGS_TF; regs->flags |= ctx->saved_flags; @@ -440,7 +446,8 @@ int register_kmmio_probe(struct kmmio_probe *p) unsigned int l; pte_t *pte; - spin_lock_irqsave(&kmmio_lock, flags); + local_irq_save(flags); + arch_spin_lock(&kmmio_lock); if (get_kmmio_probe(addr)) { ret = -EEXIST; goto out; @@ -460,7 +467,9 @@ int register_kmmio_probe(struct kmmio_probe *p) size += page_level_size(l); } out: - spin_unlock_irqrestore(&kmmio_lock, flags); + arch_spin_unlock(&kmmio_lock); + local_irq_restore(flags); + /* * XXX: What should I do here? * Here was a call to global_flush_tlb(), but it does not exist @@ -494,7 +503,8 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) struct kmmio_fault_page **prevp = &dr->release_list; unsigned long flags; - spin_lock_irqsave(&kmmio_lock, flags); + local_irq_save(flags); + arch_spin_lock(&kmmio_lock); while (f) { if (!f->count) { list_del_rcu(&f->list); @@ -506,7 +516,8 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) } f = *prevp; } - spin_unlock_irqrestore(&kmmio_lock, flags); + arch_spin_unlock(&kmmio_lock); + local_irq_restore(flags); /* This is the real RCU destroy call. */ call_rcu(&dr->rcu, rcu_free_kmmio_fault_pages); @@ -540,14 +551,16 @@ void unregister_kmmio_probe(struct kmmio_probe *p) if (!pte) return; - spin_lock_irqsave(&kmmio_lock, flags); + local_irq_save(flags); + arch_spin_lock(&kmmio_lock); while (size < size_lim) { release_kmmio_fault_page(addr + size, &release_list); size += page_level_size(l); } list_del_rcu(&p->list); kmmio_count--; - spin_unlock_irqrestore(&kmmio_lock, flags); + arch_spin_unlock(&kmmio_lock); + local_irq_restore(flags); if (!release_list) return; -- GitLab From 20fb6c997600012209699564a79911584dd5876b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 9 Dec 2022 13:41:44 -0500 Subject: [PATCH 1388/1480] x86/mm/kmmio: Use rcu_read_lock_sched_notrace() The mmiotrace tracer is "special". The purpose is to help reverse engineer binary drivers by removing the memory allocated by the driver and when the driver goes to access it, a fault occurs, the mmiotracer will record what the driver was doing and then do the work on its behalf by single stepping through the process. But to achieve this ability, it must do some special things. One is to take the rcu_read_lock() when the fault occurs, and then release it in the breakpoint that is single stepping. This makes lockdep unhappy, as it changes the state of RCU from within an exception that is not contained in that exception, and we get a nasty splat from lockdep. Instead, switch to rcu_read_lock_sched_notrace() as the RCU sched variant has the same grace period as normal RCU. This is basically the same as rcu_read_lock() but does not make lockdep complain about it. Note, the preempt_disable() is still needed as it uses preempt_enable_no_resched(). Link: https://lore.kernel.org/linux-trace-kernel/20221209134144.04f33626@gandalf.local.home Cc: Masami Hiramatsu Cc: Andrew Morton Cc: Karol Herbst Cc: Pekka Paalanen Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Acked-by: Paul E. McKenney Signed-off-by: Steven Rostedt (Google) --- arch/x86/mm/kmmio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index edb4864501582..853c49877c161 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -254,7 +254,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) * again. */ preempt_disable(); - rcu_read_lock(); + rcu_read_lock_sched_notrace(); faultpage = get_kmmio_fault_page(page_base); if (!faultpage) { @@ -323,7 +323,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) return 1; /* fault handled */ no_kmmio: - rcu_read_unlock(); + rcu_read_unlock_sched_notrace(); preempt_enable_no_resched(); return ret; } @@ -363,7 +363,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) /* These were acquired in kmmio_handler(). */ ctx->active--; BUG_ON(ctx->active); - rcu_read_unlock(); + rcu_read_unlock_sched_notrace(); preempt_enable_no_resched(); /* -- GitLab From 2cc6a528882d0e0ccbc1bca5f95b8c963cedac54 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Wed, 7 Dec 2022 11:46:35 +0800 Subject: [PATCH 1389/1480] tracing/hist: Fix wrong return value in parse_action_params() When number of synth fields is more than SYNTH_FIELDS_MAX, parse_action_params() should return -EINVAL. Link: https://lore.kernel.org/linux-trace-kernel/20221207034635.2253990-1-zhengyejian1@huawei.com Cc: Cc: Cc: stable@vger.kernel.org Fixes: c282a386a397 ("tracing: Add 'onmatch' hist trigger action support") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_hist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index a0cd118af5272..b4ad86c22b43a 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -3609,6 +3609,7 @@ static int parse_action_params(struct trace_array *tr, char *params, while (params) { if (data->n_params >= SYNTH_FIELDS_MAX) { hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0); + ret = -EINVAL; goto out; } -- GitLab From 82470f7d9044842618c847a7166de2b7458157a7 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Wed, 7 Dec 2022 11:51:43 +0800 Subject: [PATCH 1390/1480] tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx' When generate a synthetic event with many params and then create a trace action for it [1], kernel panic happened [2]. It is because that in trace_action_create() 'data->n_params' is up to SYNTH_FIELDS_MAX (current value is 64), and array 'data->var_ref_idx' keeps indices into array 'hist_data->var_refs' for each synthetic event param, but the length of 'data->var_ref_idx' is TRACING_MAP_VARS_MAX (current value is 16), so out-of-bound write happened when 'data->n_params' more than 16. In this case, 'data->match_data.event' is overwritten and eventually cause the panic. To solve the issue, adjust the length of 'data->var_ref_idx' to be SYNTH_FIELDS_MAX and add sanity checks to avoid out-of-bound write. [1] # cd /sys/kernel/tracing/ # echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\ int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\ int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\ int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\ int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\ int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\ int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\ int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\ int v63" >> synthetic_events # echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="bash"' >> \ events/sched/sched_waking/trigger # echo "hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid)" >> events/sched/sched_switch/trigger [2] BUG: unable to handle page fault for address: ffff91c900000000 PGD 61001067 P4D 61001067 PUD 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 2 PID: 322 Comm: bash Tainted: G W 6.1.0-rc8+ #229 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:strcmp+0xc/0x30 Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14 07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3 RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000 RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000 RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000 R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580 R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538 FS: 00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0 Call Trace: __find_event_file+0x55/0x90 action_create+0x76c/0x1060 event_hist_trigger_parse+0x146d/0x2060 ? event_trigger_write+0x31/0xd0 trigger_process_regex+0xbb/0x110 event_trigger_write+0x6b/0xd0 vfs_write+0xc8/0x3e0 ? alloc_fd+0xc0/0x160 ? preempt_count_add+0x4d/0xa0 ? preempt_count_add+0x70/0xa0 ksys_write+0x5f/0xe0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f1d1d0cf077 Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 RSP: 002b:00007ffcebb0e568 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000143 RCX: 00007f1d1d0cf077 RDX: 0000000000000143 RSI: 00005639265aa7e0 RDI: 0000000000000001 RBP: 00005639265aa7e0 R08: 000000000000000a R09: 0000000000000142 R10: 000056392639c017 R11: 0000000000000246 R12: 0000000000000143 R13: 00007f1d1d1ae6a0 R14: 00007f1d1d1aa4a0 R15: 00007f1d1d1a98a0 Modules linked in: CR2: ffff91c900000000 ---[ end trace 0000000000000000 ]--- RIP: 0010:strcmp+0xc/0x30 Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14 07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3 RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000 RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000 RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000 R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580 R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538 FS: 00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0 Link: https://lore.kernel.org/linux-trace-kernel/20221207035143.2278781-1-zhengyejian1@huawei.com Cc: Cc: Cc: stable@vger.kernel.org Fixes: d380dcde9a07 ("tracing: Fix now invalid var_ref_vals assumption in trace action") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_hist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index b4ad86c22b43a..8264b28d5a57e 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -621,7 +621,7 @@ struct action_data { * event param, and is passed to the synthetic event * invocation. */ - unsigned int var_ref_idx[TRACING_MAP_VARS_MAX]; + unsigned int var_ref_idx[SYNTH_FIELDS_MAX]; struct synth_event *synth_event; bool use_trace_keyword; char *synth_event_name; @@ -2186,7 +2186,9 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data, return ref_field; } } - + /* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */ + if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX) + return NULL; ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL); if (ref_field) { if (init_var_ref(ref_field, var_field, system, event_name)) { @@ -3946,6 +3948,10 @@ static int trace_action_create(struct hist_trigger_data *hist_data, lockdep_assert_held(&event_mutex); + /* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */ + if (data->n_params > SYNTH_FIELDS_MAX) + return -EINVAL; + if (data->use_trace_keyword) synth_event_name = data->synth_event_name; else -- GitLab From ff4837f7fe59ff018eca4705a70eca5e0b486b97 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Wed, 7 Dec 2022 17:15:57 +0800 Subject: [PATCH 1391/1480] tracing: Fix issue of missing one synthetic field The maximum number of synthetic fields supported is defined as SYNTH_FIELDS_MAX which value currently is 64, but it actually fails when try to generate a synthetic event with 64 fields by executing like: # echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\ int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\ int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\ int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\ int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\ int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\ int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\ int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\ int v63; int v64" >> /sys/kernel/tracing/synthetic_events Correct the field counting to fix it. Link: https://lore.kernel.org/linux-trace-kernel/20221207091557.3137904-1-zhengyejian1@huawei.com Cc: Cc: Cc: stable@vger.kernel.org Fixes: c9e759b1e845 ("tracing: Rework synthetic event command parsing") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index c3b582d19b620..67592eed0be8d 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -1282,12 +1282,12 @@ static int __create_synth_event(const char *name, const char *raw_fields) goto err_free_arg; } - fields[n_fields++] = field; if (n_fields == SYNTH_FIELDS_MAX) { synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0); ret = -EINVAL; goto err_free_arg; } + fields[n_fields++] = field; n_fields_this_loop++; } -- GitLab From 608c6ed3337850c767ab0dd6c583477922233e29 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Wed, 7 Dec 2022 21:53:26 +0800 Subject: [PATCH 1392/1480] tracing/hist: Fix issue of losting command info in error_log When input some constructed invalid 'trigger' command, command info in 'error_log' are lost [1]. The root cause is that there is a path that event_hist_trigger_parse() is recursely called once and 'last_cmd' which save origin command is cleared, then later calling of hist_err() will no longer record origin command info: event_hist_trigger_parse() { last_cmd_set() // <1> 'last_cmd' save origin command here at first create_actions() { onmatch_create() { action_create() { trace_action_create() { trace_action_create_field_var() { create_field_var_hist() { event_hist_trigger_parse() { // <2> recursely called once hist_err_clear() // <3> 'last_cmd' is cleared here } hist_err() // <4> No longer find origin command!!! Since 'glob' is empty string while running into the recurse call, we can trickly check it and bypass the call of hist_err_clear() to solve it. [1] # cd /sys/kernel/tracing # echo "my_synth_event int v1; int v2; int v3;" >> synthetic_events # echo 'hist:keys=pid' >> events/sched/sched_waking/trigger # echo "hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(\ pid,pid1)" >> events/sched/sched_switch/trigger # cat error_log [ 8.405018] hist:sched:sched_switch: error: Couldn't find synthetic event Command: hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1) ^ [ 8.816902] hist:sched:sched_switch: error: Couldn't find field Command: hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1) ^ [ 8.816902] hist:sched:sched_switch: error: Couldn't parse field variable Command: hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(pid,pid1) ^ [ 8.999880] : error: Couldn't find field Command: ^ [ 8.999880] : error: Couldn't parse field variable Command: ^ [ 8.999880] : error: Couldn't find field Command: ^ [ 8.999880] : error: Couldn't create histogram for field Command: ^ Link: https://lore.kernel.org/linux-trace-kernel/20221207135326.3483216-1-zhengyejian1@huawei.com Cc: Cc: Fixes: f404da6e1d46 ("tracing: Add 'last error' error facility for hist triggers") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 8264b28d5a57e..fcaf226b77446 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -6576,7 +6576,7 @@ enable: if (se) se->ref++; out: - if (ret == 0) + if (ret == 0 && glob[0]) hist_err_clear(); return ret; -- GitLab From 88ca6a71dcab4a4ba6e6e2ff66415a5c4f86e874 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 9 Dec 2022 10:11:51 -0500 Subject: [PATCH 1393/1480] ring-buffer: Handle resize in early boot up With the new command line option that allows trace event triggers to be added at boot, the "snapshot" trigger will allocate the snapshot buffer very early, when interrupts can not be enabled. Allocating the ring buffer is not the problem, but it also resizes it, which is, as the resize code does synchronization that can not be preformed at early boot. To handle this, first change the raw_spin_lock_irq() in rb_insert_pages() to raw_spin_lock_irqsave(), such that the unlocking of that spin lock will not enable interrupts. Next, where it calls schedule_work_on(), disable migration and check if the CPU to update is the current CPU, and if so, perform the work directly, otherwise re-enable migration and call the schedule_work_on() to the CPU that is being updated. The rb_insert_pages() just needs to be run on the CPU that it is updating, and does not need preemption nor interrupts disabled when calling it. Link: https://lore.kernel.org/lkml/Y5J%2FCajlNh1gexvo@google.com/ Link: https://lore.kernel.org/linux-trace-kernel/20221209101151.1fec1167@gandalf.local.home Cc: Masami Hiramatsu Cc: Andrew Morton Fixes: a01fdc897fa5 ("tracing: Add trace_trigger kernel command line option") Reported-by: Ross Zwisler Signed-off-by: Steven Rostedt Tested-by: Ross Zwisler Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ring_buffer.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 843818ee4814e..c366a0a9ddba4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2062,8 +2062,10 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer) { struct list_head *pages = &cpu_buffer->new_pages; int retries, success; + unsigned long flags; - raw_spin_lock_irq(&cpu_buffer->reader_lock); + /* Can be called at early boot up, where interrupts must not been enabled */ + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); /* * We are holding the reader lock, so the reader page won't be swapped * in the ring buffer. Now we are racing with the writer trying to @@ -2120,7 +2122,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer) * tracing */ RB_WARN_ON(cpu_buffer, !success); - raw_spin_unlock_irq(&cpu_buffer->reader_lock); + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); /* free pages if they weren't inserted */ if (!success) { @@ -2248,8 +2250,16 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, rb_update_pages(cpu_buffer); cpu_buffer->nr_pages_to_update = 0; } else { - schedule_work_on(cpu, - &cpu_buffer->update_pages_work); + /* Run directly if possible. */ + migrate_disable(); + if (cpu != smp_processor_id()) { + migrate_enable(); + schedule_work_on(cpu, + &cpu_buffer->update_pages_work); + } else { + update_pages_handler(&cpu_buffer->update_pages_work); + migrate_enable(); + } } } @@ -2298,9 +2308,17 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, if (!cpu_online(cpu_id)) rb_update_pages(cpu_buffer); else { - schedule_work_on(cpu_id, - &cpu_buffer->update_pages_work); - wait_for_completion(&cpu_buffer->update_done); + /* Run directly if possible. */ + migrate_disable(); + if (cpu_id == smp_processor_id()) { + rb_update_pages(cpu_buffer); + migrate_enable(); + } else { + migrate_enable(); + schedule_work_on(cpu_id, + &cpu_buffer->update_pages_work); + wait_for_completion(&cpu_buffer->update_done); + } } cpu_buffer->nr_pages_to_update = 0; -- GitLab From 98629dadcd020cba690ce0c49a564a1166444646 Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Thu, 8 Dec 2022 17:33:10 -0700 Subject: [PATCH 1394/1480] tracing: remove unnecessary trace_trigger ifdef The trace_trigger command line option introduced by commit a01fdc897fa5 ("tracing: Add trace_trigger kernel command line option") doesn't need to depend on the CONFIG_HIST_TRIGGERS kernel config option. This code doesn't depend on the histogram code, and the run-time selection of triggers is usable without CONFIG_HIST_TRIGGERS. Link: https://lore.kernel.org/linux-trace-kernel/20221209003310.1737039-1-zwisler@google.com Cc: Masami Hiramatsu Cc: Andrew Morton Cc: Mathieu Desnoyers Cc: Joel Fernandes Cc: Tom Zanussi Fixes: a01fdc897fa5 ("tracing: Add trace_trigger kernel command line option") Signed-off-by: Ross Zwisler Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3bfaf560ecc46..33e0b4f8ebe62 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2796,7 +2796,6 @@ trace_create_new_event(struct trace_event_call *call, return file; } -#ifdef CONFIG_HIST_TRIGGERS #define MAX_BOOT_TRIGGERS 32 static struct boot_triggers { @@ -2832,7 +2831,6 @@ static __init int setup_trace_triggers(char *str) return 1; } __setup("trace_trigger=", setup_trace_triggers); -#endif /* Add an event to a trace directory */ static int @@ -2850,7 +2848,6 @@ __trace_add_new_event(struct trace_event_call *call, struct trace_array *tr) return event_define_fields(call); } -#ifdef CONFIG_HIST_TRIGGERS static void trace_early_triggers(struct trace_event_file *file, const char *name) { int ret; @@ -2868,9 +2865,6 @@ static void trace_early_triggers(struct trace_event_file *file, const char *name bootup_triggers[i].event); } } -#else -static inline void trace_early_triggers(struct trace_event_file *file, const char *name) { } -#endif /* * Just create a descriptor for early init. A descriptor is required -- GitLab From ec370890f92ba8ad5476a34068655b06ba48def7 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Mon, 5 Dec 2022 09:27:38 +0100 Subject: [PATCH 1395/1480] tracing/osnoise: Make osnoise_options static Make osnoise_options static, as reported by the kernel test robot. Link: https://lkml.kernel.org/r/63255826485400d7a2270e9c5e66111079671e7a.1670228712.git.bristot@kernel.org Reported-by: kernel test robot Cc: Daniel Bristot de Oliveira Cc: Steven Rostedt Cc: Masami Hiramatsu Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_osnoise.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 3f10dd1f2f1ce..8ba82c71268f7 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -59,8 +59,8 @@ enum osnoise_options_index { static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD" }; -#define OSN_DEFAULT_OPTIONS 0x2 -unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; +#define OSN_DEFAULT_OPTIONS 0x2 +static unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; /* * trace_array of the enabled osnoise/timerlat instances. -- GitLab From bfd5a5e82d22da43afa0e2bb9fb72339aa79c6cc Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 5 Dec 2022 10:21:52 +0000 Subject: [PATCH 1396/1480] tracing: Fix some checker warnings Fix some checker warnings in the trace code by adding __printf attributes to a number of trace functions and their declarations. Changes: ======== ver #2) - Dropped the fix for the unconditional tracing_max_lat_fops decl[1]. Link: https://lore.kernel.org/r/20221205180617.9b9d3971cbe06ee536603523@kernel.org/ [1] Link: https://lore.kernel.org/r/166992525941.1716618.13740663757583361463.stgit@warthog.procyon.org.uk/ # v1 Link: https://lkml.kernel.org/r/167023571258.382307.15314866482834835192.stgit@warthog.procyon.org.uk Signed-off-by: David Howells Signed-off-by: Steven Rostedt (Google) --- include/linux/trace_events.h | 3 ++- include/linux/trace_seq.h | 3 ++- kernel/trace/trace.h | 2 +- kernel/trace/trace_output.c | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index bb2053246d6a2..4342e996bcdb7 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -234,7 +234,8 @@ void tracing_record_taskinfo_sched_switch(struct task_struct *prev, void tracing_record_cmdline(struct task_struct *task); void tracing_record_tgid(struct task_struct *task); -int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...); +int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...) + __printf(3, 4); struct event_filter; diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 5a2c650d9e1c1..0c4c7587d6c36 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -97,7 +97,8 @@ extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, const void *buf, size_t len, bool ascii); #else /* CONFIG_TRACING */ -static inline void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) +static inline __printf(2, 3) +void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { } static inline void diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 9dc920b01c17f..e46a49269be20 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -614,7 +614,7 @@ void trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer, bool trace_is_tracepoint_string(const char *str); const char *trace_event_format(struct trace_iterator *iter, const char *fmt); void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, - va_list ap); + va_list ap) __printf(2, 0); int trace_empty(struct trace_iterator *iter); diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index f0ba97121345b..57a13b61f1865 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -322,8 +322,9 @@ void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...) } EXPORT_SYMBOL(trace_event_printf); -static int trace_output_raw(struct trace_iterator *iter, char *name, - char *fmt, va_list ap) +static __printf(3, 0) +int trace_output_raw(struct trace_iterator *iter, char *name, + char *fmt, va_list ap) { struct trace_seq *s = &iter->seq; -- GitLab From 0e162c6f1c8f7f502b3978f5a37ed6fa2e4d21f9 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Fri, 25 Nov 2022 10:43:00 +0700 Subject: [PATCH 1397/1480] Documentation/osnoise: Escape underscore of NO_ prefix kernel test robot reported unknown target name warning: Documentation/trace/osnoise-tracer.rst:112: WARNING: Unknown target name: "no". The warning causes NO_ prefix to be rendered as link text instead, which points to non-existent link target. Escape the prefix underscore to fix the warning. Link: https://lkml.kernel.org/r/20221125034300.24168-1-bagasdotme@gmail.com Cc: Masami Hiramatsu Cc: Jonathan Corbet Cc: Ammar Faizi Cc: GNU/Weeb Mailing List Link: https://lore.kernel.org/linux-doc/202211240447.HxRNftE5-lkp@intel.com/ Fixes: 67543cd6b8eee5 ("Documentation/osnoise: Add osnoise/options documentation") Reported-by: kernel test robot Signed-off-by: Bagas Sanjaya Acked-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- Documentation/trace/osnoise-tracer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/trace/osnoise-tracer.rst b/Documentation/trace/osnoise-tracer.rst index 3c675ed82b27a..fdd562d7c22d1 100644 --- a/Documentation/trace/osnoise-tracer.rst +++ b/Documentation/trace/osnoise-tracer.rst @@ -111,7 +111,7 @@ The tracer has a set of options inside the osnoise directory, they are: be used, which is currently 5 us. - osnoise/options: a set of on/off options that can be enabled by writing the option name to the file or disabled by writing the option - name preceded with the 'NO_' prefix. For example, writing + name preceded with the 'NO\_' prefix. For example, writing NO_OSNOISE_WORKLOAD disables the OSNOISE_WORKLOAD option. The special DEAFAULTS option resets all options to the default value. -- GitLab From 1603dda47714cebe8a29b2154407da7a929d13f4 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Fri, 9 Dec 2022 23:05:52 +0100 Subject: [PATCH 1398/1480] tracing/osnoise: Add PANIC_ON_STOP option Often the latency observed in a CPU is not caused by the work being done in the CPU itself, but by work done on another CPU that causes the hardware to stall all CPUs. In this case, it is interesting to know what is happening on ALL CPUs, and the best way to do this is via crash dump analysis. Add the PANIC_ON_STOP option to osnoise/timerlat tracers. The default behavior is having this option off. When enabled by the user, the system will panic after hitting a stop tracing condition. This option was motivated by a real scenario that Juri Lelli and I were debugging. Link: https://lkml.kernel.org/r/249ce4287c6725543e6db845a6e0df621dc67db5.1670623111.git.bristot@kernel.org Cc: Juri Lelli Cc: Clark Williams Cc: Bagas Sanjaya Cc: Daniel Bristot de Oliveira Cc: Masami Hiramatsu Cc: Jonathan Corbet Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_osnoise.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 8ba82c71268f7..5a7613942223f 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -54,10 +54,11 @@ enum osnoise_options_index { OSN_DEFAULTS = 0, OSN_WORKLOAD, + OSN_PANIC_ON_STOP, OSN_MAX }; -static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD" }; +static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD", "PANIC_ON_STOP" }; #define OSN_DEFAULT_OPTIONS 0x2 static unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; @@ -1270,6 +1271,9 @@ static __always_inline void osnoise_stop_tracing(void) trace_array_printk_buf(tr->array_buffer.buffer, _THIS_IP_, "stop tracing hit on cpu %d\n", smp_processor_id()); + if (test_bit(OSN_PANIC_ON_STOP, &osnoise_options)) + panic("tracer hit stop condition on CPU %d\n", smp_processor_id()); + tracer_tracing_off(tr); } rcu_read_unlock(); -- GitLab From b5dce2002567a9b1a83ef3e3a8678d8c32be2a78 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Fri, 9 Dec 2022 23:05:53 +0100 Subject: [PATCH 1399/1480] tracing/osnoise: Add preempt and/or irq disabled options The osnoise workload runs with preemption and IRQs enabled in such a way as to allow all sorts of noise to disturb osnoise's execution. hwlat tracer has a similar workload but works with irq disabled, allowing only NMIs and the hardware to generate noise. While thinking about adding an options file to hwlat tracer to allow the system to panic, and other features I was thinking to add, like having a tracepoint at each noise detection, it came to my mind that is easier to make osnoise and also do hardware latency detection than making hwlat "feature compatible" with osnoise. Other points are: - osnoise already has an independent cpu file. - osnoise has a more intuitive interface, e.g., runtime/period vs. window/width (and people often need help remembering what it is). - osnoise: tracepoints - osnoise stop options - osnoise options file itself Moreover, the user-space side (in rtla) is simplified by reusing the existing osnoise code. Finally, people have been asking me about using osnoise for hw latency detection, and I have to explain that it was sufficient but not necessary. These options make it sufficient and necessary. Adding a Suggested-by Clark, as he often asked me about this possibility. Link: https://lkml.kernel.org/r/d9c6c19135497054986900f94c8e47410b15316a.1670623111.git.bristot@kernel.org Cc: Suggested-by: Clark Williams Cc: Juri Lelli Cc: Bagas Sanjaya Cc: Daniel Bristot de Oliveira Cc: Masami Hiramatsu Cc: Jonathan Corbet Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_osnoise.c | 48 ++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 5a7613942223f..94c1b5eb1dc02 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -55,10 +55,17 @@ enum osnoise_options_index { OSN_DEFAULTS = 0, OSN_WORKLOAD, OSN_PANIC_ON_STOP, + OSN_PREEMPT_DISABLE, + OSN_IRQ_DISABLE, OSN_MAX }; -static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD", "PANIC_ON_STOP" }; +static const char * const osnoise_options_str[OSN_MAX] = { + "DEFAULTS", + "OSNOISE_WORKLOAD", + "PANIC_ON_STOP", + "OSNOISE_PREEMPT_DISABLE", + "OSNOISE_IRQ_DISABLE" }; #define OSN_DEFAULT_OPTIONS 0x2 static unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; @@ -1308,18 +1315,26 @@ static void notify_new_max_latency(u64 latency) */ static int run_osnoise(void) { + bool disable_irq = test_bit(OSN_IRQ_DISABLE, &osnoise_options); struct osnoise_variables *osn_var = this_cpu_osn_var(); u64 start, sample, last_sample; u64 last_int_count, int_count; s64 noise = 0, max_noise = 0; s64 total, last_total = 0; struct osnoise_sample s; + bool disable_preemption; unsigned int threshold; u64 runtime, stop_in; u64 sum_noise = 0; int hw_count = 0; int ret = -1; + /* + * Disabling preemption is only required if IRQs are enabled, + * and the options is set on. + */ + disable_preemption = !disable_irq && test_bit(OSN_PREEMPT_DISABLE, &osnoise_options); + /* * Considers the current thread as the workload. */ @@ -1335,6 +1350,15 @@ static int run_osnoise(void) */ threshold = tracing_thresh ? : 5000; + /* + * Apply PREEMPT and IRQ disabled options. + */ + if (disable_irq) + local_irq_disable(); + + if (disable_preemption) + preempt_disable(); + /* * Make sure NMIs see sampling first */ @@ -1422,16 +1446,21 @@ static int run_osnoise(void) * cond_resched() */ if (IS_ENABLED(CONFIG_PREEMPT_RCU)) { - local_irq_disable(); + if (!disable_irq) + local_irq_disable(); + rcu_momentary_dyntick_idle(); - local_irq_enable(); + + if (!disable_irq) + local_irq_enable(); } /* * For the non-preemptive kernel config: let threads runs, if - * they so wish. + * they so wish, unless set not do to so. */ - cond_resched(); + if (!disable_irq && !disable_preemption) + cond_resched(); last_sample = sample; last_int_count = int_count; @@ -1450,6 +1479,15 @@ static int run_osnoise(void) */ barrier(); + /* + * Return to the preemptive state. + */ + if (disable_preemption) + preempt_enable(); + + if (disable_irq) + local_irq_enable(); + /* * Save noise info. */ -- GitLab From d358dfe60b7724ad0acb8cf8375a608b983e2b59 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Fri, 9 Dec 2022 23:05:54 +0100 Subject: [PATCH 1400/1480] Documentation/osnoise: Add osnoise/options documentation Add the documentation about the osnoise/options file, the options, and some additional explanation about the OSNOISE_WORKLOAD option. Link: https://lkml.kernel.org/r/fde5567a4bae364f67fd1e9a644d1d62862618a6.1670623111.git.bristot@kernel.org Cc: Daniel Bristot de Oliveira Cc: Juri Lelli Cc: Clark Williams Cc: Masami Hiramatsu Cc: Jonathan Corbet Cc: Bagas Sanjaya Signed-off-by: Daniel Bristot de Oliveira Reviewed-by: Bagas Sanjaya Signed-off-by: Steven Rostedt (Google) --- Documentation/trace/osnoise-tracer.rst | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Documentation/trace/osnoise-tracer.rst b/Documentation/trace/osnoise-tracer.rst index fdd562d7c22d1..140ef2533d26a 100644 --- a/Documentation/trace/osnoise-tracer.rst +++ b/Documentation/trace/osnoise-tracer.rst @@ -92,8 +92,8 @@ Note that the example above shows a high number of HW noise samples. The reason being is that this sample was taken on a virtual machine, and the host interference is detected as a hardware interference. -Tracer options ---------------------- +Tracer Configuration +-------------------- The tracer has a set of options inside the osnoise directory, they are: @@ -115,6 +115,22 @@ The tracer has a set of options inside the osnoise directory, they are: NO_OSNOISE_WORKLOAD disables the OSNOISE_WORKLOAD option. The special DEAFAULTS option resets all options to the default value. +Tracer Options +-------------- + +The osnoise/options file exposes a set of on/off configuration options for +the osnoise tracer. These options are: + + - DEFAULTS: reset the options to the default value. + - OSNOISE_WORKLOAD: do not dispatch osnoise workload (see dedicated + section below). + - PANIC_ON_STOP: call panic() if the tracer stops. This option serves to + capture a vmcore. + - OSNOISE_PREEMPT_DISABLE: disable preemption while running the osnoise + workload, allowing only IRQ and hardware-related noise. + - OSNOISE_IRQ_DISABLE: disable IRQs while running the osnoise workload, + allowing only NMIs and hardware-related noise, like hwlat tracer. + Additional Tracing ------------------ -- GitLab From ff39899be80b9d90d5e13775eb9fd150338b6e15 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 21 Jul 2022 09:59:32 +0800 Subject: [PATCH 1401/1480] exfat: simplify empty entry hint This commit adds exfat_set_empty_hint()/exfat_reset_empty_hint() to reduce code complexity and make code more readable. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 58 +++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 0fc08fdcba733..c0e60ff9ec7d4 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -897,6 +897,29 @@ free_es: return NULL; } +static inline void exfat_reset_empty_hint(struct exfat_hint_femp *hint_femp) +{ + hint_femp->eidx = EXFAT_HINT_NONE; + hint_femp->count = 0; +} + +static inline void exfat_set_empty_hint(struct exfat_inode_info *ei, + struct exfat_hint_femp *candi_empty, struct exfat_chain *clu, + int dentry, int num_entries) +{ + if (ei->hint_femp.eidx == EXFAT_HINT_NONE || + ei->hint_femp.eidx > dentry) { + if (candi_empty->count == 0) { + candi_empty->cur = *clu; + candi_empty->eidx = dentry; + } + + candi_empty->count++; + if (candi_empty->count == num_entries) + ei->hint_femp = *candi_empty; + } +} + enum { DIRENT_STEP_FILE, DIRENT_STEP_STRM, @@ -921,7 +944,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, { int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len; int order, step, name_len = 0; - int dentries_per_clu, num_empty = 0; + int dentries_per_clu; unsigned int entry_type; unsigned short *uniname = NULL; struct exfat_chain clu; @@ -939,10 +962,13 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, end_eidx = dentry; } - candi_empty.eidx = EXFAT_HINT_NONE; + exfat_reset_empty_hint(&ei->hint_femp); + rewind: order = 0; step = DIRENT_STEP_FILE; + exfat_reset_empty_hint(&candi_empty); + while (clu.dir != EXFAT_EOF_CLUSTER) { i = dentry & (dentries_per_clu - 1); for (; i < dentries_per_clu; i++, dentry++) { @@ -962,26 +988,8 @@ rewind: entry_type == TYPE_DELETED) { step = DIRENT_STEP_FILE; - num_empty++; - if (candi_empty.eidx == EXFAT_HINT_NONE && - num_empty == 1) { - exfat_chain_set(&candi_empty.cur, - clu.dir, clu.size, clu.flags); - } - - if (candi_empty.eidx == EXFAT_HINT_NONE && - num_empty >= num_entries) { - candi_empty.eidx = - dentry - (num_empty - 1); - WARN_ON(candi_empty.eidx < 0); - candi_empty.count = num_empty; - - if (ei->hint_femp.eidx == - EXFAT_HINT_NONE || - candi_empty.eidx <= - ei->hint_femp.eidx) - ei->hint_femp = candi_empty; - } + exfat_set_empty_hint(ei, &candi_empty, &clu, + dentry, num_entries); brelse(bh); if (entry_type == TYPE_UNUSED) @@ -989,8 +997,7 @@ rewind: continue; } - num_empty = 0; - candi_empty.eidx = EXFAT_HINT_NONE; + exfat_reset_empty_hint(&candi_empty); if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) { step = DIRENT_STEP_FILE; @@ -1090,9 +1097,6 @@ not_found: rewind = 1; dentry = 0; clu.dir = p_dir->dir; - /* reset empty hint */ - num_empty = 0; - candi_empty.eidx = EXFAT_HINT_NONE; goto rewind; } -- GitLab From e298c8a818a3e517582e60c412f4a41b3a1647c5 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Mon, 7 Nov 2022 17:22:13 +0900 Subject: [PATCH 1402/1480] exfat: hint the empty entry which at the end of cluster chain After traversing all directory entries, hint the empty directory entry no matter whether or not there are enough empty directory entries. After this commit, hint the empty directory entries like this: 1. Hint the deleted directory entries if enough; 2. Hint the deleted and unused directory entries which at the end of the cluster chain no matter whether enough or not(Add by this commit); 3. If no any empty directory entries, hint the empty directory entries in the new cluster(Add by this commit). This avoids repeated traversal of directory entries, reduces CPU usage, and improves the performance of creating files and directories(especially on low-performance CPUs). Test create 5000 files in a class 4 SD card on imx6q-sabrelite with: for ((i=0;i<5;i++)); do sync time (for ((j=1;j<=1000;j++)); do touch file$((i*1000+j)); done) done The more files, the more performance improvements. Before After Improvement 1~1000 25.360s 22.168s 14.40% 1001~2000 38.242s 28.72ss 33.15% 2001~3000 49.134s 35.037s 40.23% 3001~4000 62.042s 41.624s 49.05% 4001~5000 73.629s 46.772s 57.42% Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 26 ++++++++++++++++++++++---- fs/exfat/namei.c | 33 +++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index c0e60ff9ec7d4..30d0ac43b66c1 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -905,17 +905,24 @@ static inline void exfat_reset_empty_hint(struct exfat_hint_femp *hint_femp) static inline void exfat_set_empty_hint(struct exfat_inode_info *ei, struct exfat_hint_femp *candi_empty, struct exfat_chain *clu, - int dentry, int num_entries) + int dentry, int num_entries, int entry_type) { if (ei->hint_femp.eidx == EXFAT_HINT_NONE || ei->hint_femp.eidx > dentry) { + int total_entries = EXFAT_B_TO_DEN(i_size_read(&ei->vfs_inode)); + if (candi_empty->count == 0) { candi_empty->cur = *clu; candi_empty->eidx = dentry; } - candi_empty->count++; - if (candi_empty->count == num_entries) + if (entry_type == TYPE_UNUSED) + candi_empty->count += total_entries - dentry; + else + candi_empty->count++; + + if (candi_empty->count == num_entries || + candi_empty->count + candi_empty->eidx == total_entries) ei->hint_femp = *candi_empty; } } @@ -989,7 +996,8 @@ rewind: step = DIRENT_STEP_FILE; exfat_set_empty_hint(ei, &candi_empty, &clu, - dentry, num_entries); + dentry, num_entries, + entry_type); brelse(bh); if (entry_type == TYPE_UNUSED) @@ -1100,6 +1108,16 @@ not_found: goto rewind; } + /* + * set the EXFAT_EOF_CLUSTER flag to avoid search + * from the beginning again when allocated a new cluster + */ + if (ei->hint_femp.eidx == EXFAT_HINT_NONE) { + ei->hint_femp.cur.dir = EXFAT_EOF_CLUSTER; + ei->hint_femp.eidx = p_dir->size * dentries_per_clu; + ei->hint_femp.count = 0; + } + /* initialized hint_stat */ hint_stat->clu = p_dir->dir; hint_stat->eidx = 0; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index b617bebc3d0f3..99e00a36c0290 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -224,11 +224,18 @@ static int exfat_search_empty_slot(struct super_block *sb, if (hint_femp->eidx != EXFAT_HINT_NONE) { dentry = hint_femp->eidx; - if (num_entries <= hint_femp->count) { - hint_femp->eidx = EXFAT_HINT_NONE; - return dentry; - } + /* + * If hint_femp->count is enough, it is needed to check if + * there are actual empty entries. + * Otherwise, and if "dentry + hint_famp->count" is also equal + * to "p_dir->size * dentries_per_clu", it means ENOSPC. + */ + if (dentry + hint_femp->count == p_dir->size * dentries_per_clu && + num_entries > hint_femp->count) + return -ENOSPC; + + hint_femp->eidx = EXFAT_HINT_NONE; exfat_chain_dup(&clu, &hint_femp->cur); } else { exfat_chain_dup(&clu, p_dir); @@ -293,6 +300,12 @@ static int exfat_search_empty_slot(struct super_block *sb, } } + hint_femp->eidx = p_dir->size * dentries_per_clu - num_empty; + hint_femp->count = num_empty; + if (num_empty == 0) + exfat_chain_set(&hint_femp->cur, EXFAT_EOF_CLUSTER, 0, + clu.flags); + return -ENOSPC; } @@ -369,15 +382,11 @@ static int exfat_find_empty_entry(struct inode *inode, if (exfat_ent_set(sb, last_clu, clu.dir)) return -EIO; - if (hint_femp.eidx == EXFAT_HINT_NONE) { - /* the special case that new dentry - * should be allocated from the start of new cluster - */ - hint_femp.eidx = EXFAT_B_TO_DEN_IDX(p_dir->size, sbi); - hint_femp.count = sbi->dentries_per_clu; - + if (hint_femp.cur.dir == EXFAT_EOF_CLUSTER) exfat_chain_set(&hint_femp.cur, clu.dir, 0, clu.flags); - } + + hint_femp.count += sbi->dentries_per_clu; + hint_femp.cur.size++; p_dir->size++; size = EXFAT_CLU_TO_B(p_dir->size, sbi); -- GitLab From f83d8a3b532097276266b5e81073ea46e27b17ab Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 7 Apr 2022 15:55:56 +0800 Subject: [PATCH 1403/1480] exfat: reduce the size of exfat_entry_set_cache In normal, there are 19 directory entries at most for a file or a directory. - A file directory entry - A stream extension directory entry - 1~17 file name directory entry So the directory entries are in 3 sectors at most, it is enough for struct exfat_entry_set_cache to pre-allocate 3 bh. This commit changes the size of struct exfat_entry_set_cache as: Before After 32-bit system 88 32 bytes 64-bit system 168 48 bytes Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/exfat_fs.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index a8f8eee4937cb..af55018ff22e5 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -9,6 +9,7 @@ #include #include #include +#include #define EXFAT_ROOT_INO 1 @@ -41,6 +42,14 @@ enum { #define ES_2_ENTRIES 2 #define ES_ALL_ENTRIES 0 +#define ES_IDX_FILE 0 +#define ES_IDX_STREAM 1 +#define ES_IDX_FIRST_FILENAME 2 +#define EXFAT_FILENAME_ENTRY_NUM(name_len) \ + DIV_ROUND_UP(name_len, EXFAT_FILE_NAME_LEN) +#define ES_IDX_LAST_FILENAME(name_len) \ + (ES_IDX_FIRST_FILENAME + EXFAT_FILENAME_ENTRY_NUM(name_len) - 1) + #define DIR_DELETED 0xFFFF0321 /* type values */ @@ -68,9 +77,6 @@ enum { #define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */ #define MAX_VFSNAME_BUF_SIZE ((MAX_NAME_LENGTH + 1) * MAX_CHARSET_SIZE) -/* Enough size to hold 256 dentry (even 512 Byte sector) */ -#define DIR_CACHE_SIZE (256*sizeof(struct exfat_dentry)/512+1) - #define EXFAT_HINT_NONE -1 #define EXFAT_MIN_SUBDIR 2 @@ -125,6 +131,17 @@ enum { #define BITS_PER_BYTE_MASK 0x7 #define IGNORED_BITS_REMAINED(clu, clu_base) ((1 << ((clu) - (clu_base))) - 1) +#define ES_ENTRY_NUM(name_len) (ES_IDX_LAST_FILENAME(name_len) + 1) +/* 19 entries = 1 file entry + 1 stream entry + 17 filename entries */ +#define ES_MAX_ENTRY_NUM ES_ENTRY_NUM(MAX_NAME_LENGTH) + +/* + * 19 entries x 32 bytes/entry = 608 bytes. + * The 608 bytes are in 3 sectors at most (even 512 Byte sector). + */ +#define DIR_CACHE_SIZE \ + (DIV_ROUND_UP(EXFAT_DEN_TO_B(ES_MAX_ENTRY_NUM), SECTOR_SIZE) + 1) + struct exfat_dentry_namebuf { char *lfn; int lfnbuf_len; /* usually MAX_UNINAME_BUF_SIZE */ @@ -166,11 +183,11 @@ struct exfat_hint { struct exfat_entry_set_cache { struct super_block *sb; - bool modified; unsigned int start_off; int num_bh; struct buffer_head *bh[DIR_CACHE_SIZE]; unsigned int num_entries; + bool modified; }; struct exfat_dir_entry { -- GitLab From a3ff29a95fde16906304455aa8c0bd84eb770258 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Wed, 9 Nov 2022 13:50:22 +0800 Subject: [PATCH 1404/1480] exfat: support dynamic allocate bh for exfat_entry_set_cache In special cases, a file or a directory may occupied more than 19 directory entries, pre-allocating 3 bh is not enough. Such as - Support vendor secondary directory entry in the future. - Since file directory entry is damaged, the SecondaryCount field is bigger than 18. So this commit supports dynamic allocation of bh. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 15 +++++++++++++++ fs/exfat/exfat_fs.h | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 30d0ac43b66c1..03e9c9e3966e3 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -615,6 +615,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) bforget(es->bh[i]); else brelse(es->bh[i]); + + if (IS_DYNAMIC_ES(es)) + kfree(es->bh); + kfree(es); return err; } @@ -847,6 +851,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, /* byte offset in sector */ off = EXFAT_BLK_OFFSET(byte_offset, sb); es->start_off = off; + es->bh = es->__bh; /* sector offset in cluster */ sec = EXFAT_B_TO_BLK(byte_offset, sb); @@ -866,6 +871,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, es->num_entries = num_entries; num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); + if (num_bh > ARRAY_SIZE(es->__bh)) { + es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); + if (!es->bh) { + brelse(bh); + kfree(es); + return NULL; + } + es->bh[0] = bh; + } + for (i = 1; i < num_bh; i++) { /* get the next sector */ if (exfat_is_last_sector_in_cluster(sbi, sec)) { diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index af55018ff22e5..82395ae80dba1 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -185,11 +185,14 @@ struct exfat_entry_set_cache { struct super_block *sb; unsigned int start_off; int num_bh; - struct buffer_head *bh[DIR_CACHE_SIZE]; + struct buffer_head *__bh[DIR_CACHE_SIZE]; + struct buffer_head **bh; unsigned int num_entries; bool modified; }; +#define IS_DYNAMIC_ES(es) ((es)->__bh != (es)->bh) + struct exfat_dir_entry { struct exfat_chain dir; int entry; -- GitLab From 20914ff6dd56dd6b548bf5dd90bff09ef89999e4 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 17 Nov 2022 11:37:13 +0800 Subject: [PATCH 1405/1480] exfat: move exfat_entry_set_cache from heap to stack The size of struct exfat_entry_set_cache is only 56 bytes on 64-bit system, and allocating from stack is more efficient than allocating from heap. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 35 +++++++++++++++-------------------- fs/exfat/exfat_fs.h | 5 +++-- fs/exfat/inode.c | 13 ++++++------- fs/exfat/namei.c | 11 +++++------ 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 03e9c9e3966e3..a3fb609dd1299 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -33,10 +33,9 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, struct exfat_chain *p_dir, int entry, unsigned short *uniname) { int i; - struct exfat_entry_set_cache *es; + struct exfat_entry_set_cache es; - es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES); - if (!es) + if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES)) return; /* @@ -45,8 +44,8 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, * Third entry : first file-name entry * So, the index of first file-name dentry should start from 2. */ - for (i = 2; i < es->num_entries; i++) { - struct exfat_dentry *ep = exfat_get_dentry_cached(es, i); + for (i = 2; i < es.num_entries; i++) { + struct exfat_dentry *ep = exfat_get_dentry_cached(&es, i); /* end of name entry */ if (exfat_get_entry_type(ep) != TYPE_EXTEND) @@ -56,7 +55,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, uniname += EXFAT_FILE_NAME_LEN; } - exfat_free_dentry_set(es, false); + exfat_free_dentry_set(&es, false); } /* read a directory entry from the opened directory */ @@ -619,7 +618,6 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) if (IS_DYNAMIC_ES(es)) kfree(es->bh); - kfree(es); return err; } @@ -816,14 +814,14 @@ struct exfat_dentry *exfat_get_dentry_cached( * pointer of entry set on success, * NULL on failure. */ -struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, - struct exfat_chain *p_dir, int entry, unsigned int type) +int exfat_get_dentry_set(struct exfat_entry_set_cache *es, + struct super_block *sb, struct exfat_chain *p_dir, int entry, + unsigned int type) { int ret, i, num_bh; unsigned int off, byte_offset, clu = 0; sector_t sec; struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct exfat_entry_set_cache *es; struct exfat_dentry *ep; int num_entries; enum exfat_validate_dentry_mode mode = ES_MODE_STARTED; @@ -831,17 +829,15 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, if (p_dir->dir == DIR_DELETED) { exfat_err(sb, "access to deleted dentry"); - return NULL; + return -EIO; } byte_offset = EXFAT_DEN_TO_B(entry); ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu); if (ret) - return NULL; + return ret; - es = kzalloc(sizeof(*es), GFP_KERNEL); - if (!es) - return NULL; + memset(es, 0, sizeof(*es)); es->sb = sb; es->modified = false; @@ -859,7 +855,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, bh = sb_bread(sb, sec); if (!bh) - goto free_es; + return -EIO; es->bh[es->num_bh++] = bh; ep = exfat_get_dentry_cached(es, 0); @@ -875,8 +871,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); if (!es->bh) { brelse(bh); - kfree(es); - return NULL; + return -ENOMEM; } es->bh[0] = bh; } @@ -905,11 +900,11 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) goto free_es; } - return es; + return 0; free_es: exfat_free_dentry_set(es, false); - return NULL; + return -EIO; } static inline void exfat_reset_empty_hint(struct exfat_hint_femp *hint_femp) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 82395ae80dba1..2ffe5792b1a99 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -490,8 +490,9 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb, struct exfat_chain *p_dir, int entry, struct buffer_head **bh); struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es, int num); -struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, - struct exfat_chain *p_dir, int entry, unsigned int type); +int exfat_get_dentry_set(struct exfat_entry_set_cache *es, + struct super_block *sb, struct exfat_chain *p_dir, int entry, + unsigned int type); int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync); int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir); diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index 5590a1e83126c..cdcf037a304f5 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -21,7 +21,7 @@ int __exfat_write_inode(struct inode *inode, int sync) { unsigned long long on_disk_size; struct exfat_dentry *ep, *ep2; - struct exfat_entry_set_cache *es = NULL; + struct exfat_entry_set_cache es; struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_inode_info *ei = EXFAT_I(inode); @@ -42,11 +42,10 @@ int __exfat_write_inode(struct inode *inode, int sync) exfat_set_volume_dirty(sb); /* get the directory entry of given file or directory */ - es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES); - if (!es) + if (exfat_get_dentry_set(&es, sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES)) return -EIO; - ep = exfat_get_dentry_cached(es, 0); - ep2 = exfat_get_dentry_cached(es, 1); + ep = exfat_get_dentry_cached(&es, 0); + ep2 = exfat_get_dentry_cached(&es, 1); ep->dentry.file.attr = cpu_to_le16(exfat_make_attr(inode)); @@ -83,8 +82,8 @@ int __exfat_write_inode(struct inode *inode, int sync) ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER; } - exfat_update_dir_chksum_with_entry_set(es); - return exfat_free_dentry_set(es, sync); + exfat_update_dir_chksum_with_entry_set(&es); + return exfat_free_dentry_set(&es, sync); } int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 99e00a36c0290..8d72527dfb78f 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -604,7 +604,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_inode_info *ei = EXFAT_I(dir); struct exfat_dentry *ep, *ep2; - struct exfat_entry_set_cache *es; + struct exfat_entry_set_cache es; /* for optimized dir & entry to prevent long traverse of cluster chain */ struct exfat_hint hint_opt; @@ -644,11 +644,10 @@ static int exfat_find(struct inode *dir, struct qstr *qname, if (cdir.flags & ALLOC_NO_FAT_CHAIN) cdir.size -= dentry / sbi->dentries_per_clu; dentry = hint_opt.eidx; - es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); - if (!es) + if (exfat_get_dentry_set(&es, sb, &cdir, dentry, ES_2_ENTRIES)) return -EIO; - ep = exfat_get_dentry_cached(es, 0); - ep2 = exfat_get_dentry_cached(es, 1); + ep = exfat_get_dentry_cached(&es, 0); + ep2 = exfat_get_dentry_cached(&es, 1); info->type = exfat_get_entry_type(ep); info->attr = le16_to_cpu(ep->dentry.file.attr); @@ -677,7 +676,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, ep->dentry.file.access_time, ep->dentry.file.access_date, 0); - exfat_free_dentry_set(es, false); + exfat_free_dentry_set(&es, false); if (ei->start_clu == EXFAT_FREE_CLUSTER) { exfat_fs_error(sb, -- GitLab From 3b9681acb0ef739343d8cfd35e054aab9597f1dc Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 17 Mar 2022 18:12:40 +0800 Subject: [PATCH 1406/1480] exfat: rename exfat_free_dentry_set() to exfat_put_dentry_set() Since struct exfat_entry_set_cache is allocated from stack, no need to free, so rename exfat_free_dentry_set() to exfat_put_dentry_set(). After renaming, the new function pair is exfat_get_dentry_set()/exfat_put_dentry_set(). Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 16 ++++++++-------- fs/exfat/exfat_fs.h | 2 +- fs/exfat/inode.c | 2 +- fs/exfat/namei.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index a3fb609dd1299..a9a0b3e46af2d 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -55,7 +55,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, uniname += EXFAT_FILE_NAME_LEN; } - exfat_free_dentry_set(&es, false); + exfat_put_dentry_set(&es, false); } /* read a directory entry from the opened directory */ @@ -602,7 +602,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) es->modified = true; } -int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) +int exfat_put_dentry_set(struct exfat_entry_set_cache *es, int sync) { int i, err = 0; @@ -860,7 +860,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, ep = exfat_get_dentry_cached(es, 0); if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) - goto free_es; + goto put_es; num_entries = type == ES_ALL_ENTRIES ? ep->dentry.file.num_ext + 1 : type; @@ -882,7 +882,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, if (p_dir->flags == ALLOC_NO_FAT_CHAIN) clu++; else if (exfat_get_next_cluster(sb, &clu)) - goto free_es; + goto put_es; sec = exfat_cluster_to_sector(sbi, clu); } else { sec++; @@ -890,7 +890,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, bh = sb_bread(sb, sec); if (!bh) - goto free_es; + goto put_es; es->bh[es->num_bh++] = bh; } @@ -898,12 +898,12 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, for (i = 1; i < num_entries; i++) { ep = exfat_get_dentry_cached(es, i); if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) - goto free_es; + goto put_es; } return 0; -free_es: - exfat_free_dentry_set(es, false); +put_es: + exfat_put_dentry_set(es, false); return -EIO; } diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 2ffe5792b1a99..324acc57d0292 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -493,7 +493,7 @@ struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es, int exfat_get_dentry_set(struct exfat_entry_set_cache *es, struct super_block *sb, struct exfat_chain *p_dir, int entry, unsigned int type); -int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync); +int exfat_put_dentry_set(struct exfat_entry_set_cache *es, int sync); int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir); /* inode.c */ diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index cdcf037a304f5..a84eae72556d7 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -83,7 +83,7 @@ int __exfat_write_inode(struct inode *inode, int sync) } exfat_update_dir_chksum_with_entry_set(&es); - return exfat_free_dentry_set(&es, sync); + return exfat_put_dentry_set(&es, sync); } int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 8d72527dfb78f..57510d7f58cfe 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -676,7 +676,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, ep->dentry.file.access_time, ep->dentry.file.access_date, 0); - exfat_free_dentry_set(&es, false); + exfat_put_dentry_set(&es, false); if (ei->start_clu == EXFAT_FREE_CLUSTER) { exfat_fs_error(sb, -- GitLab From f3fe3954c09f97d8227d9d2edc807796a8b228ab Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 17 Mar 2022 19:39:20 +0800 Subject: [PATCH 1407/1480] exfat: replace magic numbers with Macros Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 12 ++++++------ fs/exfat/inode.c | 4 ++-- fs/exfat/namei.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index a9a0b3e46af2d..c05493fc91241 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -44,7 +44,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, * Third entry : first file-name entry * So, the index of first file-name dentry should start from 2. */ - for (i = 2; i < es.num_entries; i++) { + for (i = ES_IDX_FIRST_FILENAME; i < es.num_entries; i++) { struct exfat_dentry *ep = exfat_get_dentry_cached(&es, i); /* end of name entry */ @@ -336,7 +336,7 @@ int exfat_calc_num_entries(struct exfat_uni_name *p_uniname) return -EINVAL; /* 1 file entry + 1 stream entry + name entries */ - return ((len - 1) / EXFAT_FILE_NAME_LEN + 3); + return ES_ENTRY_NUM(len); } unsigned int exfat_get_entry_type(struct exfat_dentry *ep) @@ -591,13 +591,13 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) unsigned short chksum = 0; struct exfat_dentry *ep; - for (i = 0; i < es->num_entries; i++) { + for (i = ES_IDX_FILE; i < es->num_entries; i++) { ep = exfat_get_dentry_cached(es, i); chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, chksum_type); chksum_type = CS_DEFAULT; } - ep = exfat_get_dentry_cached(es, 0); + ep = exfat_get_dentry_cached(es, ES_IDX_FILE); ep->dentry.file.checksum = cpu_to_le16(chksum); es->modified = true; } @@ -858,7 +858,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, return -EIO; es->bh[es->num_bh++] = bh; - ep = exfat_get_dentry_cached(es, 0); + ep = exfat_get_dentry_cached(es, ES_IDX_FILE); if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) goto put_es; @@ -895,7 +895,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, } /* validate cached dentries */ - for (i = 1; i < num_entries; i++) { + for (i = ES_IDX_STREAM; i < num_entries; i++) { ep = exfat_get_dentry_cached(es, i); if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) goto put_es; diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index a84eae72556d7..dac5001bae9eb 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -44,8 +44,8 @@ int __exfat_write_inode(struct inode *inode, int sync) /* get the directory entry of given file or directory */ if (exfat_get_dentry_set(&es, sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES)) return -EIO; - ep = exfat_get_dentry_cached(&es, 0); - ep2 = exfat_get_dentry_cached(&es, 1); + ep = exfat_get_dentry_cached(&es, ES_IDX_FILE); + ep2 = exfat_get_dentry_cached(&es, ES_IDX_STREAM); ep->dentry.file.attr = cpu_to_le16(exfat_make_attr(inode)); diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 57510d7f58cfe..01e4e8c60bbea 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -646,8 +646,8 @@ static int exfat_find(struct inode *dir, struct qstr *qname, dentry = hint_opt.eidx; if (exfat_get_dentry_set(&es, sb, &cdir, dentry, ES_2_ENTRIES)) return -EIO; - ep = exfat_get_dentry_cached(&es, 0); - ep2 = exfat_get_dentry_cached(&es, 1); + ep = exfat_get_dentry_cached(&es, ES_IDX_FILE); + ep2 = exfat_get_dentry_cached(&es, ES_IDX_STREAM); info->type = exfat_get_entry_type(ep); info->attr = le16_to_cpu(ep->dentry.file.attr); -- GitLab From 088f1343d9108c16fca064951d85e6de9f5cab42 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Tue, 16 Aug 2022 16:55:06 +0800 Subject: [PATCH 1408/1480] exfat: remove call ilog2() from exfat_readdir() There is no need to call ilog2() for the conversions between cluster and dentry in exfat_readdir(), because these conversions can be replaced with EXFAT_DEN_TO_CLU()/EXFAT_CLU_TO_DEN(). Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 9 ++++----- fs/exfat/exfat_fs.h | 10 ++++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index c05493fc91241..397ea2d98848f 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -61,7 +61,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, /* read a directory entry from the opened directory */ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) { - int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext; + int i, dentries_per_clu, num_ext; unsigned int type, clu_offset, max_dentries; struct exfat_chain dir, clu; struct exfat_uni_name uni_name; @@ -83,11 +83,10 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags); dentries_per_clu = sbi->dentries_per_clu; - dentries_per_clu_bits = ilog2(dentries_per_clu); max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES, - (u64)sbi->num_clusters << dentries_per_clu_bits); + (u64)EXFAT_CLU_TO_DEN(sbi->num_clusters, sbi)); - clu_offset = dentry >> dentries_per_clu_bits; + clu_offset = EXFAT_DEN_TO_CLU(dentry, sbi); exfat_chain_dup(&clu, &dir); if (clu.flags == ALLOC_NO_FAT_CHAIN) { @@ -162,7 +161,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent dir_entry->entry = dentry; brelse(bh); - ei->hint_bmap.off = dentry >> dentries_per_clu_bits; + ei->hint_bmap.off = EXFAT_DEN_TO_CLU(dentry, sbi); ei->hint_bmap.clu = clu.dir; *cpos = EXFAT_DEN_TO_B(dentry + 1 + num_ext); diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 324acc57d0292..37e8af8042aa9 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -101,11 +101,17 @@ enum { /* * helpers for block size to dentry size conversion. */ -#define EXFAT_B_TO_DEN_IDX(b, sbi) \ - ((b) << ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS)) #define EXFAT_B_TO_DEN(b) ((b) >> DENTRY_SIZE_BITS) #define EXFAT_DEN_TO_B(b) ((b) << DENTRY_SIZE_BITS) +/* + * helpers for cluster size to dentry size conversion. + */ +#define EXFAT_CLU_TO_DEN(clu, sbi) \ + ((clu) << ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS)) +#define EXFAT_DEN_TO_CLU(dentry, sbi) \ + ((dentry) >> ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS)) + /* * helpers for fat entry. */ -- GitLab From 015c0d4f6b1e65857de88279f07d7ecc5e305137 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Mon, 15 Aug 2022 10:15:16 +0800 Subject: [PATCH 1409/1480] exfat: remove unneeded codes from __exfat_rename() The code gets the dentry, but the dentry is not used, remove the code. Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/namei.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 01e4e8c60bbea..347c8df45bd00 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -1175,7 +1175,7 @@ static int __exfat_rename(struct inode *old_parent_inode, struct exfat_inode_info *new_ei = NULL; unsigned int new_entry_type = TYPE_UNUSED; int new_entry = 0; - struct buffer_head *old_bh, *new_bh = NULL; + struct buffer_head *new_bh = NULL; /* check the validity of pointer parameters */ if (new_path == NULL || strlen(new_path) == 0) @@ -1191,13 +1191,6 @@ static int __exfat_rename(struct inode *old_parent_inode, EXFAT_I(old_parent_inode)->flags); dentry = ei->entry; - ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh); - if (!ep) { - ret = -EIO; - goto out; - } - brelse(old_bh); - /* check whether new dir is existing directory and empty */ if (new_inode) { ret = -EIO; -- GitLab From 72880cb5f157514d797d5f6ab3184bbde671a18a Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Sun, 10 Apr 2022 16:12:14 +0800 Subject: [PATCH 1410/1480] exfat: remove unnecessary arguments from exfat_find_dir_entry() This commit removes argument 'num_entries' and 'type' from exfat_find_dir_entry(). Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 12 +++++++----- fs/exfat/exfat_fs.h | 3 +-- fs/exfat/namei.c | 10 ++-------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 397ea2d98848f..8121a7e073bc7 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -956,7 +956,7 @@ enum { */ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, - int num_entries, unsigned int type, struct exfat_hint *hint_opt) + struct exfat_hint *hint_opt) { int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len; int order, step, name_len = 0; @@ -967,6 +967,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, struct exfat_hint *hint_stat = &ei->hint_stat; struct exfat_hint_femp candi_empty; struct exfat_sb_info *sbi = EXFAT_SB(sb); + int num_entries = exfat_calc_num_entries(p_uniname); + + if (num_entries < 0) + return num_entries; dentries_per_clu = sbi->dentries_per_clu; @@ -1020,10 +1024,8 @@ rewind: step = DIRENT_STEP_FILE; hint_opt->clu = clu.dir; hint_opt->eidx = i; - if (type == TYPE_ALL || type == entry_type) { - num_ext = ep->dentry.file.num_ext; - step = DIRENT_STEP_STRM; - } + num_ext = ep->dentry.file.num_ext; + step = DIRENT_STEP_STRM; brelse(bh); continue; } diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 37e8af8042aa9..21fec01d68ff0 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -71,7 +71,6 @@ enum { #define TYPE_PADDING 0x0402 #define TYPE_ACLTAB 0x0403 #define TYPE_BENIGN_SEC 0x0800 -#define TYPE_ALL 0x0FFF #define MAX_CHARSET_SIZE 6 /* max size of multi-byte character */ #define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */ @@ -490,7 +489,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es); int exfat_calc_num_entries(struct exfat_uni_name *p_uniname); int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, - int num_entries, unsigned int type, struct exfat_hint *hint_opt); + struct exfat_hint *hint_opt); int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu); struct exfat_dentry *exfat_get_dentry(struct super_block *sb, struct exfat_chain *p_dir, int entry, struct buffer_head **bh); diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 347c8df45bd00..5f995eba5dbbe 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -597,7 +597,7 @@ unlock: static int exfat_find(struct inode *dir, struct qstr *qname, struct exfat_dir_entry *info) { - int ret, dentry, num_entries, count; + int ret, dentry, count; struct exfat_chain cdir; struct exfat_uni_name uni_name; struct super_block *sb = dir->i_sb; @@ -616,10 +616,6 @@ static int exfat_find(struct inode *dir, struct qstr *qname, if (ret) return ret; - num_entries = exfat_calc_num_entries(&uni_name); - if (num_entries < 0) - return num_entries; - /* check the validation of hint_stat and initialize it if required */ if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) { ei->hint_stat.clu = cdir.dir; @@ -629,9 +625,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, } /* search the file name for directories */ - dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, - num_entries, TYPE_ALL, &hint_opt); - + dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, &hint_opt); if (dentry < 0) return dentry; /* -error value */ -- GitLab From e981917b3fae689e9372647a38746444205bb905 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 17 Nov 2022 10:36:21 +0800 Subject: [PATCH 1411/1480] exfat: remove argument 'size' from exfat_truncate() argument 'size' is not used in exfat_truncate(), remove it. Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/exfat_fs.h | 2 +- fs/exfat/file.c | 4 ++-- fs/exfat/inode.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 21fec01d68ff0..ae048802f9db1 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -449,7 +449,7 @@ int exfat_trim_fs(struct inode *inode, struct fstrim_range *range); /* file.c */ extern const struct file_operations exfat_file_operations; int __exfat_truncate(struct inode *inode, loff_t new_size); -void exfat_truncate(struct inode *inode, loff_t size); +void exfat_truncate(struct inode *inode); int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *attr); int exfat_getattr(struct user_namespace *mnt_userns, const struct path *path, diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 4e0793f35e8fb..7c97c1df1305a 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -189,7 +189,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size) return 0; } -void exfat_truncate(struct inode *inode, loff_t size) +void exfat_truncate(struct inode *inode) { struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); @@ -310,7 +310,7 @@ int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, * __exfat_write_inode() is called from exfat_truncate(), inode * is already written by it, so mark_inode_dirty() is unneeded. */ - exfat_truncate(inode, attr->ia_size); + exfat_truncate(inode); up_write(&EXFAT_I(inode)->truncate_lock); } else mark_inode_dirty(inode); diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index dac5001bae9eb..0d147f8a1f7c6 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -362,7 +362,7 @@ static void exfat_write_failed(struct address_space *mapping, loff_t to) if (to > i_size_read(inode)) { truncate_pagecache(inode, i_size_read(inode)); inode->i_mtime = inode->i_ctime = current_time(inode); - exfat_truncate(inode, EXFAT_I(inode)->i_size_aligned); + exfat_truncate(inode); } } -- GitLab From f7cde96710a4362dca199458d3de04f631178453 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Mon, 28 Mar 2022 16:37:58 +0800 Subject: [PATCH 1412/1480] exfat: remove i_size_write() from __exfat_truncate() The file/directory size is updated into inode by i_size_write() before __exfat_truncate() is called, so it is redundant to re-update by i_size_write() in __exfat_truncate(). Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/exfat_fs.h | 2 +- fs/exfat/file.c | 8 +++----- fs/exfat/inode.c | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index ae048802f9db1..a1e7feb220797 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -448,7 +448,7 @@ int exfat_trim_fs(struct inode *inode, struct fstrim_range *range); /* file.c */ extern const struct file_operations exfat_file_operations; -int __exfat_truncate(struct inode *inode, loff_t new_size); +int __exfat_truncate(struct inode *inode); void exfat_truncate(struct inode *inode); int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *attr); diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 7c97c1df1305a..f5b29072775de 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -93,7 +93,7 @@ static int exfat_sanitize_mode(const struct exfat_sb_info *sbi, } /* resize the file length */ -int __exfat_truncate(struct inode *inode, loff_t new_size) +int __exfat_truncate(struct inode *inode) { unsigned int num_clusters_new, num_clusters_phys; unsigned int last_clu = EXFAT_FREE_CLUSTER; @@ -113,7 +113,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size) exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags); - if (new_size > 0) { + if (i_size_read(inode) > 0) { /* * Truncate FAT chain num_clusters after the first cluster * num_clusters = min(new, phys); @@ -143,8 +143,6 @@ int __exfat_truncate(struct inode *inode, loff_t new_size) ei->start_clu = EXFAT_EOF_CLUSTER; } - i_size_write(inode, new_size); - if (ei->type == TYPE_FILE) ei->attr |= ATTR_ARCHIVE; @@ -207,7 +205,7 @@ void exfat_truncate(struct inode *inode) goto write_size; } - err = __exfat_truncate(inode, i_size_read(inode)); + err = __exfat_truncate(inode); if (err) goto write_size; diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index 0d147f8a1f7c6..95adc4b2e436b 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -626,7 +626,7 @@ void exfat_evict_inode(struct inode *inode) if (!inode->i_nlink) { i_size_write(inode, 0); mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); - __exfat_truncate(inode, 0); + __exfat_truncate(inode); mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock); } -- GitLab From c1ac03af6ed45d05786c219d102f37eb44880f28 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Tue, 29 Nov 2022 19:30:09 +0800 Subject: [PATCH 1413/1480] tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line print_trace_line may overflow seq_file buffer. If the event is not consumed, the while loop keeps peeking this event, causing a infinite loop. Link: https://lkml.kernel.org/r/20221129113009.182425-1-yangjihong1@huawei.com Cc: Masami Hiramatsu Cc: stable@vger.kernel.org Fixes: 088b1e427dbba ("ftrace: pipe fixes") Signed-off-by: Yang Jihong Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 664619b3f1e17..548890c7c0f5c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6802,7 +6802,20 @@ waitagain: ret = print_trace_line(iter); if (ret == TRACE_TYPE_PARTIAL_LINE) { - /* don't print partial lines */ + /* + * If one print_trace_line() fills entire trace_seq in one shot, + * trace_seq_to_user() will returns -EBUSY because save_len == 0, + * In this case, we need to consume it, otherwise, loop will peek + * this event next time, resulting in an infinite loop. + */ + if (save_len == 0) { + iter->seq.full = 0; + trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n"); + trace_consume(iter); + break; + } + + /* In other cases, don't print partial lines */ iter->seq.seq.len = save_len; break; } -- GitLab From 3e12758392bee50135301b0189c064ab80980aca Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Mon, 12 Dec 2022 10:37:03 -0500 Subject: [PATCH 1414/1480] x86/mm/kmmio: Remove redundant preempt_disable() Now that kmmio uses rcu_read_lock_sched_notrace() there's no reason to call preempt_disable() as the read_lock_sched_notrace() already does that and is redundant. This also removes the preempt_enable_no_resched() as the "no_resched()" portion was bogus as there's no reason to do that. Link: https://lkml.kernel.org/r/20221212103703.7129cc5d@gandalf.local.home Cc: Masami Hiramatsu Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: Borislav Petkov Cc: "x86@kernel.org" Cc: Karol Herbst Cc: Pekka Paalanen Cc: Dave Hansen Cc: Andy Lutomirski Cc: Ingo Molnar Signed-off-by: Steven Rostedt (Google) --- arch/x86/mm/kmmio.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 853c49877c161..9f82019179e11 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -246,14 +246,13 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) page_base &= page_level_mask(l); /* - * Preemption is now disabled to prevent process switch during - * single stepping. We can only handle one active kmmio trace + * Hold the RCU read lock over single stepping to avoid looking + * up the probe and kmmio_fault_page again. The rcu_read_lock_sched() + * also disables preemption and prevents process switch during + * the single stepping. We can only handle one active kmmio trace * per cpu, so ensure that we finish it before something else - * gets to run. We also hold the RCU read lock over single - * stepping to avoid looking up the probe and kmmio_fault_page - * again. + * gets to run. */ - preempt_disable(); rcu_read_lock_sched_notrace(); faultpage = get_kmmio_fault_page(page_base); @@ -324,7 +323,6 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) no_kmmio: rcu_read_unlock_sched_notrace(); - preempt_enable_no_resched(); return ret; } @@ -364,7 +362,6 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) ctx->active--; BUG_ON(ctx->active); rcu_read_unlock_sched_notrace(); - preempt_enable_no_resched(); /* * if somebody else is singlestepping across a probe point, flags -- GitLab From c19204cbd65c12fdcd34fb8f5d645007238ed5cd Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 8 Dec 2022 16:11:00 -0600 Subject: [PATCH 1415/1480] cifs: minor cleanup of some headers checkpatch showed formatting problems with extra spaces, and extra semicolon and some missing blank lines in some cifs headers. Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Germano Percossi Signed-off-by: Steve French --- fs/cifs/cifs_ioctl.h | 2 +- fs/cifs/cifsfs.h | 4 ++-- fs/cifs/cifsglob.h | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h index d86d78d5bfdc1..332588e77c311 100644 --- a/fs/cifs/cifs_ioctl.h +++ b/fs/cifs/cifs_ioctl.h @@ -108,7 +108,7 @@ struct smb3_notify_info { #define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify) #define CIFS_DUMP_FULL_KEY _IOWR(CIFS_IOCTL_MAGIC, 10, struct smb3_full_key_debug_info) #define CIFS_IOC_NOTIFY_INFO _IOWR(CIFS_IOCTL_MAGIC, 11, struct smb3_notify_info) -#define CIFS_IOC_SHUTDOWN _IOR ('X', 125, __u32) +#define CIFS_IOC_SHUTDOWN _IOR('X', 125, __u32) /* * Flags for going down operation diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 388b745a978e2..00a573e0ad0e1 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -105,8 +105,8 @@ extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_fsync(struct file *, loff_t, loff_t, int); extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int); extern int cifs_flush(struct file *, fl_owner_t id); -extern int cifs_file_mmap(struct file * , struct vm_area_struct *); -extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *); +extern int cifs_file_mmap(struct file *file, struct vm_area_struct *vma); +extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma); extern const struct file_operations cifs_dir_ops; extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_readdir(struct file *file, struct dir_context *ctx); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1420acf987f03..cd3a173e65b1c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -785,6 +785,7 @@ static inline unsigned int in_flight(struct TCP_Server_Info *server) { unsigned int num; + spin_lock(&server->req_lock); num = server->in_flight; spin_unlock(&server->req_lock); @@ -795,6 +796,7 @@ static inline bool has_credits(struct TCP_Server_Info *server, int *credits, int num_credits) { int num; + spin_lock(&server->req_lock); num = *credits; spin_unlock(&server->req_lock); @@ -1025,7 +1027,7 @@ struct cifs_ses { struct TCP_Server_Info *server; /* pointer to server info */ int ses_count; /* reference counter */ enum ses_status_enum ses_status; /* updates protected by cifs_tcp_ses_lock */ - unsigned overrideSecFlg; /* if non-zero override global sec flags */ + unsigned int overrideSecFlg; /* if non-zero override global sec flags */ char *serverOS; /* name of operating system underlying server */ char *serverNOS; /* name of network operating system of server */ char *serverDomain; /* security realm of server */ @@ -1381,7 +1383,7 @@ struct cifsFileInfo { __u32 pid; /* process id who opened file */ struct cifs_fid fid; /* file id from remote */ struct list_head rlist; /* reconnect list */ - /* BB add lock scope info here if needed */ ; + /* BB add lock scope info here if needed */ /* lock scope id (0 if none) */ struct dentry *dentry; struct tcon_link *tlink; @@ -1769,6 +1771,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, int number_of_items) { int i; + if ((number_of_items == 0) || (param == NULL)) return; for (i = 0; i < number_of_items; i++) { -- GitLab From 9544597b5b63ff1674d60e069f93555ab924b62b Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 9 Dec 2022 16:55:51 -0600 Subject: [PATCH 1416/1480] cifs: fix various whitespace errors in headers Fix some extra spaces and a few comments that were unnecessarily split over two lines. These were some trivial issues pointed out by checkpatch) Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 50 +++++++++++++++++++-------------------------- fs/cifs/cifsproto.h | 2 +- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index d1abaeea974a9..623caece2b10c 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1429,7 +1429,7 @@ typedef struct smb_com_transaction_change_notify_req { __u8 WatchTree; /* 1 = Monitor subdirectories */ __u8 Reserved2; __le16 ByteCount; -/* __u8 Pad[3];*/ +/* __u8 Pad[3];*/ /* __u8 Data[1];*/ } __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; @@ -1752,8 +1752,7 @@ struct smb_com_transaction2_sfi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ struct trans2_resp t2; __u16 ByteCount; - __u16 Reserved2; /* parameter word reserved - - present for infolevels > 100 */ + __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ } __attribute__((packed)); struct smb_t2_qfi_req { @@ -1768,8 +1767,7 @@ struct smb_t2_qfi_rsp { struct smb_hdr hdr; /* wct = 10 + SetupCount */ struct trans2_resp t2; __u16 ByteCount; - __u16 Reserved2; /* parameter word reserved - - present for infolevels > 100 */ + __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ } __attribute__((packed)); /* @@ -2146,13 +2144,11 @@ typedef struct { #define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based calls including posix open and posix unlink */ -#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up - to 0xFFFF00 */ +#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up to 0xFFFF00 */ #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */ #define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */ -#define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and - QFS PROXY call */ +#define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and QFS PROXY call */ #ifdef CONFIG_CIFS_POSIX /* presumably don't need the 0x20 POSIX_PATH_OPS_CAP since we never send LockingX instead of posix locking call on unix sess (and we do not expect @@ -2368,8 +2364,7 @@ typedef struct { struct file_allocation_info { __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */ -} __attribute__((packed)); /* size used on disk, for level 0x103 for set, - 0x105 for query */ +} __packed; /* size used on disk, for level 0x103 for set, 0x105 for query */ struct file_end_of_file_info { __le64 FileSize; /* offset to end of file */ @@ -2409,8 +2404,7 @@ struct cifs_posix_acl { /* access conrol list (ACL) */ __le16 access_entry_count; /* access ACL - count of entries */ __le16 default_entry_count; /* default ACL - count of entries */ struct cifs_posix_ace ace_array[]; - /* followed by - struct cifs_posix_ace default_ace_arraay[] */ + /* followed by struct cifs_posix_ace default_ace_array[] */ } __attribute__((packed)); /* level 0x204 */ /* types of access control entries already defined in posix_acl.h */ @@ -2429,17 +2423,17 @@ struct cifs_posix_acl { /* access conrol list (ACL) */ /* end of POSIX ACL definitions */ /* POSIX Open Flags */ -#define SMB_O_RDONLY 0x1 -#define SMB_O_WRONLY 0x2 -#define SMB_O_RDWR 0x4 -#define SMB_O_CREAT 0x10 -#define SMB_O_EXCL 0x20 -#define SMB_O_TRUNC 0x40 -#define SMB_O_APPEND 0x80 -#define SMB_O_SYNC 0x100 -#define SMB_O_DIRECTORY 0x200 -#define SMB_O_NOFOLLOW 0x400 -#define SMB_O_DIRECT 0x800 +#define SMB_O_RDONLY 0x1 +#define SMB_O_WRONLY 0x2 +#define SMB_O_RDWR 0x4 +#define SMB_O_CREAT 0x10 +#define SMB_O_EXCL 0x20 +#define SMB_O_TRUNC 0x40 +#define SMB_O_APPEND 0x80 +#define SMB_O_SYNC 0x100 +#define SMB_O_DIRECTORY 0x200 +#define SMB_O_NOFOLLOW 0x400 +#define SMB_O_DIRECT 0x800 typedef struct { __le32 OpenFlags; /* same as NT CreateX */ @@ -2716,15 +2710,13 @@ typedef struct file_xattr_info { __u32 xattr_value_len; char xattr_name[]; /* followed by xattr_value[xattr_value_len], no pad */ -} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info - level 0x205 */ +} __packed FILE_XATTR_INFO; /* extended attribute info level 0x205 */ /* flags for lsattr and chflags commands removed arein uapi/linux/fs.h */ typedef struct file_chattr_info { __le64 mask; /* list of all possible attribute bits */ __le64 mode; /* list of actual attribute bits on this inode */ -} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes - (chattr, chflags) level 0x206 */ -#endif /* POSIX */ +} __packed FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ +#endif /* POSIX */ #endif /* _CIFSPDU_H */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 83e83d8beabba..f216fa269c850 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -124,7 +124,7 @@ extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, struct kvec * /* resp vec */); extern int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *ptcon, - struct smb_hdr *in_buf , + struct smb_hdr *in_buf, struct smb_hdr *out_buf, int *bytes_returned); void -- GitLab From 2bfd81043e944af0e52835ef6d9b41795af22341 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 11 Dec 2022 13:54:21 -0600 Subject: [PATCH 1417/1480] cifs: fix missing display of three mount options Three mount options: "tcpnodelay" and "noautotune" and "noblocksend" were not displayed when passed in on cifs/smb3 mounts (e.g. displayed in /proc/mounts e.g.). No change to defaults so these are not displayed if not specified on mount. Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 712a431614480..6094cb2ff099b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -678,9 +678,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",echo_interval=%lu", tcon->ses->server->echo_interval / HZ); - /* Only display max_credits if it was overridden on mount */ + /* Only display the following if overridden on mount */ if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE) seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits); + if (tcon->ses->server->tcp_nodelay) + seq_puts(s, ",tcpnodelay"); + if (tcon->ses->server->noautotune) + seq_puts(s, ",noautotune"); + if (tcon->ses->server->noblocksnd) + seq_puts(s, ",noblocksend"); if (tcon->snapshot_time) seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); -- GitLab From 9d91f8108ebfed54284332e04d2073107df18794 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 11 Dec 2022 14:44:31 -0600 Subject: [PATCH 1418/1480] cifs: print warning when conflicting soft vs. hard mount options specified If the user specifies conflicting hard vs. soft mount options (or nosoft vs. nohard) print a warning to dmesg We were missing a warning when a user e.g. mounted with both "hard,soft" mount options. Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/fs_context.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 45119597c7655..2c92a821e0284 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -884,16 +884,21 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, ctx->nodfs = 1; break; case Opt_hard: - if (result.negated) + if (result.negated) { + if (ctx->retry == 1) + cifs_dbg(VFS, "conflicting hard vs. soft mount options\n"); ctx->retry = 0; - else + } else ctx->retry = 1; break; case Opt_soft: if (result.negated) ctx->retry = 1; - else + else { + if (ctx->retry == 1) + cifs_dbg(VFS, "conflicting hard vs soft mount options\n"); ctx->retry = 0; + } break; case Opt_mapposix: if (result.negated) -- GitLab From f7f291e14dde32a07b1f0aa06921d28f875a7b54 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Sun, 11 Dec 2022 18:18:55 -0300 Subject: [PATCH 1419/1480] cifs: fix oops during encryption When running xfstests against Azure the following oops occurred on an arm64 system Unable to handle kernel write to read-only memory at virtual address ffff0001221cf000 Mem abort info: ESR = 0x9600004f EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x0f: level 3 permission fault Data abort info: ISV = 0, ISS = 0x0000004f CM = 0, WnR = 1 swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000294f3000 [ffff0001221cf000] pgd=18000001ffff8003, p4d=18000001ffff8003, pud=18000001ff82e003, pmd=18000001ff71d003, pte=00600001221cf787 Internal error: Oops: 9600004f [#1] PREEMPT SMP ... pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) pc : __memcpy+0x40/0x230 lr : scatterwalk_copychunks+0xe0/0x200 sp : ffff800014e92de0 x29: ffff800014e92de0 x28: ffff000114f9de80 x27: 0000000000000008 x26: 0000000000000008 x25: ffff800014e92e78 x24: 0000000000000008 x23: 0000000000000001 x22: 0000040000000000 x21: ffff000000000000 x20: 0000000000000001 x19: ffff0001037c4488 x18: 0000000000000014 x17: 235e1c0d6efa9661 x16: a435f9576b6edd6c x15: 0000000000000058 x14: 0000000000000001 x13: 0000000000000008 x12: ffff000114f2e590 x11: ffffffffffffffff x10: 0000040000000000 x9 : ffff8000105c3580 x8 : 2e9413b10000001a x7 : 534b4410fb86b005 x6 : 534b4410fb86b005 x5 : ffff0001221cf008 x4 : ffff0001037c4490 x3 : 0000000000000001 x2 : 0000000000000008 x1 : ffff0001037c4488 x0 : ffff0001221cf000 Call trace: __memcpy+0x40/0x230 scatterwalk_map_and_copy+0x98/0x100 crypto_ccm_encrypt+0x150/0x180 crypto_aead_encrypt+0x2c/0x40 crypt_message+0x750/0x880 smb3_init_transform_rq+0x298/0x340 smb_send_rqst.part.11+0xd8/0x180 smb_send_rqst+0x3c/0x100 compound_send_recv+0x534/0xbc0 smb2_query_info_compound+0x32c/0x440 smb2_set_ea+0x438/0x4c0 cifs_xattr_set+0x5d4/0x7c0 This is because in scatterwalk_copychunks(), we attempted to write to a buffer (@sign) that was allocated in the stack (vmalloc area) by crypt_message() and thus accessing its remaining 8 (x2) bytes ended up crossing a page boundary. To simply fix it, we could just pass @sign kmalloc'd from crypt_message() and then we're done. Luckily, we don't seem to pass any other vmalloc'd buffers in smb_rqst::rq_iov... Instead, let's map the correct pages and offsets from vmalloc buffers as well in cifs_sg_set_buf() and then avoiding such oopses. Signed-off-by: Paulo Alcantara (SUSE) Cc: stable@vger.kernel.org Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 68 +++++++++++++++++++++ fs/cifs/cifsproto.h | 4 +- fs/cifs/misc.c | 4 +- fs/cifs/smb2ops.c | 143 +++++++++++++++++++++----------------------- 4 files changed, 140 insertions(+), 79 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cd3a173e65b1c..703685e2db5e7 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -2140,4 +2142,70 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const dst->FileNameLength = src->FileNameLength; } +static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst, + int num_rqst, + const u8 *sig) +{ + unsigned int len, skip; + unsigned int nents = 0; + unsigned long addr; + int i, j; + + /* Assumes the first rqst has a transform header as the first iov. + * I.e. + * rqst[0].rq_iov[0] is transform header + * rqst[0].rq_iov[1+] data to be encrypted/decrypted + * rqst[1+].rq_iov[0+] data to be encrypted/decrypted + */ + for (i = 0; i < num_rqst; i++) { + /* + * The first rqst has a transform header where the + * first 20 bytes are not part of the encrypted blob. + */ + for (j = 0; j < rqst[i].rq_nvec; j++) { + struct kvec *iov = &rqst[i].rq_iov[j]; + + skip = (i == 0) && (j == 0) ? 20 : 0; + addr = (unsigned long)iov->iov_base + skip; + if (unlikely(is_vmalloc_addr((void *)addr))) { + len = iov->iov_len - skip; + nents += DIV_ROUND_UP(offset_in_page(addr) + len, + PAGE_SIZE); + } else { + nents++; + } + } + nents += rqst[i].rq_npages; + } + nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE); + return nents; +} + +/* We can not use the normal sg_set_buf() as we will sometimes pass a + * stack object as buf. + */ +static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg, + const void *buf, + unsigned int buflen) +{ + unsigned long addr = (unsigned long)buf; + unsigned int off = offset_in_page(addr); + + addr &= PAGE_MASK; + if (unlikely(is_vmalloc_addr((void *)addr))) { + do { + unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off); + + sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off); + + off = 0; + addr += PAGE_SIZE; + buflen -= len; + } while (buflen); + } else { + sg_set_page(sg++, virt_to_page(addr), buflen, off); + } + return sg; +} + #endif /* _CIFS_GLOB_H */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index f216fa269c850..9c6147ca029d2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -600,8 +600,8 @@ int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); int cifs_alloc_hash(const char *name, struct shash_desc **sdesc); void cifs_free_hash(struct shash_desc **sdesc); -extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, - unsigned int *len, unsigned int *offset); +void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page, + unsigned int *len, unsigned int *offset); struct cifs_chan * cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server); int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 3e68d8208cf5e..1cbecd64d697f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1136,8 +1136,8 @@ cifs_free_hash(struct shash_desc **sdesc) * @len: Where to store the length for this page: * @offset: Where to store the offset for this page */ -void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, - unsigned int *len, unsigned int *offset) +void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page, + unsigned int *len, unsigned int *offset) { *len = rqst->rq_pagesz; *offset = (page == 0) ? rqst->rq_offset : 0; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 72b22d033ed56..6e772b31e02a3 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4204,69 +4204,82 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); } -/* We can not use the normal sg_set_buf() as we will sometimes pass a - * stack object as buf. - */ -static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, - unsigned int buflen) +static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst, + int num_rqst, const u8 *sig, u8 **iv, + struct aead_request **req, struct scatterlist **sgl, + unsigned int *num_sgs) { - void *addr; - /* - * VMAP_STACK (at least) puts stack into the vmalloc address space - */ - if (is_vmalloc_addr(buf)) - addr = vmalloc_to_page(buf); - else - addr = virt_to_page(buf); - sg_set_page(sg, addr, buflen, offset_in_page(buf)); + unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm); + unsigned int iv_size = crypto_aead_ivsize(tfm); + unsigned int len; + u8 *p; + + *num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig); + + len = iv_size; + len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1); + len = ALIGN(len, crypto_tfm_ctx_alignment()); + len += req_size; + len = ALIGN(len, __alignof__(struct scatterlist)); + len += *num_sgs * sizeof(**sgl); + + p = kmalloc(len, GFP_ATOMIC); + if (!p) + return NULL; + + *iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1); + *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size, + crypto_tfm_ctx_alignment()); + *sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size, + __alignof__(struct scatterlist)); + return p; } -/* Assumes the first rqst has a transform header as the first iov. - * I.e. - * rqst[0].rq_iov[0] is transform header - * rqst[0].rq_iov[1+] data to be encrypted/decrypted - * rqst[1+].rq_iov[0+] data to be encrypted/decrypted - */ -static struct scatterlist * -init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign) +static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst, + int num_rqst, const u8 *sig, u8 **iv, + struct aead_request **req, struct scatterlist **sgl) { - unsigned int sg_len; + unsigned int off, len, skip; struct scatterlist *sg; - unsigned int i; - unsigned int j; - unsigned int idx = 0; - int skip; - - sg_len = 1; - for (i = 0; i < num_rqst; i++) - sg_len += rqst[i].rq_nvec + rqst[i].rq_npages; + unsigned int num_sgs; + unsigned long addr; + int i, j; + void *p; - sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL); - if (!sg) + p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs); + if (!p) return NULL; - sg_init_table(sg, sg_len); + sg_init_table(*sgl, num_sgs); + sg = *sgl; + + /* Assumes the first rqst has a transform header as the first iov. + * I.e. + * rqst[0].rq_iov[0] is transform header + * rqst[0].rq_iov[1+] data to be encrypted/decrypted + * rqst[1+].rq_iov[0+] data to be encrypted/decrypted + */ for (i = 0; i < num_rqst; i++) { + /* + * The first rqst has a transform header where the + * first 20 bytes are not part of the encrypted blob. + */ for (j = 0; j < rqst[i].rq_nvec; j++) { - /* - * The first rqst has a transform header where the - * first 20 bytes are not part of the encrypted blob - */ - skip = (i == 0) && (j == 0) ? 20 : 0; - smb2_sg_set_buf(&sg[idx++], - rqst[i].rq_iov[j].iov_base + skip, - rqst[i].rq_iov[j].iov_len - skip); - } + struct kvec *iov = &rqst[i].rq_iov[j]; + skip = (i == 0) && (j == 0) ? 20 : 0; + addr = (unsigned long)iov->iov_base + skip; + len = iov->iov_len - skip; + sg = cifs_sg_set_buf(sg, (void *)addr, len); + } for (j = 0; j < rqst[i].rq_npages; j++) { - unsigned int len, offset; - - rqst_page_get_length(&rqst[i], j, &len, &offset); - sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset); + rqst_page_get_length(&rqst[i], j, &len, &off); + sg_set_page(sg++, rqst[i].rq_pages[j], len, off); } } - smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE); - return sg; + cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE); + + return p; } static int @@ -4314,11 +4327,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, u8 sign[SMB2_SIGNATURE_SIZE] = {}; u8 key[SMB3_ENC_DEC_KEY_SIZE]; struct aead_request *req; - char *iv; - unsigned int iv_len; + u8 *iv; DECLARE_CRYPTO_WAIT(wait); struct crypto_aead *tfm; unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize); + void *creq; rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key); if (rc) { @@ -4352,32 +4365,15 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, return rc; } - req = aead_request_alloc(tfm, GFP_KERNEL); - if (!req) { - cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); + creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg); + if (unlikely(!creq)) return -ENOMEM; - } if (!enc) { memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE); crypt_len += SMB2_SIGNATURE_SIZE; } - sg = init_sg(num_rqst, rqst, sign); - if (!sg) { - cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__); - rc = -ENOMEM; - goto free_req; - } - - iv_len = crypto_aead_ivsize(tfm); - iv = kzalloc(iv_len, GFP_KERNEL); - if (!iv) { - cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__); - rc = -ENOMEM; - goto free_sg; - } - if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) || (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE); @@ -4386,6 +4382,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE); } + aead_request_set_tfm(req, tfm); aead_request_set_crypt(req, sg, sg, crypt_len, iv); aead_request_set_ad(req, assoc_data_len); @@ -4398,11 +4395,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, if (!rc && enc) memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); - kfree_sensitive(iv); -free_sg: - kfree_sensitive(sg); -free_req: - kfree_sensitive(req); + kfree_sensitive(creq); return rc; } -- GitLab From a9438b44bc7015b18931e312bbd249a25bb59a65 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 12 Dec 2022 12:36:33 +0100 Subject: [PATCH 1420/1480] writeback: Add asserts for adding freed inode to lists In the past we had several use-after-free issues with inodes getting added to writeback lists after evict() removed them. These are painful to debug so add some asserts to catch the problem earlier. The only non-obvious change in the commit is that we need to tweak redirty_tail_locked() to avoid triggering assertion in inode_io_list_move_locked(). Signed-off-by: Jan Kara Link: https://lore.kernel.org/r/20221212113633.29181-1-jack@suse.cz Signed-off-by: Jens Axboe --- fs/fs-writeback.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 443f83382b9bd..6cd172c4cb3e2 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -121,6 +121,7 @@ static bool inode_io_list_move_locked(struct inode *inode, { assert_spin_locked(&wb->list_lock); assert_spin_locked(&inode->i_lock); + WARN_ON_ONCE(inode->i_state & I_FREEING); list_move(&inode->i_io_list, head); @@ -280,6 +281,7 @@ static void inode_cgwb_move_to_attached(struct inode *inode, { assert_spin_locked(&wb->list_lock); assert_spin_locked(&inode->i_lock); + WARN_ON_ONCE(inode->i_state & I_FREEING); inode->i_state &= ~I_SYNC_QUEUED; if (wb != &wb->bdi->wb) @@ -1129,6 +1131,7 @@ static void inode_cgwb_move_to_attached(struct inode *inode, { assert_spin_locked(&wb->list_lock); assert_spin_locked(&inode->i_lock); + WARN_ON_ONCE(inode->i_state & I_FREEING); inode->i_state &= ~I_SYNC_QUEUED; list_del_init(&inode->i_io_list); @@ -1294,6 +1297,17 @@ static void redirty_tail_locked(struct inode *inode, struct bdi_writeback *wb) { assert_spin_locked(&inode->i_lock); + inode->i_state &= ~I_SYNC_QUEUED; + /* + * When the inode is being freed just don't bother with dirty list + * tracking. Flush worker will ignore this inode anyway and it will + * trigger assertions in inode_io_list_move_locked(). + */ + if (inode->i_state & I_FREEING) { + list_del_init(&inode->i_io_list); + wb_io_lists_depopulated(wb); + return; + } if (!list_empty(&wb->b_dirty)) { struct inode *tail; @@ -1302,7 +1316,6 @@ static void redirty_tail_locked(struct inode *inode, struct bdi_writeback *wb) inode->dirtied_when = jiffies; } inode_io_list_move_locked(inode, wb, &wb->b_dirty); - inode->i_state &= ~I_SYNC_QUEUED; } static void redirty_tail(struct inode *inode, struct bdi_writeback *wb) -- GitLab From 23e188a16423a6e65290abf39dd427ff047e6843 Mon Sep 17 00:00:00 2001 From: Miaohe Lin Date: Sat, 10 Dec 2022 18:10:42 +0800 Subject: [PATCH 1421/1480] writeback: remove obsolete macro EXPIRE_DIRTY_ATIME EXPIRE_DIRTY_ATIME is not used anymore. Remove it. Signed-off-by: Miaohe Lin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20221210101042.2012931-1-linmiaohe@huawei.com Signed-off-by: Jens Axboe --- fs/fs-writeback.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 6cd172c4cb3e2..6c113585e7824 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1358,8 +1358,6 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t) return ret; } -#define EXPIRE_DIRTY_ATIME 0x0001 - /* * Move expired (dirtied before dirtied_before) dirty inodes from * @delaying_queue to @dispatch_queue. -- GitLab From d1f0f50fbbbbca1e3e8157e51934613bf88f6d44 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Thu, 8 Dec 2022 09:33:41 +0800 Subject: [PATCH 1422/1480] samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() Add missing pci_disable_device() in fail path of mdpy_fb_probe(). Besides, fix missing release functions in mdpy_fb_remove(). Fixes: cacade1946a4 ("sample: vfio mdev display - guest driver") Signed-off-by: Shang XiaoJing Link: https://lore.kernel.org/r/20221208013341.3999-1-shangxiaojing@huawei.com Signed-off-by: Alex Williamson --- samples/vfio-mdev/mdpy-fb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c index 9ec93d90e8a5a..4eb7aa11cfbb2 100644 --- a/samples/vfio-mdev/mdpy-fb.c +++ b/samples/vfio-mdev/mdpy-fb.c @@ -109,7 +109,7 @@ static int mdpy_fb_probe(struct pci_dev *pdev, ret = pci_request_regions(pdev, "mdpy-fb"); if (ret < 0) - return ret; + goto err_disable_dev; pci_read_config_dword(pdev, MDPY_FORMAT_OFFSET, &format); pci_read_config_dword(pdev, MDPY_WIDTH_OFFSET, &width); @@ -191,6 +191,9 @@ err_release_fb: err_release_regions: pci_release_regions(pdev); +err_disable_dev: + pci_disable_device(pdev); + return ret; } @@ -199,7 +202,10 @@ static void mdpy_fb_remove(struct pci_dev *pdev) struct fb_info *info = pci_get_drvdata(pdev); unregister_framebuffer(info); + iounmap(info->screen_base); framebuffer_release(info); + pci_release_regions(pdev); + pci_disable_device(pdev); } static struct pci_device_id mdpy_fb_pci_table[] = { -- GitLab From fe3dd71db2b81c202bc80532bbe0e07238a45ed9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 8 Dec 2022 19:01:26 +0300 Subject: [PATCH 1423/1480] vfio/mlx5: fix error code in mlx5vf_precopy_ioctl() The copy_to_user() function returns the number of bytes remaining to be copied but we want to return a negative error code here. Fixes: 0dce165b1adf ("vfio/mlx5: Introduce vfio precopy ioctl implementation") Signed-off-by: Dan Carpenter Reviewed-by: Yishai Hadas Link: https://lore.kernel.org/r/Y5IKVknlf5Z5NPtU@kili Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index cd90eb86128c3..94f7a0fd10e85 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -404,7 +404,10 @@ static long mlx5vf_precopy_ioctl(struct file *filp, unsigned int cmd, done: mlx5vf_state_mutex_unlock(mvdev); - return copy_to_user((void __user *)arg, &info, minsz); + if (copy_to_user((void __user *)arg, &info, minsz)) + return -EFAULT; + return 0; + err_migf_unlock: mutex_unlock(&migf->lock); err_state_unlock: -- GitLab From 70be6f322860d322ebcd120cf0c05402ead5c6de Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 8 Dec 2022 19:02:17 +0300 Subject: [PATCH 1424/1480] vfio/mlx5: error pointer dereference in error handling This code frees the wrong "buf" variable and results in an error pointer dereference. Fixes: 34e2f27143d1 ("vfio/mlx5: Introduce multiple loads") Signed-off-by: Dan Carpenter Reviewed-by: Yishai Hadas Link: https://lore.kernel.org/r/Y5IKia5SaiVxYmG5@kili Signed-off-by: Alex Williamson --- drivers/vfio/pci/mlx5/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 94f7a0fd10e85..031ac8cc215d4 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -826,7 +826,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) spin_lock_init(&migf->list_lock); return migf; out_buf: - mlx5vf_free_data_buffer(buf); + mlx5vf_free_data_buffer(migf->buf); out_pd: mlx5vf_cmd_dealloc_pd(migf); out_free: -- GitLab From 40306b4d1ba25970dafd53432e8daa5d591ebd99 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Tue, 13 Dec 2022 09:40:32 +0800 Subject: [PATCH 1425/1480] exfat: fix overflow in sector and cluster conversion According to the exFAT specification, there are at most 2^32-11 clusters in a volume. so using 'int' is not enough for cluster index, the return value type of exfat_sector_to_cluster() should be 'unsigned int'. Signed-off-by: Yuezhang Mo Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/exfat_fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index a1e7feb220797..bc6d21d7c5adf 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -400,7 +400,7 @@ static inline sector_t exfat_cluster_to_sector(struct exfat_sb_info *sbi, sbi->data_start_sector; } -static inline int exfat_sector_to_cluster(struct exfat_sb_info *sbi, +static inline unsigned int exfat_sector_to_cluster(struct exfat_sb_info *sbi, sector_t sec) { return ((sec - sbi->data_start_sector) >> sbi->sect_per_clus_bits) + -- GitLab From 36955d368dc101be885ad2c71618e3c3a93cd8ee Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 17 Nov 2022 11:31:30 +0800 Subject: [PATCH 1426/1480] exfat: reuse exfat_find_location() to simplify exfat_get_dentry_set() In exfat_get_dentry_set(), part of the code is the same as exfat_find_location(), reuse exfat_find_location() to simplify exfat_get_dentry_set(). Code refinement, no functional changes. Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon --- fs/exfat/dir.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 8121a7e073bc7..1dfa67f307f17 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -818,7 +818,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, unsigned int type) { int ret, i, num_bh; - unsigned int off, byte_offset, clu = 0; + unsigned int off; sector_t sec; struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_dentry *ep; @@ -831,27 +831,16 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, return -EIO; } - byte_offset = EXFAT_DEN_TO_B(entry); - ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu); + ret = exfat_find_location(sb, p_dir, entry, &sec, &off); if (ret) return ret; memset(es, 0, sizeof(*es)); es->sb = sb; es->modified = false; - - /* byte offset in cluster */ - byte_offset = EXFAT_CLU_OFFSET(byte_offset, sbi); - - /* byte offset in sector */ - off = EXFAT_BLK_OFFSET(byte_offset, sb); es->start_off = off; es->bh = es->__bh; - /* sector offset in cluster */ - sec = EXFAT_B_TO_BLK(byte_offset, sb); - sec += exfat_cluster_to_sector(sbi, clu); - bh = sb_bread(sb, sec); if (!bh) return -EIO; @@ -878,6 +867,8 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, for (i = 1; i < num_bh; i++) { /* get the next sector */ if (exfat_is_last_sector_in_cluster(sbi, sec)) { + unsigned int clu = exfat_sector_to_cluster(sbi, sec); + if (p_dir->flags == ALLOC_NO_FAT_CHAIN) clu++; else if (exfat_get_next_cluster(sb, &clu)) -- GitLab From a785736d7e587abbfd59df44e9a815d8d109c28c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 13 Dec 2022 09:56:02 -0500 Subject: [PATCH 1427/1480] tracing: Have trigger filter parsing errors show up in error_log It is annoying that the filter parsing of triggers do not show up in the error_log. Trying to figure out what is incorrect in the input is difficult when it fails for a typo. Have the errors of filter parsing show up in error_log as well. Link: https://lore.kernel.org/linux-trace-kernel/20221213095602.083fa9fd@gandalf.local.home Cc: Masami Hiramatsu Cc: Tom Zanussi Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_trigger.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 918730d749325..19ce9d22bfd7c 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -1067,7 +1067,14 @@ int set_trigger_filter(char *filter_str, /* The filter is for the 'trigger' event, not the triggered event */ ret = create_event_filter(file->tr, file->event_call, - filter_str, false, &filter); + filter_str, true, &filter); + + /* Only enabled set_str for error handling */ + if (filter) { + kfree(filter->filter_string); + filter->filter_string = NULL; + } + /* * If create_event_filter() fails, filter still needs to be freed. * Which the calling code will do with data->filter. -- GitLab From fab89a09c86f948adfc7e20a7d608bd9f323bbe1 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Mon, 12 Dec 2022 19:38:14 -0500 Subject: [PATCH 1428/1480] tracing: Remove pointer (asterisk) and brackets from cpumask_t field To differentiate between long arrays and cpumasks, the __cpumask() field was created. Part of the TRACE_EVENT() macros test if the type is signed or not by using the is_signed_type() macro. The __cpumask() field used the __dynamic_array() helper but because cpumask_t is a structure, it could not be used in the is_signed_type() macro as that would fail to build, so instead it passed in the pointer to cpumask_t. Unfortunately, that creates in the format file: field:__data_loc cpumask_t *[] mask; offset:36; size:4; signed:0; Which looks like an array of pointers to cpumask_t and not a cpumask_t type, which is misleading to user space parsers. Douglas Raillard pointed out that the "[]" are also misleading, as cpumask_t is not an array. Since cpumask() hasn't been created yet, and the parsers currently fail on it (but will still produce the raw output), make it be: field:__data_loc cpumask_t mask; offset:36; size:4; signed:0; Which is the correct type of the field. Then the parsers can be updated to handle this. Link: https://lore.kernel.org/lkml/6dda5e1d-9416-b55e-88f3-31d148bc925f@arm.com/ Link: https://lore.kernel.org/linux-trace-kernel/20221212193814.0e3f1e43@gandalf.local.home Cc: Masami Hiramatsu Cc: Valentin Schneider Cc: Andrew Morton Fixes: 8230f27b1ccc ("tracing: Add __cpumask to denote a trace event field that is a cpumask_t") Reported-by: Douglas Raillard Signed-off-by: Steven Rostedt (Google) --- include/trace/stages/stage4_event_fields.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/trace/stages/stage4_event_fields.h b/include/trace/stages/stage4_event_fields.h index f2990d22313cf..affd541fd25ea 100644 --- a/include/trace/stages/stage4_event_fields.h +++ b/include/trace/stages/stage4_event_fields.h @@ -47,7 +47,10 @@ #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) #undef __cpumask -#define __cpumask(item) __dynamic_array(cpumask_t *, item, -1) +#define __cpumask(item) { \ + .type = "__data_loc cpumask_t", .name = #item, \ + .size = 4, .align = 4, \ + .is_signed = 0, .filter_type = FILTER_OTHER }, #undef __sockaddr #define __sockaddr(field, len) __dynamic_array(u8, field, len) @@ -68,7 +71,10 @@ #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1) #undef __rel_cpumask -#define __rel_cpumask(item) __rel_dynamic_array(cpumask_t *, item, -1) +#define __rel_cpumask(item) { \ + .type = "__rel_loc cpumask_t", .name = #item, \ + .size = 4, .align = 4, \ + .is_signed = 0, .filter_type = FILTER_OTHER }, #undef __rel_sockaddr #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len) -- GitLab From d74f4a3f6d88a2416564bc6bf937e423a4ae8f8e Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 14 Dec 2022 10:39:11 +0800 Subject: [PATCH 1429/1480] cifs: Remove duplicated include in cifsglob.h ./fs/cifs/cifsglob.h: linux/scatterlist.h is included more than once. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3459 Fixes: f7f291e14dde ("cifs: fix oops during encryption") Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 703685e2db5e7..82f2d3070c266 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -23,7 +23,6 @@ #include "cifs_fs_sb.h" #include "cifsacl.h" #include -#include #include #include "../smbfs_common/smb2pdu.h" #include "smb2pdu.h" -- GitLab From fb9f5ee9bf5cf7ebc8731a7033e57d98832dc650 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 13 Dec 2022 17:24:29 -0500 Subject: [PATCH 1430/1480] tracing: Do not synchronize freeing of trigger filter on boot up If a trigger filter on the kernel command line fails to apply (due to syntax error), it will be freed. The freeing will call tracepoint_synchronize_unregister(), but this is not needed during early boot up, and will even trigger a lockdep splat. Avoid calling the synchronization function when system_state is SYSTEM_BOOTING. Link: https://lore.kernel.org/linux-trace-kernel/20221213172429.7774f4ba@gandalf.local.home Cc: Andrew Morton Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_trigger.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 19ce9d22bfd7c..e535959939d3f 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -1085,8 +1085,14 @@ int set_trigger_filter(char *filter_str, rcu_assign_pointer(data->filter, filter); if (tmp) { - /* Make sure the call is done with the filter */ - tracepoint_synchronize_unregister(); + /* + * Make sure the call is done with the filter. + * It is possible that a filter could fail at boot up, + * and then this path will be called. Avoid the synchronization + * in that case. + */ + if (system_state != SYSTEM_BOOTING) + tracepoint_synchronize_unregister(); free_event_filter(tmp); } -- GitLab From 3c97d25ceb75fd3e660ba9fcd4c630d0b057a5a2 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 5 Dec 2022 09:34:04 -0300 Subject: [PATCH 1431/1480] perf stat: Check existence of os->prefix, fixing a segfault We need to check if we have a OS prefix, otherwise we stumble on a metric segv that I'm now seeing in Arnaldo's tree: $ gdb --args perf stat -M Backend true ... Performance counter stats for 'true': 4,712,355 TOPDOWN.SLOTS # 17.3 % tma_core_bound Program received signal SIGSEGV, Segmentation fault. __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:77 77 ../sysdeps/x86_64/multiarch/strlen-evex.S: No such file or directory. (gdb) bt #0 __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:77 #1 0x00007ffff74749a5 in __GI__IO_fputs (str=0x0, fp=0x7ffff75f5680 <_IO_2_1_stderr_>) #2 0x0000555555779f28 in do_new_line_std (config=0x555555e077c0 , os=0x7fffffffbf10) at util/stat-display.c:356 #3 0x000055555577a081 in print_metric_std (config=0x555555e077c0 , ctx=0x7fffffffbf10, color=0x0, fmt=0x5555558b77b5 "%8.1f", unit=0x7fffffffbb10 "% tma_memory_bound", val=13.165355724442199) at util/stat-display.c:380 #4 0x00005555557768b6 in generic_metric (config=0x555555e077c0 , metric_expr=0x55555593d5b7 "((CYCLE_ACTIVITY.STALLS_MEM_ANY + EXE_ACTIVITY.BOUND_ON_STORES) / (CYCLE_ACTIVITY.STALLS_TOTAL + (EXE_ACTIVITY.1_PORTS_UTIL + tma_retiring * EXE_ACTIVITY.2_PORTS_UTIL) + EXE_ACTIVITY.BOUND_ON_STORES))"..., metric_events=0x555555f334e0, metric_refs=0x555555ec81d0, name=0x555555f32e80 "TOPDOWN.SLOTS", metric_name=0x555555f26c80 "tma_memory_bound", metric_unit=0x55555593d5b1 "100%", runtime=0, map_idx=0, out=0x7fffffffbd90, st=0x555555e9e620 ) at util/stat-shadow.c:934 #5 0x0000555555778cac in perf_stat__print_shadow_stats (config=0x555555e077c0 , evsel=0x555555f289d0, avg=4712355, map_idx=0, out=0x7fffffffbd90, metric_events=0x555555e078e8 , st=0x555555e9e620 ) at util/stat-shadow.c:1329 #6 0x000055555577b6a0 in printout (config=0x555555e077c0 , os=0x7fffffffbf10, uval=4712355, run=325322, ena=325322, noise=4712355, map_idx=0) at util/stat-display.c:741 #7 0x000055555577bc74 in print_counter_aggrdata (config=0x555555e077c0 , counter=0x555555f289d0, s=0, os=0x7fffffffbf10) at util/stat-display.c:838 #8 0x000055555577c1d8 in print_counter (config=0x555555e077c0 , counter=0x555555f289d0, os=0x7fffffffbf10) at util/stat-display.c:957 #9 0x000055555577dba0 in evlist__print_counters (evlist=0x555555ec3610, config=0x555555e077c0 , _target=0x555555e01c80 , ts=0x0, argc=1, argv=0x7fffffffe450) at util/stat-display.c:1413 #10 0x00005555555fc821 in print_counters (ts=0x0, argc=1, argv=0x7fffffffe450) at builtin-stat.c:1040 #11 0x000055555560091a in cmd_stat (argc=1, argv=0x7fffffffe450) at builtin-stat.c:2665 #12 0x00005555556b1eea in run_builtin (p=0x555555e11f70 , argc=4, argv=0x7fffffffe450) at perf.c:322 #13 0x00005555556b2181 in handle_internal_command (argc=4, argv=0x7fffffffe450) at perf.c:376 #14 0x00005555556b22d7 in run_argv (argcp=0x7fffffffe27c, argv=0x7fffffffe270) at perf.c:420 #15 0x00005555556b26ef in main (argc=4, argv=0x7fffffffe450) at perf.c:550 (gdb) Fixes: f123b2d84ecec9a3 ("perf stat: Remove prefix argument in print_metric_headers()") Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Xing Zhengjun Link: http://lore.kernel.org/lkml/CAP-5=fUOjSM5HajU9TCD6prY39LbX4OQbkEbtKPPGRBPBN=_VQ@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f1ee4b0521986..9b7772e6abf65 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -353,7 +353,8 @@ static void do_new_line_std(struct perf_stat_config *config, struct outstate *os) { fputc('\n', os->fh); - fputs(os->prefix, os->fh); + if (os->prefix) + fputs(os->prefix, os->fh); aggr_printout(config, os->evsel, os->id, os->nr); if (config->aggr_mode == AGGR_NONE) fprintf(os->fh, " "); -- GitLab From 955f6def5590ce6ca11a1c1ced0d2d1c95421059 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Mon, 5 Dec 2022 12:14:43 +0530 Subject: [PATCH 1432/1480] perf record: Add remaining branch filters: "no_cycles", "no_flags" & "hw_index" This adds all remaining branch filters i.e "no_cycles", "no_flags" and "hw_index". While here, also updates the documentation. Signed-off-by: Anshuman Khandual Cc: James Clark Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20221205064443.533587-1-anshuman.khandual@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 5 +++++ tools/perf/util/parse-branch-options.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 9ea6d44aca58c..5f9fa07b3ddec 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -388,6 +388,7 @@ following filters are defined: - any_call: any function call or system call - any_ret: any function return or system call return - ind_call: any indirect branch + - ind_jmp: any indirect jump - call: direct calls, including far (to/from kernel) calls - u: only when the branch target is at the user level - k: only when the branch target is in the kernel @@ -396,6 +397,10 @@ following filters are defined: - no_tx: only when the target is not in a hardware transaction - abort_tx: only when the target is a hardware transaction abort - cond: conditional branches + - call_stack: save call stack + - no_flags: don't save branch flags e.g prediction, misprediction etc + - no_cycles: don't save branch cycles + - hw_index: save branch hardware index - save_type: save branch type during sampling in case binary is not available later For the platforms with Intel Arch LBR support (12th-Gen+ client or 4th-Gen Xeon+ server), the save branch type is unconditionally enabled diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 31faf2bb49ff1..fd67d204d720d 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -30,8 +30,11 @@ static const struct branch_mode branch_modes[] = { BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND), BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL), + BRANCH_OPT("no_flags", PERF_SAMPLE_BRANCH_NO_FLAGS), + BRANCH_OPT("no_cycles", PERF_SAMPLE_BRANCH_NO_CYCLES), BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE), BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK), + BRANCH_OPT("hw_index", PERF_SAMPLE_BRANCH_HW_INDEX), BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE), BRANCH_END }; -- GitLab From 8f4b1e3cebce5d12048409393de751e4d663ce42 Mon Sep 17 00:00:00 2001 From: Athira Rajeev Date: Mon, 5 Dec 2022 09:58:52 +0530 Subject: [PATCH 1433/1480] perf stat: Fix printing field separator in CSV metrics output In 'perf stat' with CSV output option, number of fields in metrics output is not matching with number of fields in other event output lines. Sample output below after applying patch to fix printing os->prefix. # ./perf stat -x, --per-socket -a -C 1 ls S0,1,82.11,msec,cpu-clock,82111626,100.00,1.000,CPUs utilized S0,1,2,,context-switches,82109314,100.00,24.358,/sec ------ ====> S0,1,,,,,,,1.71,stalled cycles per insn The above command line uses field separator as "," via "-x," option and per-socket option displays socket value as first field. But here the last line for "stalled cycles per insn" has more separators. Each csv output line is expected to have 8 field separators (for the 9 fields), where as last line has 9 "," in the result. Patch fixes this issue. The counter stats are displayed by function "perf_stat__print_shadow_stats" in code "util/stat-shadow.c". While printing the stats info for "stalled cycles per insn", function "new_line_csv" is used as new_line callback. The fields printed in each line contains: "Socket_id,aggr nr,Avg,unit,event_name,run,enable_percent,ratio,unit" The metric output prints Socket_id, aggr nr, ratio and unit. It has to skip through remaining five fields ie, Avg,unit,event_name,run,enable_percent. The csv line callback uses "os->nfields" to know the number of fields to skip to match with other lines. Currently it is set as: os.nfields = 3 + aggr_fields[config->aggr_mode] + (counter->cgrp ? 1 : 0); But in case of aggregation modes, csv_sep already gets printed along with each field (Function "aggr_printout" in util/stat-display.c). So aggr_fields can be removed from nfields. And fixed number of fields to skip has to be "4". This is to skip fields for: "avg, unit, event name, run, enable_percent" This needs 4 csv separators. Patch removes aggr_fields and uses 4 as fixed number of os->nfields to skip. After the patch: # ./perf stat -x, --per-socket -a -C 1 ls S0,1,79.08,msec,cpu-clock,79085956,100.00,1.000,CPUs utilized S0,1,7,,context-switches,79084176,100.00,88.514,/sec ------ ====> S0,1,,,,,,0.81,stalled cycles per insn Fixes: 92a61f6412d3a09d ("perf stat: Implement CSV metrics output") Reported-by: Disha Goel Reviewed-by: Kajol Jain Signed-off-by: Athira Jajeev Tested-by: Arnaldo Carvalho de Melo Tested-by: Disha Goel Cc: Andi Kleen Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nageswara R Sastry Cc: Namhyung Kim Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20221205042852.83382-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 9b7772e6abf65..660e4f6616f55 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -687,20 +687,9 @@ static void printout(struct perf_stat_config *config, struct outstate *os, struct evsel *counter = os->evsel; if (config->csv_output) { - static const int aggr_fields[AGGR_MAX] = { - [AGGR_NONE] = 1, - [AGGR_GLOBAL] = 0, - [AGGR_SOCKET] = 2, - [AGGR_DIE] = 2, - [AGGR_CORE] = 2, - [AGGR_THREAD] = 1, - [AGGR_UNSET] = 0, - [AGGR_NODE] = 1, - }; - pm = config->metric_only ? print_metric_only_csv : print_metric_csv; nl = config->metric_only ? new_line_metric : new_line_csv; - os->nfields = 3 + aggr_fields[config->aggr_mode] + (counter->cgrp ? 1 : 0); + os->nfields = 4 + (counter->cgrp ? 1 : 0); } else if (config->json_output) { pm = config->metric_only ? print_metric_only_json : print_metric_json; nl = config->metric_only ? new_line_metric : new_line_json; -- GitLab From 1849f9f00926c54fa284be3b7f801de8b010572b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 1 Dec 2022 20:57:39 -0800 Subject: [PATCH 1434/1480] tools lib api: Add dependency test to install_headers Compute the headers to be installed from their source headers and make each have its own build target to install it. Using dependencies avoids headers being reinstalled and getting a new timestamp which then causes files that depend on the header to be rebuilt. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Mark Rutland Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Rix Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20221202045743.2639466-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 3649c7f7ea651..044860ac1ed1c 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -88,10 +88,10 @@ define do_install_mkdir endef define do_install - if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ - fi; \ - $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' + if [ ! -d '$2' ]; then \ + $(INSTALL) -d -m 755 '$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$2' endef install_lib: $(LIBFILE) @@ -99,14 +99,28 @@ install_lib: $(LIBFILE) $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) -install_headers: - $(call QUIET_INSTALL, libapi_headers) \ - $(call do_install,cpu.h,$(prefix)/include/api,644); \ - $(call do_install,debug.h,$(prefix)/include/api,644); \ - $(call do_install,io.h,$(prefix)/include/api,644); \ - $(call do_install,fd/array.h,$(prefix)/include/api/fd,644); \ - $(call do_install,fs/fs.h,$(prefix)/include/api/fs,644); \ - $(call do_install,fs/tracing_path.h,$(prefix)/include/api/fs,644); +HDRS := cpu.h debug.h io.h +FD_HDRS := fd/array.h +FS_HDRS := fs/fs.h fs/tracing_path.h +INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/api +INSTALL_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) +INSTALL_FD_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(FD_HDRS)) +INSTALL_FS_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(FS_HDRS)) + +$(INSTALL_HDRS): $(INSTALL_HDRS_PFX)/%.h: %.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/,644) + +$(INSTALL_FD_HDRS): $(INSTALL_HDRS_PFX)/fd/%.h: fd/%.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/fd/,644) + +$(INSTALL_FS_HDRS): $(INSTALL_HDRS_PFX)/fs/%.h: fs/%.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/fs/,644) + +install_headers: $(INSTALL_HDRS) $(INSTALL_FD_HDRS) $(INSTALL_FS_HDRS) + $(call QUIET_INSTALL, libapi_headers) install: install_lib install_headers -- GitLab From 47e02b94a4c98dcc8072e56efaae5057174050fa Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 1 Dec 2022 20:57:40 -0800 Subject: [PATCH 1435/1480] tools lib perf: Add dependency test to install_headers Compute the headers to be installed from their source headers and make each have its own build target to install it. Using dependencies avoids headers being reinstalled and getting a new timestamp which then causes files that depend on the header to be rebuilt. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Mark Rutland Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Rix Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20221202045743.2639466-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/Makefile | 43 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index a90fb8c6bed4d..30b7f91e71472 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -176,10 +176,10 @@ define do_install_mkdir endef define do_install - if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ - fi; \ - $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' + if [ ! -d '$2' ]; then \ + $(INSTALL) -d -m 755 '$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$2' endef install_lib: libs @@ -187,23 +187,24 @@ install_lib: libs $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ) -install_headers: - $(call QUIET_INSTALL, libperf_headers) \ - $(call do_install,include/perf/bpf_perf.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/core.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/cpumap.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/event.h,$(prefix)/include/perf,644); \ - $(call do_install,include/perf/mmap.h,$(prefix)/include/perf,644); \ - $(call do_install,include/internal/cpumap.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/evlist.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/evsel.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/lib.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/mmap.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/threadmap.h,$(prefix)/include/internal,644); \ - $(call do_install,include/internal/xyarray.h,$(prefix)/include/internal,644); +HDRS := bpf_perf.h core.h cpumap.h threadmap.h evlist.h evsel.h event.h mmap.h +INTERNAL_HDRS := cpumap.h evlist.h evsel.h lib.h mmap.h threadmap.h xyarray.h + +INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/perf +INSTALL_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) +INSTALL_INTERNAL_HDRS_PFX := $(DESTDIR)$(prefix)/include/internal +INSTALL_INTERNAL_HDRS := $(addprefix $(INSTALL_INTERNAL_HDRS_PFX)/, $(INTERNAL_HDRS)) + +$(INSTALL_HDRS): $(INSTALL_HDRS_PFX)/%.h: include/perf/%.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/,644) + +$(INSTALL_INTERNAL_HDRS): $(INSTALL_INTERNAL_HDRS_PFX)/%.h: include/internal/%.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_INTERNAL_HDRS_PFX)/,644) + +install_headers: $(INSTALL_HDRS) $(INSTALL_INTERNAL_HDRS) + $(call QUIET_INSTALL, libperf_headers) install_pkgconfig: $(LIBPERF_PC) $(call QUIET_INSTALL, $(LIBPERF_PC)) \ -- GitLab From 5d890591db6bed8ca69bd4bfe0cdaca372973033 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 1 Dec 2022 20:57:41 -0800 Subject: [PATCH 1436/1480] tools lib subcmd: Add dependency test to install_headers Compute the headers to be installed from their source headers and make each have its own build target to install it. Using dependencies avoids headers being reinstalled and getting a new timestamp which then causes files that depend on the header to be rebuilt. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Mark Rutland Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Rix Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20221202045743.2639466-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/Makefile | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 9a316d8b89df5..b87213263a5e0 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -89,10 +89,10 @@ define do_install_mkdir endef define do_install - if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + if [ ! -d '$2' ]; then \ + $(INSTALL) -d -m 755 '$2'; \ fi; \ - $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' + $(INSTALL) $1 $(if $3,-m $3,) '$2' endef install_lib: $(LIBFILE) @@ -100,13 +100,16 @@ install_lib: $(LIBFILE) $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) -install_headers: - $(call QUIET_INSTALL, libsubcmd_headers) \ - $(call do_install,exec-cmd.h,$(prefix)/include/subcmd,644); \ - $(call do_install,help.h,$(prefix)/include/subcmd,644); \ - $(call do_install,pager.h,$(prefix)/include/subcmd,644); \ - $(call do_install,parse-options.h,$(prefix)/include/subcmd,644); \ - $(call do_install,run-command.h,$(prefix)/include/subcmd,644); +HDRS := exec-cmd.h help.h pager.h parse-options.h run-command.h +INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/subcmd +INSTALL_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) + +$(INSTALL_HDRS): $(INSTALL_HDRS_PFX)/%.h: %.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/,644) + +install_headers: $(INSTALL_HDRS) + $(call QUIET_INSTALL, libsubcmd_headers) install: install_lib install_headers -- GitLab From 113bb3964297467baeb1fd2c4f86d0a4142e4259 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 1 Dec 2022 20:57:42 -0800 Subject: [PATCH 1437/1480] tools lib symbol: Add dependency test to install_headers Compute the headers to be installed from their source headers and make each have its own build target to install it. Using dependencies avoids headers being reinstalled and getting a new timestamp which then causes files that depend on the header to be rebuilt. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Mark Rutland Cc: Masahiro Yamada Cc: Namhyung Kim Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Rix Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20221202045743.2639466-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/symbol/Makefile | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/lib/symbol/Makefile b/tools/lib/symbol/Makefile index ea8707b3442a7..13d43c6f92b4a 100644 --- a/tools/lib/symbol/Makefile +++ b/tools/lib/symbol/Makefile @@ -89,10 +89,10 @@ define do_install_mkdir endef define do_install - if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ - fi; \ - $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' + if [ ! -d '$2' ]; then \ + $(INSTALL) -d -m 755 '$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$2' endef install_lib: $(LIBFILE) @@ -100,9 +100,16 @@ install_lib: $(LIBFILE) $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) -install_headers: - $(call QUIET_INSTALL, libsymbol_headers) \ - $(call do_install,kallsyms.h,$(prefix)/include/symbol,644); +HDRS := kallsyms.h +INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/symbol +INSTALL_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) + +$(INSTALL_HDRS): $(INSTALL_HDRS_PFX)/%.h: %.h + $(call QUIET_INSTALL, $@) \ + $(call do_install,$<,$(INSTALL_HDRS_PFX)/,644) + +install_headers: $(INSTALL_HDRS) + $(call QUIET_INSTALL, libsymbol_headers) install: install_lib install_headers -- GitLab From 117195d9f8af74c65bf57d9b56f496b5b3655bcb Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 2 Dec 2022 11:04:47 -0800 Subject: [PATCH 1438/1480] perf stat: Fix multi-line metric output in JSON When a metric produces more than one values, it missed to print the opening bracket. Fixes: ab6baaae27357290 ("perf stat: Fix JSON output in metric-only mode") Reported-by: Weilin Wang Signed-off-by: Namhyung Kim Tested-by: Weilin Wang Cc: Adrian Hunter Cc: Athira Jajeev Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221202190447.1588680-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 660e4f6616f55..7f885b04c23fb 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -441,7 +441,7 @@ static void new_line_json(struct perf_stat_config *config, void *ctx) { struct outstate *os = ctx; - fputc('\n', os->fh); + fputs("\n{", os->fh); if (os->prefix) fprintf(os->fh, "%s", os->prefix); aggr_printout(config, os->evsel, os->id, os->nr); -- GitLab From 3f81f72d30b46efb614d93f430684c0deb8439b7 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 30 Nov 2022 11:15:21 +0000 Subject: [PATCH 1439/1480] perf stat: Fix invalid output handle In this context, 'os' is already a pointer so the extra dereference isn't required. This fixes the following test failure on aarch64: $ ./perf test "json output" -vvv 92: perf stat JSON output linter : --- start --- Checking json output: no args Test failed for input: ... Fatal error: glibc detected an invalid stdio handle ---- end ---- perf stat JSON output linter: FAILED! Fixes: e7f4da312259e618 ("perf stat: Pass struct outstate to printout()") Signed-off-by: James Clark Tested-by: Athira Jajeev Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221130111521.334152-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 7f885b04c23fb..ead4915c4a033 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -731,7 +731,7 @@ static void printout(struct perf_stat_config *config, struct outstate *os, perf_stat__print_shadow_stats(config, counter, uval, map_idx, &out, &config->metric_events, &rt_stat); } else { - pm(config, &os, /*color=*/NULL, /*format=*/NULL, /*unit=*/"", /*val=*/0); + pm(config, os, /*color=*/NULL, /*format=*/NULL, /*unit=*/"", /*val=*/0); } if (!config->metric_only) { -- GitLab From fce9a619145181ca6a41253f7de3df56b1e4ad59 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 29 Nov 2022 22:29:32 -0800 Subject: [PATCH 1440/1480] perf util: Make header guard consistent with tool Remove git reference by changing GIT_COMPAT_UTIL_H to __PERF_UTIL_H. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/20221130062935.2219247-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index c1f2d423a9ecb..63cdab0e5314c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef GIT_COMPAT_UTIL_H -#define GIT_COMPAT_UTIL_H +#ifndef __PERF_UTIL_H +#define __PERF_UTIL_H #define _BSD_SOURCE 1 /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ @@ -94,4 +94,4 @@ int do_realloc_array_as_needed(void **arr, size_t *arr_sz, size_t x, 0; \ }) -#endif /* GIT_COMPAT_UTIL_H */ +#endif /* __PERF_UTIL_H */ -- GitLab From 5b7a29fb0b7d67e5d40cd6557e073afb6a7466ab Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 29 Nov 2022 22:29:33 -0800 Subject: [PATCH 1441/1480] perf util: Add host_is_bigendian to util.h Avoid libtraceevent dependency for tep_is_bigendian or trace-event.h dependency for bigendian. Add a new host_is_bigendian to util.h, using the compiler defined __BYTE_ORDER__ when available. Committer notes: Added: #else /* !__BYTE_ORDER__ */ On that nested #ifdef block, as per Namhyung's suggestion. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt (VMware) Link: https://lore.kernel.org/r/20221130062935.2219247-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/sample-parsing.c | 4 ++-- tools/perf/util/evsel.c | 5 +---- tools/perf/util/trace-event-info.c | 14 +++----------- tools/perf/util/trace-event-read.c | 3 ++- tools/perf/util/trace-event.h | 2 -- tools/perf/util/util.h | 19 +++++++++++++++++++ 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 95feb6ef34a0a..cb8cd09938d5f 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -16,7 +16,6 @@ #include "dso.h" #include "env.h" #include "parse-events.h" -#include "trace-event.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" @@ -28,6 +27,7 @@ #include "util/mmap.h" #include "util/string2.h" #include "util/synthetic-events.h" +#include "util/util.h" #include "thread.h" #include "tests.h" @@ -79,7 +79,7 @@ static size_t read_objdump_chunk(const char **line, unsigned char **buf, * see disassemble_bytes() at binutils/objdump.c for details * how objdump chooses display endian) */ - if (bytes_read > 1 && !bigendian()) { + if (bytes_read > 1 && !host_is_bigendian()) { unsigned char *chunk_end = chunk_start + bytes_read - 1; unsigned char tmp; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 20930dd48ee03..927c7f0cc4ccc 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -13,7 +13,7 @@ #include "evsel.h" #include "debug.h" #include "util/synthetic-events.h" -#include "util/trace-event.h" +#include "util/util.h" #include "tests.h" @@ -117,7 +117,7 @@ static bool samples_same(const struct perf_sample *s1, COMP(branch_stack->hw_idx); for (i = 0; i < s1->branch_stack->nr; i++) { if (needs_swap) - return ((tep_is_bigendian()) ? + return ((host_is_bigendian()) ? (FLAG(s2).value == BS_EXPECTED_BE) : (FLAG(s2).value == BS_EXPECTED_LE)); else diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 45f4f08399ae1..0f617359a82f2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2320,11 +2320,8 @@ u64 evsel__bitfield_swap_branch_flags(u64 value) * as it has variable bit-field sizes. Instead the * macro takes the bit-field position/size, * swaps it based on the host endianness. - * - * tep_is_bigendian() is used here instead of - * bigendian() to avoid python test fails. */ - if (tep_is_bigendian()) { + if (host_is_bigendian()) { new_val = bitfield_swap(value, 0, 1); new_val |= bitfield_swap(value, 1, 1); new_val |= bitfield_swap(value, 2, 1); diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 892c323b4ac9f..c24b3a15e3196 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -26,6 +26,7 @@ #include #include "evsel.h" #include "debug.h" +#include "util.h" #define VERSION "0.6" #define MAX_EVENT_LENGTH 512 @@ -38,15 +39,6 @@ struct tracepoint_path { struct tracepoint_path *next; }; -int bigendian(void) -{ - unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; - unsigned int *ptr; - - ptr = (unsigned int *)(void *)str; - return *ptr == 0x01020304; -} - /* unfortunately, you can not stat debugfs or proc files for size */ static int record_file(const char *file, ssize_t hdr_sz) { @@ -79,7 +71,7 @@ static int record_file(const char *file, ssize_t hdr_sz) /* ugh, handle big-endian hdr_size == 4 */ sizep = (char*)&size; - if (bigendian()) + if (host_is_bigendian()) sizep += sizeof(u64) - hdr_sz; if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) { @@ -564,7 +556,7 @@ static int tracing_data_header(void) return -1; /* save endian */ - if (bigendian()) + if (host_is_bigendian()) buf[0] = 1; else buf[0] = 0; diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 8a01af783310a..43146a4ce2fb2 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -17,6 +17,7 @@ #include "trace-event.h" #include "debug.h" +#include "util.h" static int input_fd; @@ -414,7 +415,7 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) return -1; } file_bigendian = buf[0]; - host_bigendian = bigendian(); + host_bigendian = host_is_bigendian() ? 1 : 0; if (trace_event__init(tevent)) { pr_debug("trace_event__init failed"); diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 6409811057888..8f39f5bcb2c26 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -27,8 +27,6 @@ trace_event__tp_format(const char *sys, const char *name); struct tep_event *trace_event__tp_format_id(int id); -int bigendian(void); - void event_format__fprintf(struct tep_event *event, int cpu, void *data, int size, FILE *fp); diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 63cdab0e5314c..1d3b300af5a14 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -94,4 +94,23 @@ int do_realloc_array_as_needed(void **arr, size_t *arr_sz, size_t x, 0; \ }) +static inline bool host_is_bigendian(void) +{ +#ifdef __BYTE_ORDER__ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return false; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return true; +#else +#error "Unrecognized __BYTE_ORDER__" +#endif +#else /* !__BYTE_ORDER__ */ + unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; + unsigned int *ptr; + + ptr = (unsigned int *)(void *)str; + return *ptr == 0x01020304; +#endif +} + #endif /* __PERF_UTIL_H */ -- GitLab From 336b92da1aa4228a664f27972f61e6186f369e79 Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Tue, 6 Dec 2022 10:02:36 +0530 Subject: [PATCH 1442/1480] perf tool: Move pmus list variable to a new file The 'pmus' list variable is defined as static variable under pmu.c file. Introduce a new pmus.c file and migrate this variable to it. Also make it non static so that it can be accessed from outside. Suggested-by: Ian Rogers Signed-off-by: Ravi Bangoria Acked-by: Ian Rogers Acked-by: Kan Liang Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ananth Narayan Cc: Athira Jajeev Cc: Jiri Olsa Cc: Kajol Jain Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sandipan Das Cc: Santosh Shukla Cc: Thomas Richter Cc: carsten.haitzler@arm.com Link: https://lore.kernel.org/r/20221206043237.12159-2-ravi.bangoria@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/Build | 1 + tools/perf/util/pmu.c | 2 +- tools/perf/util/pmus.c | 5 +++++ tools/perf/util/pmus.h | 9 +++++++++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/perf/util/pmus.c create mode 100644 tools/perf/util/pmus.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index ab37f588ee8b3..d04802bfa23fd 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -73,6 +73,7 @@ perf-y += trace-event-parse.o perf-y += parse-events-flex.o perf-y += parse-events-bison.o perf-y += pmu.o +perf-y += pmus.o perf-y += pmu-flex.o perf-y += pmu-bison.o perf-y += pmu-hybrid.o diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 8ff6462f051e1..2bdeb89352e7a 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -22,6 +22,7 @@ #include "debug.h" #include "evsel.h" #include "pmu.h" +#include "pmus.h" #include "parse-events.h" #include "print-events.h" #include "header.h" @@ -58,7 +59,6 @@ struct perf_pmu_format { int perf_pmu_parse(struct list_head *list, char *name); extern FILE *perf_pmu_in; -static LIST_HEAD(pmus); static bool hybrid_scanned; /* diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c new file mode 100644 index 0000000000000..7f3b93c4d2297 --- /dev/null +++ b/tools/perf/util/pmus.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +LIST_HEAD(pmus); diff --git a/tools/perf/util/pmus.h b/tools/perf/util/pmus.h new file mode 100644 index 0000000000000..5ec12007eb5cd --- /dev/null +++ b/tools/perf/util/pmus.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PMUS_H +#define __PMUS_H + +extern struct list_head pmus; + +#define perf_pmus__for_each_pmu(pmu) list_for_each_entry(pmu, &pmus, list) + +#endif /* __PMUS_H */ -- GitLab From 9d9b22bedad13d96b34fe005ef44b4523c4eb786 Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Tue, 6 Dec 2022 10:02:37 +0530 Subject: [PATCH 1443/1480] perf test: Add event group test for events in multiple PMUs Multiple events in a group can belong to one or more PMUs, however there are some limitations. One of the limitations is that perf doesn't allow creating a group of events from different hw PMUs. Write a simple test to create various combinations of hw, sw and uncore PMU events and verify group creation succeeds or fails as expected. Signed-off-by: Ravi Bangoria Acked-by: Ian Rogers Acked-by: Kan Liang Acked-by: Madhavan Srinivasan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ananth Narayan Cc: Athira Jajeev Cc: Carsten Haitzler Cc: Jiri Olsa Cc: Kajol Jain Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sandipan Das Cc: Santosh Shukla Cc: Thomas Richter Link: https://lore.kernel.org/r/20221206043237.12159-3-ravi.bangoria@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/event_groups.c | 127 ++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 130 insertions(+) create mode 100644 tools/perf/tests/event_groups.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 11b69023011b0..658b5052c24d2 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -67,6 +67,7 @@ perf-y += expand-cgroup.o perf-y += perf-time-to-tsc.o perf-y += dlfilter-test.o perf-y += sigtrap.o +perf-y += event_groups.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 4c6ae59a4dfd7..ddd8262bfa264 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -110,6 +110,7 @@ static struct test_suite *generic_tests[] = { &suite__perf_time_to_tsc, &suite__dlfilter, &suite__sigtrap, + &suite__event_groups, NULL, }; diff --git a/tools/perf/tests/event_groups.c b/tools/perf/tests/event_groups.c new file mode 100644 index 0000000000000..612c0444aaa83 --- /dev/null +++ b/tools/perf/tests/event_groups.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "linux/perf_event.h" +#include "tests.h" +#include "debug.h" +#include "pmu.h" +#include "pmus.h" +#include "header.h" +#include "../perf-sys.h" + +/* hw: cycles, sw: context-switch, uncore: [arch dependent] */ +static int types[] = {0, 1, -1}; +static unsigned long configs[] = {0, 3, 0}; + +#define NR_UNCORE_PMUS 5 + +/* Uncore pmus that support more than 3 counters */ +static struct uncore_pmus { + const char *name; + __u64 config; +} uncore_pmus[NR_UNCORE_PMUS] = { + { "amd_l3", 0x0 }, + { "amd_df", 0x0 }, + { "uncore_imc_0", 0x1 }, /* Intel */ + { "core_imc", 0x318 }, /* PowerPC: core_imc/CPM_STCX_FIN/ */ + { "hv_24x7", 0x22000000003 }, /* PowerPC: hv_24x7/CPM_STCX_FIN/ */ +}; + +static int event_open(int type, unsigned long config, int group_fd) +{ + struct perf_event_attr attr; + + memset(&attr, 0, sizeof(struct perf_event_attr)); + attr.type = type; + attr.size = sizeof(struct perf_event_attr); + attr.config = config; + /* + * When creating an event group, typically the group leader is + * initialized with disabled set to 1 and any child events are + * initialized with disabled set to 0. Despite disabled being 0, + * the child events will not start until the group leader is + * enabled. + */ + attr.disabled = group_fd == -1 ? 1 : 0; + + return sys_perf_event_open(&attr, -1, 0, group_fd, 0); +} + +static int setup_uncore_event(void) +{ + struct perf_pmu *pmu; + int i; + + if (list_empty(&pmus)) + perf_pmu__scan(NULL); + + perf_pmus__for_each_pmu(pmu) { + for (i = 0; i < NR_UNCORE_PMUS; i++) { + if (!strcmp(uncore_pmus[i].name, pmu->name)) { + pr_debug("Using %s for uncore pmu event\n", pmu->name); + types[2] = pmu->type; + configs[2] = uncore_pmus[i].config; + return 0; + } + } + } + return -1; +} + +static int run_test(int i, int j, int k) +{ + int erroneous = ((((1 << i) | (1 << j) | (1 << k)) & 5) == 5); + int group_fd, sibling_fd1, sibling_fd2; + + group_fd = event_open(types[i], configs[i], -1); + if (group_fd == -1) + return -1; + + sibling_fd1 = event_open(types[j], configs[j], group_fd); + if (sibling_fd1 == -1) { + close(group_fd); + return erroneous ? 0 : -1; + } + + sibling_fd2 = event_open(types[k], configs[k], group_fd); + if (sibling_fd2 == -1) { + close(sibling_fd1); + close(group_fd); + return erroneous ? 0 : -1; + } + + close(sibling_fd2); + close(sibling_fd1); + close(group_fd); + return erroneous ? -1 : 0; +} + +static int test__event_groups(struct test_suite *text __maybe_unused, int subtest __maybe_unused) +{ + int i, j, k; + int ret; + int r; + + ret = setup_uncore_event(); + if (ret || types[2] == -1) + return TEST_SKIP; + + ret = TEST_OK; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) { + r = run_test(i, j, k); + if (r) + ret = TEST_FAIL; + + pr_debug("0x%x 0x%lx, 0x%x 0x%lx, 0x%x 0x%lx: %s\n", + types[i], configs[i], types[j], configs[j], + types[k], configs[k], r ? "Fail" : "Pass"); + } + } + } + return ret; +} + +DEFINE_SUITE("Event groups", event_groups); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index e15f24cfc9094..fb4b5ad4dd0fe 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -147,6 +147,7 @@ DECLARE_SUITE(expand_cgroup_events); DECLARE_SUITE(perf_time_to_tsc); DECLARE_SUITE(dlfilter); DECLARE_SUITE(sigtrap); +DECLARE_SUITE(event_groups); /* * PowerPC and S390 do not support creation of instruction breakpoints using the -- GitLab From cc2367eebb0c3c5501cddd5823e5feda7b57f706 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Dec 2022 13:49:04 -0300 Subject: [PATCH 1444/1480] machine: Adopt is_lock_function() from builtin-lock.c It is used in bpf_lock_contention.c and builtin-lock.c will be made CONFIG_LIBTRACEEVENT=y conditional, so move it to machine.c, that is always available. This makes those 4 global variables for sched and lock text start and end to move to 'struct machine' too, as conceivably we can have that info for several machine instances, say some 'perf diff' like tool. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/ Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 58 +-------------------------- tools/perf/util/bpf_lock_contention.c | 2 +- tools/perf/util/lock-contention.h | 2 - tools/perf/util/machine.c | 40 ++++++++++++++++++ tools/perf/util/machine.h | 5 +++ 5 files changed, 48 insertions(+), 59 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 0d280093b19a5..15ce6358f1279 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -67,11 +67,6 @@ static enum { LOCK_AGGR_CALLER, } aggr_mode = LOCK_AGGR_ADDR; -static u64 sched_text_start; -static u64 sched_text_end; -static u64 lock_text_start; -static u64 lock_text_end; - static struct thread_stat *thread_stat_find(u32 tid) { struct rb_node *node; @@ -854,55 +849,6 @@ end: return 0; } -bool is_lock_function(struct machine *machine, u64 addr) -{ - if (!sched_text_start) { - struct map *kmap; - struct symbol *sym; - - sym = machine__find_kernel_symbol_by_name(machine, - "__sched_text_start", - &kmap); - if (!sym) { - /* to avoid retry */ - sched_text_start = 1; - return false; - } - - sched_text_start = kmap->unmap_ip(kmap, sym->start); - - /* should not fail from here */ - sym = machine__find_kernel_symbol_by_name(machine, - "__sched_text_end", - &kmap); - sched_text_end = kmap->unmap_ip(kmap, sym->start); - - sym = machine__find_kernel_symbol_by_name(machine, - "__lock_text_start", - &kmap); - lock_text_start = kmap->unmap_ip(kmap, sym->start); - - sym = machine__find_kernel_symbol_by_name(machine, - "__lock_text_end", - &kmap); - lock_text_end = kmap->unmap_ip(kmap, sym->start); - } - - /* failed to get kernel symbols */ - if (sched_text_start == 1) - return false; - - /* mutex and rwsem functions are in sched text section */ - if (sched_text_start <= addr && addr < sched_text_end) - return true; - - /* spinlock functions are in lock text section */ - if (lock_text_start <= addr && addr < lock_text_end) - return true; - - return false; -} - static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip, char *buf, int size) { @@ -961,7 +907,7 @@ static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sampl goto next; sym = node->ms.sym; - if (sym && !is_lock_function(machine, node->ip)) { + if (sym && !machine__is_lock_function(machine, node->ip)) { get_symbol_name_offset(node->ms.map, sym, node->ip, buf, size); return 0; @@ -1007,7 +953,7 @@ static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample) if (++skip <= stack_skip) goto next; - if (node->ms.sym && is_lock_function(machine, node->ip)) + if (node->ms.sym && machine__is_lock_function(machine, node->ip)) goto next; hash ^= hash_long((unsigned long)node->ip, 64); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 4db9ad3d50c41..f4ebb9a2e3809 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -153,7 +153,7 @@ int lock_contention_read(struct lock_contention *con) bpf_map_lookup_elem(stack, &key, stack_trace); /* skip lock internal functions */ - while (is_lock_function(machine, stack_trace[idx]) && + while (machine__is_lock_function(machine, stack_trace[idx]) && idx < con->max_stack - 1) idx++; diff --git a/tools/perf/util/lock-contention.h b/tools/perf/util/lock-contention.h index e3c061b1795ba..a2346875098dc 100644 --- a/tools/perf/util/lock-contention.h +++ b/tools/perf/util/lock-contention.h @@ -145,6 +145,4 @@ static inline int lock_contention_read(struct lock_contention *con __maybe_unuse #endif /* HAVE_BPF_SKEL */ -bool is_lock_function(struct machine *machine, u64 addr); - #endif /* PERF_LOCK_CONTENTION_H */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 76316e459c3de..803c9d1803dd2 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -3336,3 +3336,43 @@ int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, voi } return err; } + +bool machine__is_lock_function(struct machine *machine, u64 addr) +{ + if (!machine->sched.text_start) { + struct map *kmap; + struct symbol *sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_start", &kmap); + + if (!sym) { + /* to avoid retry */ + machine->sched.text_start = 1; + return false; + } + + machine->sched.text_start = kmap->unmap_ip(kmap, sym->start); + + /* should not fail from here */ + sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap); + machine->sched.text_end = kmap->unmap_ip(kmap, sym->start); + + sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap); + machine->lock.text_start = kmap->unmap_ip(kmap, sym->start); + + sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap); + machine->lock.text_end = kmap->unmap_ip(kmap, sym->start); + } + + /* failed to get kernel symbols */ + if (machine->sched.text_start == 1) + return false; + + /* mutex and rwsem functions are in sched text section */ + if (machine->sched.text_start <= addr && addr < machine->sched.text_end) + return true; + + /* spinlock functions are in lock text section */ + if (machine->lock.text_start <= addr && addr < machine->lock.text_end) + return true; + + return false; +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 6267c1d6f2321..d034ecaf89c19 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -56,6 +56,10 @@ struct machine { struct maps *kmaps; struct map *vmlinux_map; u64 kernel_start; + struct { + u64 text_start; + u64 text_end; + } sched, lock; pid_t *current_tid; size_t current_tid_sz; union { /* Tool specific area */ @@ -212,6 +216,7 @@ static inline bool machine__is_host(struct machine *machine) return machine ? machine->pid == HOST_KERNEL_ID : false; } +bool machine__is_lock_function(struct machine *machine, u64 addr); bool machine__is(struct machine *machine, const char *arch); bool machine__normalized_is(struct machine *machine, const char *arch); int machine__nr_cpus_avail(struct machine *machine); -- GitLab From 616aa32d6f221faa0235d2586ec1706dca70a439 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 5 Dec 2022 14:59:38 -0800 Subject: [PATCH 1445/1480] perf build: Fixes for LIBTRACEEVENT_DYNAMIC If LIBTRACEEVENT_DYNAMIC is enabled then avoid the install step for the plugins. If disabled correct DESTDIR so that the plugins are installed under /traceevent/plugins. Fixes: ef019df01e207971 ("perf build: Install libtraceevent locally when building") Reported-by: Alexander Gordeev Signed-off-by: Ian Rogers Cc: Alexander Gordeev Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20221205225940.3079667-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a17a6ea85e817..6689f644782f5 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -884,7 +884,7 @@ $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins install-traceevent-plugins: libtraceevent_plugins $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ - DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ + DESTDIR=$(DESTDIR_SQ)$(prefix) prefix= \ $(LIBTRACEEVENT_FLAGS) install endif @@ -1093,7 +1093,11 @@ install-tests: all install-gtk $(INSTALL) tests/shell/coresight/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/coresight' $(Q)$(MAKE) -C tests/shell/coresight install-tests -install-bin: install-tools install-tests install-traceevent-plugins +install-bin: install-tools install-tests + +ifndef LIBTRACEEVENT_DYNAMIC +install-bin: install-traceevent-plugins +endif install: install-bin try-install-man -- GitLab From b897613510890d6e92b6a276a20f6c3d96fe90e8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 6 Dec 2022 09:58:04 -0800 Subject: [PATCH 1446/1480] perf stat: Update event skip condition for system-wide per-thread mode and merged uncore and hybrid events In print_counter_aggrdata(), it skips some events that has no aggregate count. It's actually for system-wide per-thread mode and merged uncore and hybrid events. Let's update the condition to check them explicitly. Fixes: 91f85f98da7ab8c3 ("perf stat: Display event stats using aggr counts") Reported-by: Athira Jajeev Signed-off-by: Namhyung Kim Acked-by: Athira Jajeev Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20221206175804.391387-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index ead4915c4a033..8bd8b0142630c 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -804,7 +804,8 @@ static void print_counter_aggrdata(struct perf_stat_config *config, os->nr = aggr->nr; os->evsel = counter; - if (counter->supported && aggr->nr == 0) + /* Skip already merged uncore/hybrid events */ + if (counter->merged_stat) return; uniquify_counter(config, counter); @@ -813,6 +814,13 @@ static void print_counter_aggrdata(struct perf_stat_config *config, ena = aggr->counts.ena; run = aggr->counts.run; + /* + * Skip value 0 when enabling --per-thread globally, otherwise it will + * have too many 0 output. + */ + if (val == 0 && config->aggr_mode == AGGR_THREAD && config->system_wide) + return; + if (!metric_only) { if (config->json_output) fputc('{', output); @@ -889,9 +897,6 @@ static void print_aggr(struct perf_stat_config *config, print_metric_begin(config, evlist, os, s); evlist__for_each_entry(evlist, counter) { - if (counter->merged_stat) - continue; - print_counter_aggrdata(config, counter, s, os); } print_metric_end(config, os); @@ -918,9 +923,6 @@ static void print_aggr_cgroup(struct perf_stat_config *config, print_metric_begin(config, evlist, os, s); evlist__for_each_entry(evlist, counter) { - if (counter->merged_stat) - continue; - if (counter->cgrp != os->cgrp) continue; @@ -940,9 +942,6 @@ static void print_counter(struct perf_stat_config *config, if (!config->aggr_map) return; - if (counter->merged_stat) - return; - for (s = 0; s < config->aggr_map->nr; s++) { print_counter_aggrdata(config, counter, s, os); } -- GitLab From 40769665b63d8c84b5b1c63fee404d4c20cff751 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 6 Dec 2022 21:59:08 -0800 Subject: [PATCH 1447/1480] perf jevents: Parse metrics during conversion Currently the 'MetricExpr' json value is passed from the json file to the pmu-events.c. This change introduces an expression tree that is parsed into. The parsing is done largely by using operator overloading and python's 'eval' function. Two advantages in doing this are: 1) Broken metrics fail at compile time rather than relying on `perf test` to detect. `perf test` remains relevant for checking event encoding and actual metric use. 2) The conversion to a string from the tree can minimize the metric's string size, for example, preferring 1e6 over 1000000, avoiding multiplication by 1 and removing unnecessary whitespace. On x86 this reduces the string size by 2,930bytes (0.07%). In future changes it would be possible to programmatically generate the json expressions (a single line of text and so a pain to write manually) for an architecture using the expression tree. This could avoid copy-pasting metrics for all architecture variants. v4. Doesn't simplify "0*SLOTS" to 0, as the pattern is used to fix Intel metrics with topdown events. v3. Avoids generic types on standard types like set that aren't supported until Python 3.9, fixing an issue with Python 3.6 reported-by John Garry. v3 also fixes minor pylint issues and adds a call to Simplify on the read expression tree. v2. Improvements to type information. Committer notes: Added one-line fixer from Ian, see first Link: tag below. Signed-off-by: Ian Rogers Reviewed-by: John Garry Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Sumanth Korikkar Cc: Thomas Richter Link: https://lore.kernel.org/r/CAP-5=fWa=zNK_ecpWGoGggHCQx7z-oW0eGMQf19Maywg0QK=4g@mail.gmail.com Link: https://lore.kernel.org/r/20221207055908.1385448-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/Build | 2 +- tools/perf/pmu-events/jevents.py | 12 +- tools/perf/pmu-events/metric.py | 502 +++++++++++++++++++++++++++ tools/perf/pmu-events/metric_test.py | 157 +++++++++ 4 files changed, 669 insertions(+), 4 deletions(-) create mode 100644 tools/perf/pmu-events/metric.py create mode 100644 tools/perf/pmu-events/metric_test.py diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index 04ef95174660b..15b9e8fdbffa7 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -21,7 +21,7 @@ $(OUTPUT)pmu-events/pmu-events.c: pmu-events/empty-pmu-events.c $(call rule_mkdir) $(Q)$(call echo-cmd,gen)cp $< $@ else -$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY) +$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS_PY) pmu-events/metric.py $(call rule_mkdir) $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) pmu-events/arch $@ endif diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py index 0daa3e007528f..4c398e0eeb2f8 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -4,6 +4,7 @@ import argparse import csv import json +import metric import os import sys from typing import (Callable, Dict, Optional, Sequence, Set, Tuple) @@ -268,9 +269,10 @@ class JsonEvent: self.metric_name = jd.get('MetricName') self.metric_group = jd.get('MetricGroup') self.metric_constraint = jd.get('MetricConstraint') - self.metric_expr = jd.get('MetricExpr') - if self.metric_expr: - self.metric_expr = self.metric_expr.replace('\\', '\\\\') + self.metric_expr = None + if 'MetricExpr' in jd: + self.metric_expr = metric.ParsePerfJson(jd['MetricExpr']).Simplify() + arch_std = jd.get('ArchStdEvent') if precise and self.desc and '(Precise Event)' not in self.desc: extra_desc += ' (Must be precise)' if precise == '2' else (' (Precise ' @@ -322,6 +324,10 @@ class JsonEvent: s = '' for attr in _json_event_attributes: x = getattr(self, attr) + if x and attr == 'metric_expr': + # Convert parsed metric expressions into a string. Slashes + # must be doubled in the file. + x = x.ToPerfJson().replace('\\', '\\\\') s += f'{x}\\000' if x else '\\000' return s diff --git a/tools/perf/pmu-events/metric.py b/tools/perf/pmu-events/metric.py new file mode 100644 index 0000000000000..4797ed4fd817b --- /dev/null +++ b/tools/perf/pmu-events/metric.py @@ -0,0 +1,502 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +"""Parse or generate representations of perf metrics.""" +import ast +import decimal +import json +import re +from typing import Dict, List, Optional, Set, Union + + +class Expression: + """Abstract base class of elements in a metric expression.""" + + def ToPerfJson(self) -> str: + """Returns a perf json file encoded representation.""" + raise NotImplementedError() + + def ToPython(self) -> str: + """Returns a python expr parseable representation.""" + raise NotImplementedError() + + def Simplify(self): + """Returns a simplified version of self.""" + raise NotImplementedError() + + def Equals(self, other) -> bool: + """Returns true when two expressions are the same.""" + raise NotImplementedError() + + def __str__(self) -> str: + return self.ToPerfJson() + + def __or__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('|', self, other) + + def __ror__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('|', other, self) + + def __xor__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('^', self, other) + + def __and__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('&', self, other) + + def __lt__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('<', self, other) + + def __gt__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('>', self, other) + + def __add__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('+', self, other) + + def __radd__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('+', other, self) + + def __sub__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('-', self, other) + + def __rsub__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('-', other, self) + + def __mul__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('*', self, other) + + def __rmul__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('*', other, self) + + def __truediv__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('/', self, other) + + def __rtruediv__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('/', other, self) + + def __mod__(self, other: Union[int, float, 'Expression']) -> 'Operator': + return Operator('%', self, other) + + +def _Constify(val: Union[bool, int, float, Expression]) -> Expression: + """Used to ensure that the nodes in the expression tree are all Expression.""" + if isinstance(val, bool): + return Constant(1 if val else 0) + if isinstance(val, (int, float)): + return Constant(val) + return val + + +# Simple lookup for operator precedence, used to avoid unnecessary +# brackets. Precedence matches that of python and the simple expression parser. +_PRECEDENCE = { + '|': 0, + '^': 1, + '&': 2, + '<': 3, + '>': 3, + '+': 4, + '-': 4, + '*': 5, + '/': 5, + '%': 5, +} + + +class Operator(Expression): + """Represents a binary operator in the parse tree.""" + + def __init__(self, operator: str, lhs: Union[int, float, Expression], + rhs: Union[int, float, Expression]): + self.operator = operator + self.lhs = _Constify(lhs) + self.rhs = _Constify(rhs) + + def Bracket(self, + other: Expression, + other_str: str, + rhs: bool = False) -> str: + """If necessary brackets the given other value. + + If ``other`` is an operator then a bracket is necessary when + this/self operator has higher precedence. Consider: '(a + b) * c', + ``other_str`` will be 'a + b'. A bracket is necessary as without + the bracket 'a + b * c' will evaluate 'b * c' first. However, '(a + * b) + c' doesn't need a bracket as 'a * b' will always be + evaluated first. For 'a / (b * c)' (ie the same precedence level + operations) then we add the bracket to best match the original + input, but not for '(a / b) * c' where the bracket is unnecessary. + + Args: + other (Expression): is a lhs or rhs operator + other_str (str): ``other`` in the appropriate string form + rhs (bool): is ``other`` on the RHS + + Returns: + str: possibly bracketed other_str + """ + if isinstance(other, Operator): + if _PRECEDENCE.get(self.operator, -1) > _PRECEDENCE.get( + other.operator, -1): + return f'({other_str})' + if rhs and _PRECEDENCE.get(self.operator, -1) == _PRECEDENCE.get( + other.operator, -1): + return f'({other_str})' + return other_str + + def ToPerfJson(self): + return (f'{self.Bracket(self.lhs, self.lhs.ToPerfJson())} {self.operator} ' + f'{self.Bracket(self.rhs, self.rhs.ToPerfJson(), True)}') + + def ToPython(self): + return (f'{self.Bracket(self.lhs, self.lhs.ToPython())} {self.operator} ' + f'{self.Bracket(self.rhs, self.rhs.ToPython(), True)}') + + def Simplify(self) -> Expression: + lhs = self.lhs.Simplify() + rhs = self.rhs.Simplify() + if isinstance(lhs, Constant) and isinstance(rhs, Constant): + return Constant(ast.literal_eval(lhs + self.operator + rhs)) + + if isinstance(self.lhs, Constant): + if self.operator in ('+', '|') and lhs.value == '0': + return rhs + + # Simplify multiplication by 0 except for the slot event which + # is deliberately introduced using this pattern. + if self.operator == '*' and lhs.value == '0' and ( + not isinstance(rhs, Event) or 'slots' not in rhs.name.lower()): + return Constant(0) + + if self.operator == '*' and lhs.value == '1': + return rhs + + if isinstance(rhs, Constant): + if self.operator in ('+', '|') and rhs.value == '0': + return lhs + + if self.operator == '*' and rhs.value == '0': + return Constant(0) + + if self.operator == '*' and self.rhs.value == '1': + return lhs + + return Operator(self.operator, lhs, rhs) + + def Equals(self, other: Expression) -> bool: + if isinstance(other, Operator): + return self.operator == other.operator and self.lhs.Equals( + other.lhs) and self.rhs.Equals(other.rhs) + return False + + +class Select(Expression): + """Represents a select ternary in the parse tree.""" + + def __init__(self, true_val: Union[int, float, Expression], + cond: Union[int, float, Expression], + false_val: Union[int, float, Expression]): + self.true_val = _Constify(true_val) + self.cond = _Constify(cond) + self.false_val = _Constify(false_val) + + def ToPerfJson(self): + true_str = self.true_val.ToPerfJson() + cond_str = self.cond.ToPerfJson() + false_str = self.false_val.ToPerfJson() + return f'({true_str} if {cond_str} else {false_str})' + + def ToPython(self): + return (f'Select({self.true_val.ToPython()}, {self.cond.ToPython()}, ' + f'{self.false_val.ToPython()})') + + def Simplify(self) -> Expression: + cond = self.cond.Simplify() + true_val = self.true_val.Simplify() + false_val = self.false_val.Simplify() + if isinstance(cond, Constant): + return false_val if cond.value == '0' else true_val + + if true_val.Equals(false_val): + return true_val + + return Select(true_val, cond, false_val) + + def Equals(self, other: Expression) -> bool: + if isinstance(other, Select): + return self.cond.Equals(other.cond) and self.false_val.Equals( + other.false_val) and self.true_val.Equals(other.true_val) + return False + + +class Function(Expression): + """A function in an expression like min, max, d_ratio.""" + + def __init__(self, + fn: str, + lhs: Union[int, float, Expression], + rhs: Optional[Union[int, float, Expression]] = None): + self.fn = fn + self.lhs = _Constify(lhs) + self.rhs = _Constify(rhs) + + def ToPerfJson(self): + if self.rhs: + return f'{self.fn}({self.lhs.ToPerfJson()}, {self.rhs.ToPerfJson()})' + return f'{self.fn}({self.lhs.ToPerfJson()})' + + def ToPython(self): + if self.rhs: + return f'{self.fn}({self.lhs.ToPython()}, {self.rhs.ToPython()})' + return f'{self.fn}({self.lhs.ToPython()})' + + def Simplify(self) -> Expression: + lhs = self.lhs.Simplify() + rhs = self.rhs.Simplify() if self.rhs else None + if isinstance(lhs, Constant) and isinstance(rhs, Constant): + if self.fn == 'd_ratio': + if rhs.value == '0': + return Constant(0) + Constant(ast.literal_eval(f'{lhs} / {rhs}')) + return Constant(ast.literal_eval(f'{self.fn}({lhs}, {rhs})')) + + return Function(self.fn, lhs, rhs) + + def Equals(self, other: Expression) -> bool: + if isinstance(other, Function): + return self.fn == other.fn and self.lhs.Equals( + other.lhs) and self.rhs.Equals(other.rhs) + return False + + +def _FixEscapes(s: str) -> str: + s = re.sub(r'([^\\]),', r'\1\\,', s) + return re.sub(r'([^\\])=', r'\1\\=', s) + + +class Event(Expression): + """An event in an expression.""" + + def __init__(self, name: str, legacy_name: str = ''): + self.name = _FixEscapes(name) + self.legacy_name = _FixEscapes(legacy_name) + + def ToPerfJson(self): + result = re.sub('/', '@', self.name) + return result + + def ToPython(self): + return f'Event(r"{self.name}")' + + def Simplify(self) -> Expression: + return self + + def Equals(self, other: Expression) -> bool: + return isinstance(other, Event) and self.name == other.name + + +class Constant(Expression): + """A constant within the expression tree.""" + + def __init__(self, value: Union[float, str]): + ctx = decimal.Context() + ctx.prec = 20 + dec = ctx.create_decimal(repr(value) if isinstance(value, float) else value) + self.value = dec.normalize().to_eng_string() + self.value = self.value.replace('+', '') + self.value = self.value.replace('E', 'e') + + def ToPerfJson(self): + return self.value + + def ToPython(self): + return f'Constant({self.value})' + + def Simplify(self) -> Expression: + return self + + def Equals(self, other: Expression) -> bool: + return isinstance(other, Constant) and self.value == other.value + + +class Literal(Expression): + """A runtime literal within the expression tree.""" + + def __init__(self, value: str): + self.value = value + + def ToPerfJson(self): + return self.value + + def ToPython(self): + return f'Literal({self.value})' + + def Simplify(self) -> Expression: + return self + + def Equals(self, other: Expression) -> bool: + return isinstance(other, Literal) and self.value == other.value + + +def min(lhs: Union[int, float, Expression], rhs: Union[int, float, + Expression]) -> Function: + # pylint: disable=redefined-builtin + # pylint: disable=invalid-name + return Function('min', lhs, rhs) + + +def max(lhs: Union[int, float, Expression], rhs: Union[int, float, + Expression]) -> Function: + # pylint: disable=redefined-builtin + # pylint: disable=invalid-name + return Function('max', lhs, rhs) + + +def d_ratio(lhs: Union[int, float, Expression], + rhs: Union[int, float, Expression]) -> Function: + # pylint: disable=redefined-builtin + # pylint: disable=invalid-name + return Function('d_ratio', lhs, rhs) + + +def source_count(event: Event) -> Function: + # pylint: disable=redefined-builtin + # pylint: disable=invalid-name + return Function('source_count', event) + + +class Metric: + """An individual metric that will specifiable on the perf command line.""" + groups: Set[str] + expr: Expression + scale_unit: str + constraint: bool + + def __init__(self, + name: str, + description: str, + expr: Expression, + scale_unit: str, + constraint: bool = False): + self.name = name + self.description = description + self.expr = expr.Simplify() + # Workraound valid_only_metric hiding certain metrics based on unit. + scale_unit = scale_unit.replace('/sec', ' per sec') + if scale_unit[0].isdigit(): + self.scale_unit = scale_unit + else: + self.scale_unit = f'1{scale_unit}' + self.constraint = constraint + self.groups = set() + + def __lt__(self, other): + """Sort order.""" + return self.name < other.name + + def AddToMetricGroup(self, group): + """Callback used when being added to a MetricGroup.""" + self.groups.add(group.name) + + def Flatten(self) -> Set['Metric']: + """Return a leaf metric.""" + return set([self]) + + def ToPerfJson(self) -> Dict[str, str]: + """Return as dictionary for Json generation.""" + result = { + 'MetricName': self.name, + 'MetricGroup': ';'.join(sorted(self.groups)), + 'BriefDescription': self.description, + 'MetricExpr': self.expr.ToPerfJson(), + 'ScaleUnit': self.scale_unit + } + if self.constraint: + result['MetricConstraint'] = 'NO_NMI_WATCHDOG' + + return result + + +class _MetricJsonEncoder(json.JSONEncoder): + """Special handling for Metric objects.""" + + def default(self, o): + if isinstance(o, Metric): + return o.ToPerfJson() + return json.JSONEncoder.default(self, o) + + +class MetricGroup: + """A group of metrics. + + Metric groups may be specificd on the perf command line, but within + the json they aren't encoded. Metrics may be in multiple groups + which can facilitate arrangements similar to trees. + """ + + def __init__(self, name: str, metric_list: List[Union[Metric, + 'MetricGroup']]): + self.name = name + self.metric_list = metric_list + for metric in metric_list: + metric.AddToMetricGroup(self) + + def AddToMetricGroup(self, group): + """Callback used when a MetricGroup is added into another.""" + for metric in self.metric_list: + metric.AddToMetricGroup(group) + + def Flatten(self) -> Set[Metric]: + """Returns a set of all leaf metrics.""" + result = set() + for x in self.metric_list: + result = result.union(x.Flatten()) + + return result + + def ToPerfJson(self) -> str: + return json.dumps(sorted(self.Flatten()), indent=2, cls=_MetricJsonEncoder) + + def __str__(self) -> str: + return self.ToPerfJson() + + +class _RewriteIfExpToSelect(ast.NodeTransformer): + + def visit_IfExp(self, node): + # pylint: disable=invalid-name + self.generic_visit(node) + call = ast.Call( + func=ast.Name(id='Select', ctx=ast.Load()), + args=[node.body, node.test, node.orelse], + keywords=[]) + ast.copy_location(call, node.test) + return call + + +def ParsePerfJson(orig: str) -> Expression: + """A simple json metric expression decoder. + + Converts a json encoded metric expression by way of python's ast and + eval routine. First tokens are mapped to Event calls, then + accidentally converted keywords or literals are mapped to their + appropriate calls. Python's ast is used to match if-else that can't + be handled via operator overloading. Finally the ast is evaluated. + + Args: + orig (str): String to parse. + + Returns: + Expression: The parsed string. + """ + # pylint: disable=eval-used + py = orig.strip() + py = re.sub(r'([a-zA-Z][^-+/\* \\\(\),]*(?:\\.[^-+/\* \\\(\),]*)*)', + r'Event(r"\1")', py) + py = re.sub(r'#Event\(r"([^"]*)"\)', r'Literal("#\1")', py) + py = re.sub(r'([0-9]+)Event\(r"(e[0-9]+)"\)', r'\1\2', py) + keywords = ['if', 'else', 'min', 'max', 'd_ratio', 'source_count'] + for kw in keywords: + py = re.sub(rf'Event\(r"{kw}"\)', kw, py) + + parsed = ast.parse(py, mode='eval') + _RewriteIfExpToSelect().visit(parsed) + parsed = ast.fix_missing_locations(parsed) + return _Constify(eval(compile(parsed, orig, 'eval'))) diff --git a/tools/perf/pmu-events/metric_test.py b/tools/perf/pmu-events/metric_test.py new file mode 100644 index 0000000000000..15315d0f716ca --- /dev/null +++ b/tools/perf/pmu-events/metric_test.py @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +import unittest +from metric import Constant +from metric import Event +from metric import ParsePerfJson + + +class TestMetricExpressions(unittest.TestCase): + + def test_Operators(self): + a = Event('a') + b = Event('b') + self.assertEqual((a | b).ToPerfJson(), 'a | b') + self.assertEqual((a ^ b).ToPerfJson(), 'a ^ b') + self.assertEqual((a & b).ToPerfJson(), 'a & b') + self.assertEqual((a < b).ToPerfJson(), 'a < b') + self.assertEqual((a > b).ToPerfJson(), 'a > b') + self.assertEqual((a + b).ToPerfJson(), 'a + b') + self.assertEqual((a - b).ToPerfJson(), 'a - b') + self.assertEqual((a * b).ToPerfJson(), 'a * b') + self.assertEqual((a / b).ToPerfJson(), 'a / b') + self.assertEqual((a % b).ToPerfJson(), 'a % b') + one = Constant(1) + self.assertEqual((a + one).ToPerfJson(), 'a + 1') + + def test_Brackets(self): + a = Event('a') + b = Event('b') + c = Event('c') + self.assertEqual((a * b + c).ToPerfJson(), 'a * b + c') + self.assertEqual((a + b * c).ToPerfJson(), 'a + b * c') + self.assertEqual(((a + a) + a).ToPerfJson(), 'a + a + a') + self.assertEqual(((a + b) * c).ToPerfJson(), '(a + b) * c') + self.assertEqual((a + (b * c)).ToPerfJson(), 'a + b * c') + self.assertEqual(((a / b) * c).ToPerfJson(), 'a / b * c') + self.assertEqual((a / (b * c)).ToPerfJson(), 'a / (b * c)') + + def test_ParsePerfJson(self): + # Based on an example of a real metric. + before = '(a + b + c + d) / (2 * e)' + after = before + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + # Parsing should handle events with '-' in their name. Note, in + # the json file the '\' are doubled to '\\'. + before = r'topdown\-fe\-bound / topdown\-slots - 1' + after = before + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + # Parsing should handle escaped modifiers. Note, in the json file + # the '\' are doubled to '\\'. + before = r'arb@event\=0x81\,umask\=0x1@ + arb@event\=0x84\,umask\=0x1@' + after = before + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + # Parsing should handle exponents in numbers. + before = r'a + 1e12 + b' + after = before + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + def test_IfElseTests(self): + # if-else needs rewriting to Select and back. + before = r'Event1 if #smt_on else Event2' + after = f'({before})' + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + before = r'Event1 if 0 else Event2' + after = f'({before})' + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + before = r'Event1 if 1 else Event2' + after = f'({before})' + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + # Ensure the select is evaluate last. + before = r'Event1 + 1 if Event2 < 2 else Event3 + 3' + after = (r'Select(Event(r"Event1") + Constant(1), Event(r"Event2") < ' + r'Constant(2), Event(r"Event3") + Constant(3))') + self.assertEqual(ParsePerfJson(before).ToPython(), after) + + before = r'Event1 > 1 if Event2 < 2 else Event3 > 3' + after = (r'Select(Event(r"Event1") > Constant(1), Event(r"Event2") < ' + r'Constant(2), Event(r"Event3") > Constant(3))') + self.assertEqual(ParsePerfJson(before).ToPython(), after) + + before = r'min(a + b if c > 1 else c + d, e + f)' + after = r'min((a + b if c > 1 else c + d), e + f)' + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + before =3D r'a if b else c if d else e' + after =3D r'(a if b else (c if d else e))' + self.assertEqual(ParsePerfJson(before).ToPerfJson(), after) + + def test_ToPython(self): + # pylint: disable=eval-used + # Based on an example of a real metric. + before = '(a + b + c + d) / (2 * e)' + py = ParsePerfJson(before).ToPython() + after = eval(py).ToPerfJson() + self.assertEqual(before, after) + + def test_Simplify(self): + before = '1 + 2 + 3' + after = '6' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a + 0' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = '0 + a' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a | 0' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = '0 | a' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a * 0' + after = '0' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = '0 * a' + after = '0' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a * 1' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = '1 * a' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a if 0 else b' + after = 'b' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a if 1 else b' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + before = 'a if b else a' + after = 'a' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + + # Pattern used to add a slots event to metrics that require it. + before = '0 * SLOTS' + after = '0 * SLOTS' + self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after) + +if __name__ == '__main__': + unittest.main() -- GitLab From 378ef0f5d9d7f4652d7a40e0711e8b845ada1cbd Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 5 Dec 2022 14:59:39 -0800 Subject: [PATCH 1448/1480] perf build: Use libtraceevent from the system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the LIBTRACEEVENT_DYNAMIC and LIBTRACEFS_DYNAMIC make command line variables. If libtraceevent isn't installed or NO_LIBTRACEEVENT=1 is passed to the build, don't compile in libtraceevent and libtracefs support. This also disables CONFIG_TRACE that controls "perf trace". CONFIG_LIBTRACEEVENT is used to control enablement in Build/Makefiles, HAVE_LIBTRACEEVENT is used in C code. Without HAVE_LIBTRACEEVENT tracepoints are disabled and as such the commands kmem, kwork, lock, sched and timechart are removed. The majority of commands continue to work including "perf test". Committer notes: Fixed up a tools/perf/util/Build reject and added: #include to tools/perf/util/scripting-engines/trace-event-perl.c. Committer testing: $ rpm -qi libtraceevent-devel Name : libtraceevent-devel Version : 1.5.3 Release : 2.fc36 Architecture: x86_64 Install Date: Mon 25 Jul 2022 03:20:19 PM -03 Group : Unspecified Size : 27728 License : LGPLv2+ and GPLv2+ Signature : RSA/SHA256, Fri 15 Apr 2022 02:11:58 PM -03, Key ID 999f7cbf38ab71f4 Source RPM : libtraceevent-1.5.3-2.fc36.src.rpm Build Date : Fri 15 Apr 2022 10:57:01 AM -03 Build Host : buildvm-x86-05.iad2.fedoraproject.org Packager : Fedora Project Vendor : Fedora Project URL : https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ Bug URL : https://bugz.fedoraproject.org/libtraceevent Summary : Development headers of libtraceevent Description : Development headers of libtraceevent-libs $ Default build: $ ldd ~/bin/perf | grep tracee libtraceevent.so.1 => /lib64/libtraceevent.so.1 (0x00007f1dcaf8f000) $ # perf trace -e sched:* --max-events 10 0.000 migration/0/17 sched:sched_migrate_task(comm: "", pid: 1603763 (perf), prio: 120, dest_cpu: 1) 0.005 migration/0/17 sched:sched_wake_idle_without_ipi(cpu: 1) 0.011 migration/0/17 sched:sched_switch(prev_comm: "", prev_pid: 17 (migration/0), prev_state: 1, next_comm: "", next_prio: 120) 1.173 :0/0 sched:sched_wakeup(comm: "", pid: 3138 (gnome-terminal-), prio: 120) 1.180 :0/0 sched:sched_switch(prev_comm: "", prev_prio: 120, next_comm: "", next_pid: 3138 (gnome-terminal-), next_prio: 120) 0.156 migration/1/21 sched:sched_migrate_task(comm: "", pid: 1603763 (perf), prio: 120, orig_cpu: 1, dest_cpu: 2) 0.160 migration/1/21 sched:sched_wake_idle_without_ipi(cpu: 2) 0.166 migration/1/21 sched:sched_switch(prev_comm: "", prev_pid: 21 (migration/1), prev_state: 1, next_comm: "", next_prio: 120) 1.183 :0/0 sched:sched_wakeup(comm: "", pid: 1602985 (kworker/u16:0-f), prio: 120, target_cpu: 1) 1.186 :0/0 sched:sched_switch(prev_comm: "", prev_prio: 120, next_comm: "", next_pid: 1602985 (kworker/u16:0-f), next_prio: 120) # Had to tweak tools/perf/util/setup.py to make sure the python binding shared object links with libtraceevent if -DHAVE_LIBTRACEEVENT is present in CFLAGS. Building with NO_LIBTRACEEVENT=1 uncovered some more build failures: - Make building of data-convert-bt.c to CONFIG_LIBTRACEEVENT=y - perf-$(CONFIG_LIBTRACEEVENT) += scripts/ - bpf_kwork.o needs also to be dependent on CONFIG_LIBTRACEEVENT=y - The python binding needed some fixups and util/trace-event.c can't be built and linked with the python binding shared object, so remove it in tools/perf/util/setup.py and exclude it from the list of dependencies in the python/perf.so Makefile.perf target. Building without libtraceevent-devel installed uncovered more build failures: - The python binding tools/perf/util/python.c was assuming that traceevent/parse-events.h was always available, which was the case when we defaulted to using the in-kernel tools/lib/traceevent/ files, now we need to enclose it under ifdef HAVE_LIBTRACEEVENT, just like the other parts of it that deal with tracepoints. - We have to ifdef the rules in the Build files with CONFIG_LIBTRACEEVENT=y to build builtin-trace.c and tools/perf/trace/beauty/ as we only ifdef setting CONFIG_TRACE=y when setting NO_LIBTRACEEVENT=1 in the make command line, not when we don't detect libtraceevent-devel installed in the system. Simplification here to avoid these two ways of disabling builtin-trace.c and not having CONFIG_TRACE=y when libtraceevent-devel isn't installed is the clean way. From Athira: tools/perf/arch/powerpc/util/Build -perf-y += kvm-stat.o +perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o Then, ditto for arm64 and s390, detected by container cross build tests. - s/390 uses test__checkevent_tracepoint() that is now only available if HAVE_LIBTRACEEVENT is defined, enclose the callsite with ifder HAVE_LIBTRACEEVENT. Also from Athira: With this change, I could successfully compile in these environment: - Without libtraceevent-devel installed - With libtraceevent-devel installed - With “make NO_LIBTRACEEVENT=1” Then, finally rename CONFIG_TRACEEVENT to CONFIG_LIBTRACEEVENT for consistency with other libraries detected in tools/perf/. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Tested-by: Athira Rajeev Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20221205225940.3079667-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 20 ++-- tools/perf/Makefile.config | 37 ++++--- tools/perf/Makefile.perf | 104 ++---------------- tools/perf/arch/arm64/util/Build | 2 +- tools/perf/arch/powerpc/util/Build | 2 +- tools/perf/arch/s390/util/Build | 2 +- tools/perf/arch/x86/util/Build | 2 +- tools/perf/arch/x86/util/intel-pt.c | 4 + tools/perf/builtin-annotate.c | 2 + tools/perf/builtin-data.c | 5 +- tools/perf/builtin-inject.c | 8 ++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 12 +- tools/perf/builtin-kwork.c | 1 + tools/perf/builtin-record.c | 2 + tools/perf/builtin-report.c | 9 +- tools/perf/builtin-script.c | 19 +++- tools/perf/builtin-timechart.c | 1 + tools/perf/builtin-trace.c | 5 +- tools/perf/builtin-version.c | 1 + tools/perf/perf.c | 24 +++- .../perf/scripts/python/Perf-Trace-Util/Build | 2 +- tools/perf/tests/Build | 12 +- tools/perf/tests/builtin-test.c | 6 + tools/perf/tests/parse-events.c | 23 +++- tools/perf/util/Build | 21 ++-- tools/perf/util/data-convert-bt.c | 5 +- tools/perf/util/data-convert-json.c | 9 +- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 4 + tools/perf/util/evsel.c | 11 +- tools/perf/util/evsel.h | 12 +- tools/perf/util/evsel_fprintf.c | 7 +- tools/perf/util/header.c | 19 ++++ tools/perf/util/header.h | 2 + tools/perf/util/intel-pt.c | 7 +- tools/perf/util/parse-events.c | 15 +++ tools/perf/util/parse-events.h | 1 - tools/perf/util/python.c | 10 ++ tools/perf/util/scripting-engines/Build | 6 +- .../util/scripting-engines/trace-event-perl.c | 1 + .../scripting-engines/trace-event-python.c | 1 + tools/perf/util/session.c | 2 + tools/perf/util/session.h | 2 + tools/perf/util/setup.py | 10 +- tools/perf/util/sort.c | 60 ++++++++-- tools/perf/util/synthetic-events.c | 6 + tools/perf/util/trace-event-parse.c | 2 + tools/perf/util/trace-event-read.c | 1 + tools/perf/util/trace-event-scripting.c | 1 + tools/perf/util/trace-event.c | 1 - tools/perf/util/trace-event.h | 11 +- 52 files changed, 355 insertions(+), 184 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index 496b096153bb1..6dd67e5022955 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -5,7 +5,6 @@ perf-y += builtin-diff.o perf-y += builtin-evlist.o perf-y += builtin-ftrace.o perf-y += builtin-help.o -perf-y += builtin-sched.o perf-y += builtin-buildid-list.o perf-y += builtin-buildid-cache.o perf-y += builtin-kallsyms.o @@ -13,11 +12,8 @@ perf-y += builtin-list.o perf-y += builtin-record.o perf-y += builtin-report.o perf-y += builtin-stat.o -perf-y += builtin-timechart.o perf-y += builtin-top.o perf-y += builtin-script.o -perf-y += builtin-kmem.o -perf-y += builtin-lock.o perf-y += builtin-kvm.o perf-y += builtin-inject.o perf-y += builtin-mem.o @@ -25,9 +21,18 @@ perf-y += builtin-data.o perf-y += builtin-version.o perf-y += builtin-c2c.o perf-y += builtin-daemon.o -perf-y += builtin-kwork.o -perf-$(CONFIG_TRACE) += builtin-trace.o +perf-$(CONFIG_LIBTRACEEVENT) += builtin-kmem.o +perf-$(CONFIG_LIBTRACEEVENT) += builtin-kwork.o +perf-$(CONFIG_LIBTRACEEVENT) += builtin-lock.o +perf-$(CONFIG_LIBTRACEEVENT) += builtin-sched.o +perf-$(CONFIG_LIBTRACEEVENT) += builtin-timechart.o + +ifeq ($(CONFIG_LIBTRACEEVENT),y) + perf-$(CONFIG_TRACE) += builtin-trace.o + perf-$(CONFIG_TRACE) += trace/beauty/ +endif + perf-$(CONFIG_LIBELF) += builtin-probe.o perf-y += bench/ @@ -51,7 +56,6 @@ CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)" perf-y += util/ perf-y += arch/ perf-y += ui/ -perf-y += scripts/ -perf-$(CONFIG_TRACE) += trace/beauty/ +perf-$(CONFIG_LIBTRACEEVENT) += scripts/ gtk-y += ui/gtk/ diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 9cc3c48f32881..680228e19c1aa 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -763,18 +763,20 @@ ifndef NO_LIBUNWIND EXTLIBS += $(EXTLIBS_LIBUNWIND) endif -ifeq ($(NO_SYSCALL_TABLE),0) - $(call detected,CONFIG_TRACE) -else - ifndef NO_LIBAUDIT - $(call feature_check,libaudit) - ifneq ($(feature-libaudit), 1) - msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); - NO_LIBAUDIT := 1 - else - CFLAGS += -DHAVE_LIBAUDIT_SUPPORT - EXTLIBS += -laudit - $(call detected,CONFIG_TRACE) +ifneq ($(NO_LIBTRACEEVENT),1) + ifeq ($(NO_SYSCALL_TABLE),0) + $(call detected,CONFIG_TRACE) + else + ifndef NO_LIBAUDIT + $(call feature_check,libaudit) + ifneq ($(feature-libaudit), 1) + msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); + NO_LIBAUDIT := 1 + else + CFLAGS += -DHAVE_LIBAUDIT_SUPPORT + EXTLIBS += -laudit + $(call detected,CONFIG_TRACE) + endif endif endif endif @@ -1182,9 +1184,11 @@ ifdef LIBPFM4 endif endif -ifdef LIBTRACEEVENT_DYNAMIC +# libtraceevent is a recommended dependency picked up from the system. +ifneq ($(NO_LIBTRACEEVENT),1) $(call feature_check,libtraceevent) ifeq ($(feature-libtraceevent), 1) + CFLAGS += -DHAVE_LIBTRACEEVENT EXTLIBS += -ltraceevent LIBTRACEEVENT_VERSION := $(shell $(PKG_CONFIG) --modversion libtraceevent) LIBTRACEEVENT_VERSION_1 := $(word 1, $(subst ., ,$(LIBTRACEEVENT_VERSION))) @@ -1192,12 +1196,11 @@ ifdef LIBTRACEEVENT_DYNAMIC LIBTRACEEVENT_VERSION_3 := $(word 3, $(subst ., ,$(LIBTRACEEVENT_VERSION))) LIBTRACEEVENT_VERSION_CPP := $(shell expr $(LIBTRACEEVENT_VERSION_1) \* 255 \* 255 + $(LIBTRACEEVENT_VERSION_2) \* 255 + $(LIBTRACEEVENT_VERSION_3)) CFLAGS += -DLIBTRACEEVENT_VERSION=$(LIBTRACEEVENT_VERSION_CPP) + $(call detected,CONFIG_LIBTRACEEVENT) else - dummy := $(error Error: No libtraceevent devel library found, please install libtraceevent-devel); + dummy := $(warning Warning: libtraceevent is missing limiting functionality, please install libtraceevent-dev/libtraceevent-devel) endif -endif -ifdef LIBTRACEFS_DYNAMIC $(call feature_check,libtracefs) ifeq ($(feature-libtracefs), 1) EXTLIBS += -ltracefs @@ -1207,8 +1210,6 @@ ifdef LIBTRACEFS_DYNAMIC LIBTRACEFS_VERSION_3 := $(word 3, $(subst ., ,$(LIBTRACEFS_VERSION))) LIBTRACEFS_VERSION_CPP := $(shell expr $(LIBTRACEFS_VERSION_1) \* 255 \* 255 + $(LIBTRACEFS_VERSION_2) \* 255 + $(LIBTRACEFS_VERSION_3)) CFLAGS += -DLIBTRACEFS_VERSION=$(LIBTRACEFS_VERSION_CPP) - else - dummy := $(error Error: No libtracefs devel library found, please install libtracefs-dev); endif endif diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6689f644782f5..98f629bbd1aae 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -128,10 +128,6 @@ include ../scripts/utilities.mak # # Define BUILD_BPF_SKEL to enable BPF skeletons # -# Define LIBTRACEEVENT_DYNAMIC to enable libtraceevent dynamic linking -# -# Define LIBTRACEFS_DYNAMIC to enable libtracefs dynamic linking -# # As per kernel Makefile, avoid funny character set dependencies unexport LC_ALL @@ -242,10 +238,6 @@ sub-make: fixdep else # force_fixdep LIBAPI_DIR = $(srctree)/tools/lib/api/ -ifndef LIBTRACEEVENT_DYNAMIC -LIBTRACEEVENT_DIR = $(srctree)/tools/lib/traceevent/ -LIBTRACEEVENT_PLUGINS_DIR = $(LIBTRACEEVENT_DIR)/plugins -endif LIBBPF_DIR = $(srctree)/tools/lib/bpf/ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ LIBSYMBOL_DIR = $(srctree)/tools/lib/symbol/ @@ -295,31 +287,6 @@ SCRIPT_SH += perf-iostat.sh grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) -ifndef LIBTRACEEVENT_DYNAMIC -ifneq ($(OUTPUT),) - LIBTRACEEVENT_OUTPUT = $(abspath $(OUTPUT))/libtraceevent -else - LIBTRACEEVENT_OUTPUT = $(CURDIR)/libtraceevent -endif -LIBTRACEEVENT_PLUGINS_OUTPUT = $(LIBTRACEEVENT_OUTPUT)_plugins -LIBTRACEEVENT_DESTDIR = $(LIBTRACEEVENT_OUTPUT) -LIBTRACEEVENT_PLUGINS_DESTDIR = $(LIBTRACEEVENT_PLUGINS_OUTPUT) -LIBTRACEEVENT_INCLUDE = $(LIBTRACEEVENT_DESTDIR)/include -LIBTRACEEVENT = $(LIBTRACEEVENT_OUTPUT)/libtraceevent.a -export LIBTRACEEVENT -LIBTRACEEVENT_DYNAMIC_LIST = $(LIBTRACEEVENT_PLUGINS_OUTPUT)/libtraceevent-dynamic-list -CFLAGS += -I$(LIBTRACEEVENT_OUTPUT)/include -# -# The static build has no dynsym table, so this does not work for -# static build. Looks like linker starts to scream about that now -# (in Fedora 26) so we need to switch it off for static build. -DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = $(if $(findstring -static,$(LDFLAGS)),,$(DYNAMIC_LIST_LDFLAGS)) -else -LIBTRACEEVENT_DYNAMIC_LIST = -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -endif - ifneq ($(OUTPUT),) LIBAPI_OUTPUT = $(abspath $(OUTPUT))/libapi else @@ -380,13 +347,14 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf*.so -PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) -ifndef LIBTRACEEVENT_DYNAMIC -PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI) +ifeq ($(CONFIG_LIBTRACEEVENT),y) + PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) else -PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI) + PYTHON_EXT_SRCS := $(shell grep -v '^\#\|util/trace-event.c' util/python-ext-sources) endif +PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI) + SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) PROGRAMS += $(OUTPUT)perf @@ -430,9 +398,6 @@ ifndef NO_LIBBPF PERFLIBS += $(LIBBPF) endif endif -ifndef LIBTRACEEVENT_DYNAMIC - PERFLIBS += $(LIBTRACEEVENT) -endif # We choose to avoid "if .. else if .. else .. endif endif" # because maintaining the nesting to match is a pain. If @@ -682,9 +647,9 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) # Create python binding output directory if not already present _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python') -$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) $(LIBPERF) +$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBPERF) $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \ - CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ + CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' \ $(PYTHON_WORD) util/setup.py \ --quiet build_ext; \ cp $(PYTHON_EXTBUILD_LIB)perf*.so $(OUTPUT)python/ @@ -710,8 +675,8 @@ $(PERF_IN): prepare FORCE $(PMU_EVENTS_IN): FORCE prepare $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events -$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ +$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) \ $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ $(GTK_IN): FORCE prepare @@ -797,10 +762,6 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(LIBSYMBOL) \ bpf-skel -ifndef LIBTRACEEVENT_DYNAMIC -prepare: $(LIBTRACEEVENT) -endif - $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ @@ -856,38 +817,6 @@ endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) -ifndef LIBTRACEEVENT_DYNAMIC -LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(filter-out -static,$(LDFLAGS))' - -$(LIBTRACEEVENT): FORCE | $(LIBTRACEEVENT_OUTPUT) - $(Q)$(MAKE) -C $(LIBTRACEEVENT_DIR) O=$(LIBTRACEEVENT_OUTPUT) \ - DESTDIR=$(LIBTRACEEVENT_DESTDIR) prefix= \ - $@ install_headers - -$(LIBTRACEEVENT)-clean: - $(call QUIET_CLEAN, libtraceevent) - $(Q)$(RM) -r -- $(LIBTRACEEVENT_OUTPUT) - -libtraceevent_plugins: FORCE | $(LIBTRACEEVENT_PLUGINS_OUTPUT) - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ - DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ - plugins - -libtraceevent_plugins-clean: - $(call QUIET_CLEAN, libtraceevent_plugins) - $(Q)$(RM) -r -- $(LIBTRACEEVENT_PLUGINS_OUTPUT) - -$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ - DESTDIR=$(LIBTRACEEVENT_PLUGINS_DESTDIR) prefix= \ - $(LIBTRACEEVENT_FLAGS) $@ - -install-traceevent-plugins: libtraceevent_plugins - $(Q)$(MAKE) -C $(LIBTRACEEVENT_PLUGINS_DIR) O=$(LIBTRACEEVENT_PLUGINS_OUTPUT) \ - DESTDIR=$(DESTDIR_SQ)$(prefix) prefix= \ - $(LIBTRACEEVENT_FLAGS) install -endif - $(LIBAPI): FORCE | $(LIBAPI_OUTPUT) $(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \ DESTDIR=$(LIBAPI_DESTDIR) prefix= \ @@ -1095,10 +1024,6 @@ install-tests: all install-gtk install-bin: install-tools install-tests -ifndef LIBTRACEEVENT_DYNAMIC -install-bin: install-traceevent-plugins -endif - install: install-bin try-install-man install-python_ext: @@ -1124,11 +1049,6 @@ SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT): $(Q)$(MKDIR) -p $@ -ifndef LIBTRACEEVENT_DYNAMIC -$(LIBTRACEEVENT_OUTPUT) $(LIBTRACEEVENT_PLUGINS_OUTPUT): - $(Q)$(MKDIR) -p $@ -endif - ifdef BUILD_BPF_SKEL BPFTOOL := $(SKEL_TMP_OUT)/bootstrap/bpftool BPF_INCLUDE := -I$(SKEL_TMP_OUT)/.. -I$(LIBBPF_INCLUDE) @@ -1211,10 +1131,6 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $( $(call QUIET_CLEAN, Documentation) \ $(MAKE) -C $(DOC_DIR) O=$(OUTPUT) clean >/dev/null -ifndef LIBTRACEEVENT_DYNAMIC -clean:: $(LIBTRACEEVENT)-clean libtraceevent_plugins-clean -endif - # # To provide FEATURE-DUMP into $(FEATURE_DUMP_COPY) # file if defined, with no further action. @@ -1232,6 +1148,6 @@ FORCE: .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope FORCE prepare -.PHONY: libtraceevent_plugins archheaders +.PHONY: archheaders endif # force_fixdep diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build index 337aa9bdf905d..78ef7115be3d9 100644 --- a/tools/perf/arch/arm64/util/Build +++ b/tools/perf/arch/arm64/util/Build @@ -3,7 +3,7 @@ perf-y += machine.o perf-y += perf_regs.o perf-y += tsc.o perf-y += pmu.o -perf-y += kvm-stat.o +perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-$(CONFIG_DWARF) += dwarf-regs.o perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build index 0115f31665684..9889245c555c4 100644 --- a/tools/perf/arch/powerpc/util/Build +++ b/tools/perf/arch/powerpc/util/Build @@ -1,5 +1,5 @@ perf-y += header.o -perf-y += kvm-stat.o +perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-y += perf_regs.o perf-y += mem-events.o perf-y += sym-handling.o diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build index 3d9d0f4f72ca1..db68840869979 100644 --- a/tools/perf/arch/s390/util/Build +++ b/tools/perf/arch/s390/util/Build @@ -1,5 +1,5 @@ perf-y += header.o -perf-y += kvm-stat.o +perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-y += perf_regs.o perf-$(CONFIG_DWARF) += dwarf-regs.o diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index dbeb04cb336e0..195ccfdef7aa1 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -1,7 +1,7 @@ perf-y += header.o perf-y += tsc.o perf-y += pmu.o -perf-y += kvm-stat.o +perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-y += perf_regs.o perf-y += topdown.o perf-y += machine.o diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index af102f471e9f4..1e39a034cee98 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -418,6 +418,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, return 0; } +#ifdef HAVE_LIBTRACEEVENT static int intel_pt_track_switches(struct evlist *evlist) { const char *sched_switch = "sched:sched_switch"; @@ -439,6 +440,7 @@ static int intel_pt_track_switches(struct evlist *evlist) return 0; } +#endif static void intel_pt_valid_str(char *str, size_t len, u64 valid) { @@ -829,6 +831,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ptr->have_sched_switch = 2; } } else { +#ifdef HAVE_LIBTRACEEVENT err = intel_pt_track_switches(evlist); if (err == -EPERM) pr_debug2("Unable to select sched:sched_switch\n"); @@ -836,6 +839,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, return err; else ptr->have_sched_switch = 1; +#endif } } diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 517d928c00e3f..90458ca6933fd 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -499,7 +499,9 @@ int cmd_annotate(int argc, const char **argv) .namespaces = perf_event__process_namespaces, .attr = perf_event__process_attr, .build_id = perf_event__process_build_id, +#ifdef HAVE_LIBTRACEEVENT .tracing_data = perf_event__process_tracing_data, +#endif .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index c22d82d2a73c4..b2a9a3b7f68d7 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -78,12 +78,13 @@ static int cmd_data_convert(int argc, const char **argv) return bt_convert__perf2json(input_name, to_json, &opts); if (to_ctf) { -#ifdef HAVE_LIBBABELTRACE_SUPPORT +#if defined(HAVE_LIBBABELTRACE_SUPPORT) && defined(HAVE_LIBTRACEEVENT) return bt_convert__perf2ctf(input_name, to_ctf, &opts); #else pr_err("The libbabeltrace support is not compiled in. perf should be " "compiled with environment variables LIBBABELTRACE=1 and " - "LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n"); + "LIBBABELTRACE_DIR=/path/to/libbabeltrace/.\n" + "Check also if libbtraceevent devel files are available.\n"); return -1; #endif } diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index e254f18986f7c..3f4e4dd5abf31 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -607,6 +607,7 @@ static int perf_event__repipe_exit(struct perf_tool *tool, return err; } +#ifdef HAVE_LIBTRACEEVENT static int perf_event__repipe_tracing_data(struct perf_session *session, union perf_event *event) { @@ -614,6 +615,7 @@ static int perf_event__repipe_tracing_data(struct perf_session *session, return perf_event__process_tracing_data(session, event); } +#endif static int dso__read_build_id(struct dso *dso) { @@ -807,6 +809,7 @@ static int perf_inject__sched_switch(struct perf_tool *tool, return 0; } +#ifdef HAVE_LIBTRACEEVENT static int perf_inject__sched_stat(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample, @@ -836,6 +839,7 @@ found: build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); return perf_event__repipe(tool, event_sw, &sample_sw, machine); } +#endif static struct guest_vcpu *guest_session__vcpu(struct guest_session *gs, u32 vcpu) { @@ -1961,7 +1965,9 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.mmap = perf_event__repipe_mmap; inject->tool.mmap2 = perf_event__repipe_mmap2; inject->tool.fork = perf_event__repipe_fork; +#ifdef HAVE_LIBTRACEEVENT inject->tool.tracing_data = perf_event__repipe_tracing_data; +#endif } output_data_offset = perf_session__data_offset(session->evlist); @@ -1984,8 +1990,10 @@ static int __cmd_inject(struct perf_inject *inject) evsel->handler = perf_inject__sched_switch; } else if (!strcmp(name, "sched:sched_process_exit")) evsel->handler = perf_inject__sched_process_exit; +#ifdef HAVE_LIBTRACEEVENT else if (!strncmp(name, "sched:sched_stat_", 17)) evsel->handler = perf_inject__sched_stat; +#endif } } else if (inject->itrace_synth_opts.vm_time_correlation) { session->itrace_synth_opts = &inject->itrace_synth_opts; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index ebfab2ca17024..e20656c431a4b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -35,6 +35,7 @@ #include #include +#include static int kmem_slab; static int kmem_page; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7d9ec1bac1a25..641e739c717ce 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -63,7 +63,7 @@ static const char *get_filename_for_perf_kvm(void) return filename; } -#ifdef HAVE_KVM_STAT_SUPPORT +#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, @@ -654,7 +654,7 @@ static void print_result(struct perf_kvm_stat *kvm) pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events); } -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) static int process_lost_event(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, @@ -742,7 +742,7 @@ static bool verify_vcpu(int vcpu) return true; } -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) /* keeping the max events to a modest level to keep * the processing of samples per mmap smooth. */ @@ -1290,7 +1290,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) return kvm_events_report_vcpu(kvm); } -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) static struct evlist *kvm_live_event_list(void) { struct evlist *evlist; @@ -1507,7 +1507,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) if (strlen(argv[1]) > 2 && strstarts("report", argv[1])) return kvm_events_report(&kvm, argc - 1 , argv + 1); -#ifdef HAVE_TIMERFD_SUPPORT +#if defined(HAVE_TIMERFD_SUPPORT) && defined(HAVE_LIBTRACEEVENT) if (!strncmp(argv[1], "live", 4)) return kvm_events_live(&kvm, argc - 1 , argv + 1); #endif @@ -1644,7 +1644,7 @@ int cmd_kvm(int argc, const char **argv) return cmd_top(argc, argv); else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) return __cmd_buildid_list(file_name, argc, argv); -#ifdef HAVE_KVM_STAT_SUPPORT +#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) return kvm_cmd_stat(file_name, argc, argv); #endif diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c index 0e02b80986440..dc59d75180d14 100644 --- a/tools/perf/builtin-kwork.c +++ b/tools/perf/builtin-kwork.c @@ -23,6 +23,7 @@ #include #include +#include #include #include diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b7fd7ec586fbc..7e17374f6c1a2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1701,8 +1701,10 @@ static void record__init_features(struct record *rec) if (rec->no_buildid) perf_header__clear_feat(&session->header, HEADER_BUILD_ID); +#ifdef HAVE_LIBTRACEEVENT if (!have_tracepoints(&rec->evlist->core.entries)) perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); +#endif if (!rec->opts.branch_stack) perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b6d77d3da64f6..2ee2ecca208e1 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -67,6 +67,10 @@ #include #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct report { struct perf_tool tool; struct perf_session *session; @@ -1199,7 +1203,9 @@ int cmd_report(int argc, const char **argv) .lost = perf_event__process_lost, .read = process_read_event, .attr = process_attr, +#ifdef HAVE_LIBTRACEEVENT .tracing_data = perf_event__process_tracing_data, +#endif .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, @@ -1660,6 +1666,7 @@ repeat: report.range_num); } +#ifdef HAVE_LIBTRACEEVENT if (session->tevent.pevent && tep_set_function_resolver(session->tevent.pevent, machine__resolve_kernel_addr, @@ -1668,7 +1675,7 @@ repeat: __func__); return -1; } - +#endif sort__setup_elide(stdout); ret = __cmd_report(&report); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d7ec8c1af2936..88888fb885c82 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -62,6 +62,9 @@ #include "perf.h" #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif static char const *script_name; static char const *generate_script_lang; @@ -2154,12 +2157,12 @@ static void process_event(struct perf_script *script, perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp); return; } - +#ifdef HAVE_LIBTRACEEVENT if (PRINT_FIELD(TRACE) && sample->raw_data) { event_format__fprintf(evsel->tp_format, sample->cpu, sample->raw_data, sample->raw_size, fp); } - +#endif if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) perf_sample__fprintf_synth(sample, evsel, fp); @@ -2283,8 +2286,10 @@ static void process_stat_interval(u64 tstamp) static void setup_scripting(void) { +#ifdef HAVE_LIBTRACEEVENT setup_perl_scripting(); setup_python_scripting(); +#endif } static int flush_scripting(void) @@ -3784,7 +3789,9 @@ int cmd_script(int argc, const char **argv) .fork = perf_event__process_fork, .attr = process_attr, .event_update = perf_event__process_event_update, +#ifdef HAVE_LIBTRACEEVENT .tracing_data = perf_event__process_tracing_data, +#endif .feature = process_feature_event, .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index, @@ -4215,6 +4222,7 @@ script_found: else symbol_conf.use_callchain = false; +#ifdef HAVE_LIBTRACEEVENT if (session->tevent.pevent && tep_set_function_resolver(session->tevent.pevent, machine__resolve_kernel_addr, @@ -4223,7 +4231,7 @@ script_found: err = -1; goto out_delete; } - +#endif if (generate_script_lang) { struct stat perf_stat; int input; @@ -4259,9 +4267,12 @@ script_found: err = -ENOENT; goto out_delete; } - +#ifdef HAVE_LIBTRACEEVENT err = scripting_ops->generate_script(session->tevent.pevent, "perf-script"); +#else + err = scripting_ops->generate_script(NULL, "perf-script"); +#endif goto out_delete; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index c36296bb7637e..6c629e7d370ad 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -38,6 +38,7 @@ #include "util/string2.h" #include "util/tracepoint.h" #include +#include #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE FILE *open_memstream(char **ptr, size_t *sizeloc); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 543c379d2a57a..6909cd9f48d11 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -15,7 +15,6 @@ */ #include "util/record.h" -#include #include #include #include "util/bpf_map.h" @@ -80,6 +79,10 @@ #include #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + #ifndef O_CLOEXEC # define O_CLOEXEC 02000000 #endif diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index a71f491224da1..a886929ec6e5f 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c @@ -82,6 +82,7 @@ static void library_status(void) STATUS(HAVE_AIO_SUPPORT, aio); STATUS(HAVE_ZSTD_SUPPORT, zstd); STATUS(HAVE_LIBPFM, libpfm4); + STATUS(HAVE_LIBTRACEEVENT, libtraceevent); } int cmd_version(int argc, const char **argv) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 7af135dea1cd8..82bbe0ca858bd 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -70,20 +70,26 @@ static struct cmd_struct commands[] = { { "report", cmd_report, 0 }, { "bench", cmd_bench, 0 }, { "stat", cmd_stat, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "timechart", cmd_timechart, 0 }, +#endif { "top", cmd_top, 0 }, { "annotate", cmd_annotate, 0 }, { "version", cmd_version, 0 }, { "script", cmd_script, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "sched", cmd_sched, 0 }, +#endif #ifdef HAVE_LIBELF_SUPPORT { "probe", cmd_probe, 0 }, #endif +#ifdef HAVE_LIBTRACEEVENT { "kmem", cmd_kmem, 0 }, { "lock", cmd_lock, 0 }, +#endif { "kvm", cmd_kvm, 0 }, { "test", cmd_test, 0 }, -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT) +#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)) { "trace", cmd_trace, 0 }, #endif { "inject", cmd_inject, 0 }, @@ -91,7 +97,9 @@ static struct cmd_struct commands[] = { { "data", cmd_data, 0 }, { "ftrace", cmd_ftrace, 0 }, { "daemon", cmd_daemon, 0 }, +#ifdef HAVE_LIBTRACEEVENT { "kwork", cmd_kwork, 0 }, +#endif }; struct pager_config { @@ -500,14 +508,18 @@ int main(int argc, const char **argv) argv[0] = cmd; } if (strstarts(cmd, "trace")) { -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT) - setup_path(); - argv[0] = "trace"; - return cmd_trace(argc, argv); -#else +#ifndef HAVE_LIBTRACEEVENT + fprintf(stderr, + "trace command not available: missing libtraceevent devel package at build time.\n"); + goto out; +#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT) fprintf(stderr, "trace command not available: missing audit-libs devel package at build time.\n"); goto out; +#else + setup_path(); + argv[0] = "trace"; + return cmd_trace(argc, argv); #endif } /* Look for flags.. */ diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Build b/tools/perf/scripts/python/Perf-Trace-Util/Build index 7d0e33ce6aba4..d5fed4e426179 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Build +++ b/tools/perf/scripts/python/Perf-Trace-Util/Build @@ -1,3 +1,3 @@ -perf-y += Context.o +perf-$(CONFIG_LIBTRACEEVENT) += Context.o CFLAGS_Context.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 658b5052c24d2..90fd1eb317bb4 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -6,13 +6,13 @@ perf-y += parse-events.o perf-y += dso-data.o perf-y += attr.o perf-y += vmlinux-kallsyms.o -perf-y += openat-syscall.o -perf-y += openat-syscall-all-cpus.o -perf-y += openat-syscall-tp-fields.o -perf-y += mmap-basic.o +perf-$(CONFIG_LIBTRACEEVENT) += openat-syscall.o +perf-$(CONFIG_LIBTRACEEVENT) += openat-syscall-all-cpus.o +perf-$(CONFIG_LIBTRACEEVENT) += openat-syscall-tp-fields.o +perf-$(CONFIG_LIBTRACEEVENT) += mmap-basic.o perf-y += perf-record.o perf-y += evsel-roundtrip-name.o -perf-y += evsel-tp-sched.o +perf-$(CONFIG_LIBTRACEEVENT) += evsel-tp-sched.o perf-y += fdarray.o perf-y += pmu.o perf-y += pmu-events.o @@ -30,7 +30,7 @@ perf-y += task-exit.o perf-y += sw-clock.o perf-y += mmap-thread-lookup.o perf-y += thread-maps-share.o -perf-y += switch-tracking.o +perf-$(CONFIG_LIBTRACEEVENT) += switch-tracking.o perf-y += keep-tracking.o perf-y += code-reading.o perf-y += sample-parsing.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index ddd8262bfa264..f6c16ad8ed506 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -38,9 +38,11 @@ struct test_suite *__weak arch_tests[] = { static struct test_suite *generic_tests[] = { &suite__vmlinux_matches_kallsyms, +#ifdef HAVE_LIBTRACEEVENT &suite__openat_syscall_event, &suite__openat_syscall_event_on_all_cpus, &suite__basic_mmap, +#endif &suite__mem, &suite__parse_events, &suite__expr, @@ -51,8 +53,10 @@ static struct test_suite *generic_tests[] = { &suite__dso_data_cache, &suite__dso_data_reopen, &suite__perf_evsel__roundtrip_name_test, +#ifdef HAVE_LIBTRACEEVENT &suite__perf_evsel__tp_sched_test, &suite__syscall_openat_tp_fields, +#endif &suite__attr, &suite__hists_link, &suite__python_use, @@ -71,7 +75,9 @@ static struct test_suite *generic_tests[] = { &suite__thread_maps_share, &suite__hists_output, &suite__hists_cumulate, +#ifdef HAVE_LIBTRACEEVENT &suite__switch_tracking, +#endif &suite__fdarray__filter, &suite__fdarray__add, &suite__kmod_path__parse, diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 3440dd2616b06..71a5cb3433117 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -20,6 +20,8 @@ #define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) +#ifdef HAVE_LIBTRACEEVENT + #if defined(__s390x__) /* Return true if kvm module is available and loaded. Test this * and return success when trace point kvm_s390_create_vm @@ -76,6 +78,7 @@ static int test__checkevent_tracepoint_multi(struct evlist *evlist) } return TEST_OK; } +#endif /* HAVE_LIBTRACEEVENT */ static int test__checkevent_raw(struct evlist *evlist) { @@ -222,6 +225,7 @@ static int test__checkevent_breakpoint_rw(struct evlist *evlist) return TEST_OK; } +#ifdef HAVE_LIBTRACEEVENT static int test__checkevent_tracepoint_modifier(struct evlist *evlist) { struct evsel *evsel = evlist__first(evlist); @@ -252,6 +256,7 @@ test__checkevent_tracepoint_multi_modifier(struct evlist *evlist) return test__checkevent_tracepoint_multi(evlist); } +#endif /* HAVE_LIBTRACEEVENT */ static int test__checkevent_raw_modifier(struct evlist *evlist) { @@ -453,6 +458,7 @@ static int test__checkevent_pmu(struct evlist *evlist) return TEST_OK; } +#ifdef HAVE_LIBTRACEEVENT static int test__checkevent_list(struct evlist *evlist) { struct evsel *evsel = evlist__first(evlist); @@ -491,6 +497,7 @@ static int test__checkevent_list(struct evlist *evlist) return TEST_OK; } +#endif static int test__checkevent_pmu_name(struct evlist *evlist) { @@ -762,6 +769,7 @@ static int test__group2(struct evlist *evlist) return TEST_OK; } +#ifdef HAVE_LIBTRACEEVENT static int test__group3(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -853,6 +861,7 @@ static int test__group3(struct evlist *evlist __maybe_unused) return TEST_OK; } +#endif static int test__group4(struct evlist *evlist __maybe_unused) { @@ -1460,6 +1469,7 @@ static int test__sym_event_dc(struct evlist *evlist) return TEST_OK; } +#ifdef HAVE_LIBTRACEEVENT static int count_tracepoints(void) { struct dirent *events_ent; @@ -1513,6 +1523,7 @@ static int test__all_tracepoints(struct evlist *evlist) return test__checkevent_tracepoint_multi(evlist); } +#endif /* HAVE_LIBTRACEVENT */ static int test__hybrid_hw_event_with_pmu(struct evlist *evlist) { @@ -1642,6 +1653,7 @@ struct evlist_test { }; static const struct evlist_test test__events[] = { +#ifdef HAVE_LIBTRACEEVENT { .name = "syscalls:sys_enter_openat", .check = test__checkevent_tracepoint, @@ -1652,6 +1664,7 @@ static const struct evlist_test test__events[] = { .check = test__checkevent_tracepoint_multi, /* 1 */ }, +#endif { .name = "r1a", .check = test__checkevent_raw, @@ -1702,6 +1715,7 @@ static const struct evlist_test test__events[] = { .check = test__checkevent_breakpoint_w, /* 1 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name = "syscalls:sys_enter_openat:k", .check = test__checkevent_tracepoint_modifier, @@ -1712,6 +1726,7 @@ static const struct evlist_test test__events[] = { .check = test__checkevent_tracepoint_multi_modifier, /* 3 */ }, +#endif { .name = "r1a:kp", .check = test__checkevent_raw_modifier, @@ -1757,11 +1772,13 @@ static const struct evlist_test test__events[] = { .check = test__checkevent_breakpoint_w_modifier, /* 2 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name = "r1,syscalls:sys_enter_openat:k,1:1:hp", .check = test__checkevent_list, /* 3 */ }, +#endif { .name = "instructions:G", .check = test__checkevent_exclude_host_modifier, @@ -1792,11 +1809,13 @@ static const struct evlist_test test__events[] = { .check = test__group2, /* 9 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name = "group1{syscalls:sys_enter_openat:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", .check = test__group3, /* 0 */ }, +#endif { .name = "{cycles:u,instructions:kp}:p", .check = test__group4, @@ -1807,11 +1826,13 @@ static const struct evlist_test test__events[] = { .check = test__group5, /* 2 */ }, +#ifdef HAVE_LIBTRACEEVENT { .name = "*:*", .check = test__all_tracepoints, /* 3 */ }, +#endif { .name = "{cycles,cache-misses:G}:H", .check = test__group_gh1, @@ -1867,7 +1888,7 @@ static const struct evlist_test test__events[] = { .check = test__checkevent_breakpoint_len_rw_modifier, /* 4 */ }, -#if defined(__s390x__) +#if defined(__s390x__) && defined(HAVE_LIBTRACEEVENT) { .name = "kvm-s390:kvm_s390_create_vm", .check = test__checkevent_tracepoint, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index d04802bfa23fd..8345464d01303 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -69,7 +69,6 @@ perf-y += namespaces.o perf-y += comm.o perf-y += thread.o perf-y += thread_map.o -perf-y += trace-event-parse.o perf-y += parse-events-flex.o perf-y += parse-events-bison.o perf-y += pmu.o @@ -77,11 +76,12 @@ perf-y += pmus.o perf-y += pmu-flex.o perf-y += pmu-bison.o perf-y += pmu-hybrid.o -perf-y += trace-event-read.o -perf-y += trace-event-info.o -perf-y += trace-event-scripting.o -perf-y += trace-event.o perf-y += svghelper.o +perf-$(CONFIG_LIBTRACEEVENT) += trace-event-info.o +perf-$(CONFIG_LIBTRACEEVENT) += trace-event-scripting.o +perf-$(CONFIG_LIBTRACEEVENT) += trace-event.o +perf-$(CONFIG_LIBTRACEEVENT) += trace-event-parse.o +perf-$(CONFIG_LIBTRACEEVENT) += trace-event-read.o perf-y += sort.o perf-y += hist.o perf-y += util.o @@ -153,8 +153,12 @@ perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter_cgroup.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_ftrace.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_off_cpu.o -perf-$(CONFIG_PERF_BPF_SKEL) += bpf_kwork.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_lock_contention.o + +ifeq ($(CONFIG_LIBTRACEEVENT),y) + perf-$(CONFIG_PERF_BPF_SKEL) += bpf_kwork.o +endif + perf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o perf-$(CONFIG_LIBELF) += symbol-elf.o perf-$(CONFIG_LIBELF) += probe-file.o @@ -189,7 +193,10 @@ perf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o perf-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o perf-$(CONFIG_LIBUNWIND_AARCH64) += libunwind/arm64.o -perf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o +ifeq ($(CONFIG_LIBTRACEEVENT),y) + perf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o +endif + perf-y += data-convert-json.o perf-y += scripting-engines/ diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index c65cdaf6975ed..8031b586e8138 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "asm/bug.h" #include "data-convert.h" #include "session.h" @@ -36,6 +35,10 @@ #include "clockid.h" #include "util/sample.h" +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + #define pr_N(n, fmt, ...) \ eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index 57db59068cb68..ba9d93ce94638 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -27,6 +27,10 @@ #include "util/thread.h" #include "util/tool.h" +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct convert_json { struct perf_tool tool; FILE *out; @@ -217,6 +221,7 @@ static int process_sample_event(struct perf_tool *tool, } output_json_format(out, false, 3, "]"); +#ifdef HAVE_LIBTRACEEVENT if (sample->raw_data) { int i; struct tep_format_field **fields; @@ -236,7 +241,7 @@ static int process_sample_event(struct perf_tool *tool, free(fields); } } - +#endif output_json_format(out, false, 2, "}"); return 0; } @@ -313,7 +318,9 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, .exit = perf_event__process_exit, .fork = perf_event__process_fork, .lost = perf_event__process_lost, +#ifdef HAVE_LIBTRACEEVENT .tracing_data = perf_event__process_tracing_data, +#endif .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fbf3192bced97..590d4e77effcf 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -290,6 +290,7 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide) return evsel; } +#ifdef HAVE_LIBTRACEEVENT struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_wide) { struct evsel *evsel = evsel__newtp_idx("sched", "sched_switch", 0); @@ -305,7 +306,8 @@ struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_wide) evlist__add(evlist, evsel); return evsel; -}; +} +#endif int evlist__add_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs) { @@ -376,6 +378,7 @@ struct evsel *evlist__find_tracepoint_by_name(struct evlist *evlist, const char return NULL; } +#ifdef HAVE_LIBTRACEEVENT int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, void *handler) { struct evsel *evsel = evsel__newtp(sys, name); @@ -387,6 +390,7 @@ int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, evlist__add(evlist, evsel); return 0; } +#endif struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affinity *affinity) { diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 16734c6756b3c..e5b84ead566c9 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -127,7 +127,9 @@ static inline struct evsel *evlist__add_dummy_on_all_cpus(struct evlist *evlist) { return evlist__add_aux_dummy(evlist, true); } +#ifdef HAVE_LIBTRACEEVENT struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_wide); +#endif int evlist__add_sb_event(struct evlist *evlist, struct perf_event_attr *attr, evsel__sb_cb_t cb, void *data); @@ -135,7 +137,9 @@ void evlist__set_cb(struct evlist *evlist, evsel__sb_cb_t cb, void *data); int evlist__start_sb_thread(struct evlist *evlist, struct target *target); void evlist__stop_sb_thread(struct evlist *evlist); +#ifdef HAVE_LIBTRACEEVENT int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, void *handler); +#endif int __evlist__set_tracepoints_handlers(struct evlist *evlist, const struct evsel_str_handler *assocs, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0f617359a82f2..ca911856c4b1d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -57,6 +56,10 @@ #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + struct perf_missing_features perf_missing_features; static clockid_t clockid; @@ -439,7 +442,9 @@ struct evsel *evsel__clone(struct evsel *orig) goto out_err; } evsel->cgrp = cgroup__get(orig->cgrp); +#ifdef HAVE_LIBTRACEEVENT evsel->tp_format = orig->tp_format; +#endif evsel->handler = orig->handler; evsel->core.leader = orig->core.leader; @@ -479,6 +484,7 @@ out_err: /* * Returns pointer with encoded error via interface. */ +#ifdef HAVE_LIBTRACEEVENT struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx) { struct evsel *evsel = zalloc(perf_evsel__object.size); @@ -516,6 +522,7 @@ out_free: out_err: return ERR_PTR(err); } +#endif const char *const evsel__hw_names[PERF_COUNT_HW_MAX] = { "cycles", @@ -2758,6 +2765,7 @@ u16 evsel__id_hdr_size(struct evsel *evsel) return size; } +#ifdef HAVE_LIBTRACEEVENT struct tep_format_field *evsel__field(struct evsel *evsel, const char *name) { return tep_find_field(evsel->tp_format, name); @@ -2831,6 +2839,7 @@ u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *n return field ? format_field__intval(field, sample, evsel->needs_swap) : 0; } +#endif bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index f3485799ddf9e..d572be41b9608 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -72,7 +72,9 @@ struct evsel { char *name; char *group_name; const char *pmu_name; +#ifdef HAVE_LIBTRACEEVENT struct tep_event *tp_format; +#endif char *filter; unsigned long max_events; double scale; @@ -223,11 +225,14 @@ static inline struct evsel *evsel__new(struct perf_event_attr *attr) } struct evsel *evsel__clone(struct evsel *orig); -struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx); int copy_config_terms(struct list_head *dst, struct list_head *src); void free_config_terms(struct list_head *config_terms); + +#ifdef HAVE_LIBTRACEEVENT +struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx); + /* * Returns pointer with encoded error via interface. */ @@ -235,10 +240,13 @@ static inline struct evsel *evsel__newtp(const char *sys, const char *name) { return evsel__newtp_idx(sys, name, 0); } +#endif struct evsel *evsel__new_cycles(bool precise, __u32 type, __u64 config); +#ifdef HAVE_LIBTRACEEVENT struct tep_event *event_format__new(const char *sys, const char *name); +#endif void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx); void evsel__exit(struct evsel *evsel); @@ -323,6 +331,7 @@ bool evsel__precise_ip_fallback(struct evsel *evsel); struct perf_sample; +#ifdef HAVE_LIBTRACEEVENT void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name); u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name); @@ -330,6 +339,7 @@ static inline char *evsel__strval(struct evsel *evsel, struct perf_sample *sampl { return evsel__rawptr(evsel, sample, name); } +#endif struct tep_format_field; diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 8c2ea80013291..bd22c4932d10e 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "evsel.h" #include "util/evsel_fprintf.h" #include "util/event.h" @@ -13,6 +12,10 @@ #include "srcline.h" #include "dso.h" +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) { va_list args; @@ -74,6 +77,7 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE term, (u64)evsel->core.attr.sample_freq); } +#ifdef HAVE_LIBTRACEEVENT if (details->trace_fields) { struct tep_format_field *field; @@ -96,6 +100,7 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE field = field->next; } } +#endif out: fputc('\n', fp); return ++printed; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index dc2ae397d400e..404d816ca1242 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ #include #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + /* * magic2 = "PERFILE2" * must be a numerical value to let the endianness @@ -298,6 +303,7 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize) return 0; } +#ifdef HAVE_LIBTRACEEVENT static int write_tracing_data(struct feat_fd *ff, struct evlist *evlist) { @@ -306,6 +312,7 @@ static int write_tracing_data(struct feat_fd *ff, return read_tracing_data(ff->fd, &evlist->core.entries); } +#endif static int write_build_id(struct feat_fd *ff, struct evlist *evlist __maybe_unused) @@ -2394,12 +2401,14 @@ FEAT_PROCESS_STR_FUN(arch, arch); FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc); FEAT_PROCESS_STR_FUN(cpuid, cpuid); +#ifdef HAVE_LIBTRACEEVENT static int process_tracing_data(struct feat_fd *ff, void *data) { ssize_t ret = trace_report(ff->fd, data, false); return ret < 0 ? -1 : 0; } +#endif static int process_build_id(struct feat_fd *ff, void *data __maybe_unused) { @@ -3366,7 +3375,9 @@ err: const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE]; const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = { +#ifdef HAVE_LIBTRACEEVENT FEAT_OPN(TRACING_DATA, tracing_data, false), +#endif FEAT_OPN(BUILD_ID, build_id, false), FEAT_OPR(HOSTNAME, hostname, false), FEAT_OPR(OSRELEASE, osrelease, false), @@ -4082,6 +4093,7 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } +#ifdef HAVE_LIBTRACEEVENT static int evsel__prepare_tracepoint_event(struct evsel *evsel, struct tep_handle *pevent) { struct tep_event *event; @@ -4125,6 +4137,7 @@ static int evlist__prepare_tracepoint_events(struct evlist *evlist, struct tep_h return 0; } +#endif int perf_session__read_header(struct perf_session *session, int repipe_fd) { @@ -4230,11 +4243,15 @@ int perf_session__read_header(struct perf_session *session, int repipe_fd) lseek(fd, tmp, SEEK_SET); } +#ifdef HAVE_LIBTRACEEVENT perf_header__process_sections(header, fd, &session->tevent, perf_file_section__process); if (evlist__prepare_tracepoint_events(session->evlist, session->tevent.pevent)) goto out_delete_evlist; +#else + perf_header__process_sections(header, fd, NULL, perf_file_section__process); +#endif return 0; out_errno: @@ -4412,6 +4429,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, return 0; } +#ifdef HAVE_LIBTRACEEVENT int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event) { @@ -4459,6 +4477,7 @@ int perf_event__process_tracing_data(struct perf_session *session, return size_read + padding; } +#endif int perf_event__process_build_id(struct perf_session *session, union perf_event *event) diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 2d5e601ba60f0..e3861ae621723 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -160,8 +160,10 @@ int perf_event__process_event_update(struct perf_tool *tool, union perf_event *event, struct evlist **pevlist); size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); +#ifdef HAVE_LIBTRACEEVENT int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event); +#endif int perf_event__process_build_id(struct perf_session *session, union perf_event *event); bool is_perf_magic(u64 magic); diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index e3548ddef2545..6d3921627e332 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3142,6 +3142,7 @@ static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid, return 1; } +#ifdef HAVE_LIBTRACEEVENT static int intel_pt_process_switch(struct intel_pt *pt, struct perf_sample *sample) { @@ -3165,6 +3166,7 @@ static int intel_pt_process_switch(struct intel_pt *pt, return machine__set_current_tid(pt->machine, cpu, -1, tid); } +#endif /* HAVE_LIBTRACEEVENT */ static int intel_pt_context_switch_in(struct intel_pt *pt, struct perf_sample *sample) @@ -3433,9 +3435,12 @@ static int intel_pt_process_event(struct perf_session *session, return err; } +#ifdef HAVE_LIBTRACEEVENT if (pt->switch_evsel && event->header.type == PERF_RECORD_SAMPLE) err = intel_pt_process_switch(pt, sample); - else if (event->header.type == PERF_RECORD_ITRACE_START) + else +#endif + if (event->header.type == PERF_RECORD_ITRACE_START) err = intel_pt_process_itrace_start(pt, event, sample); else if (event->header.type == PERF_RECORD_AUX_OUTPUT_HW_ID) err = intel_pt_process_aux_output_hw_id(pt, event, sample); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6502cd679f577..21cce83462b35 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -445,6 +445,7 @@ out_free_terms: return ret; } +#ifdef HAVE_LIBTRACEEVENT static void tracepoint_error(struct parse_events_error *e, int err, const char *sys, const char *name) { @@ -593,6 +594,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx, closedir(events_dir); return ret; } +#endif /* HAVE_LIBTRACEEVENT */ #ifdef HAVE_LIBBPF_SUPPORT struct __add_bpf_event_param { @@ -1143,6 +1145,7 @@ static int config_term_pmu(struct perf_event_attr *attr, return config_term_common(attr, term, err); } +#ifdef HAVE_LIBTRACEEVENT static int config_term_tracepoint(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err) @@ -1170,6 +1173,7 @@ static int config_term_tracepoint(struct perf_event_attr *attr, return 0; } +#endif static int config_attr(struct perf_event_attr *attr, struct list_head *head, @@ -1325,6 +1329,7 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, struct parse_events_error *err, struct list_head *head_config) { +#ifdef HAVE_LIBTRACEEVENT if (head_config) { struct perf_event_attr attr; @@ -1339,6 +1344,16 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, else return add_tracepoint_event(list, idx, sys, event, err, head_config); +#else + (void)list; + (void)idx; + (void)sys; + (void)event; + (void)head_config; + parse_events_error__handle(err, 0, strdup("unsupported tracepoint"), + strdup("libtraceevent is necessary for tracepoint support")); + return -1; +#endif } int parse_events_add_numeric(struct parse_events_state *parse_state, diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 07df7bb7b0420..428e72eaafcc7 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -18,7 +18,6 @@ struct parse_events_error; struct option; struct perf_pmu; -bool have_tracepoints(struct list_head *evlist); bool is_event_supported(u8 type, u64 config); const char *event_type(int type); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index b5941c74a0d64..6fb84b7455b83 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -5,7 +5,9 @@ #include #include #include +#ifdef HAVE_LIBTRACEEVENT #include +#endif #include #include "evlist.h" #include "callchain.h" @@ -417,6 +419,7 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) return ret; } +#ifdef HAVE_LIBTRACEEVENT static bool is_tracepoint(struct pyrf_event *pevent) { return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT; @@ -486,14 +489,17 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) return tracepoint_field(pevent, field); } +#endif /* HAVE_LIBTRACEEVENT */ static PyObject* pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) { PyObject *obj = NULL; +#ifdef HAVE_LIBTRACEEVENT if (is_tracepoint(pevent)) obj = get_tracepoint_field(pevent, attr_name); +#endif return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); } @@ -1326,6 +1332,9 @@ static struct { static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { +#ifndef HAVE_LIBTRACEEVENT + return NULL; +#else struct tep_event *tp_format; static char *kwlist[] = { "sys", "name", NULL }; char *sys = NULL; @@ -1340,6 +1349,7 @@ static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, return _PyLong_FromLong(-1); return _PyLong_FromLong(tp_format->id); +#endif // HAVE_LIBTRACEEVENT } static PyMethodDef perf__methods[] = { diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build index 0f5ba28339cf9..d47820c0b4d47 100644 --- a/tools/perf/util/scripting-engines/Build +++ b/tools/perf/util/scripting-engines/Build @@ -1,5 +1,7 @@ -perf-$(CONFIG_LIBPERL) += trace-event-perl.o -perf-$(CONFIG_LIBPYTHON) += trace-event-python.o +ifeq ($(CONFIG_LIBTRACEEVENT),y) + perf-$(CONFIG_LIBPERL) += trace-event-perl.o + perf-$(CONFIG_LIBPYTHON) += trace-event-python.o +endif CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default -Wno-bad-function-cast -Wno-declaration-after-statement -Wno-switch-enum diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 5b602b6d46854..0bacb49408f84 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /* perl needs the following define, right after including stdbool.h */ diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index d685a7399ee2e..fabba21919b8f 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "../build-id.h" #include "../counts.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1facd4616317d..7c021c6cedb95 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -314,7 +314,9 @@ void perf_session__delete(struct perf_session *session) evlist__delete(session->evlist); perf_data__close(session->data); } +#ifdef HAVE_LIBTRACEEVENT trace_event__cleanup(&session->tevent); +#endif free(session); } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index be5871ea558fe..ee3715e8563bf 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -33,7 +33,9 @@ struct perf_session { struct auxtrace *auxtrace; struct itrace_synth_opts *itrace_synth_opts; struct list_head auxtrace_index; +#ifdef HAVE_LIBTRACEEVENT struct trace_event tevent; +#endif struct perf_record_time_conv time_conv; bool repipe; bool one_mmap; diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 43e7ca40b2ec4..e80ffbbfacfb8 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -63,12 +63,18 @@ libperf = getenv('LIBPERF') ext_sources = [f.strip() for f in open('util/python-ext-sources') if len(f.strip()) > 0 and f[0] != '#'] +extra_libraries = [] + +if '-DHAVE_LIBTRACEEVENT' in cflags: + extra_libraries += [ 'traceevent' ] +else: + ext_sources.remove('util/trace-event.c') + # use full paths with source files ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)) -extra_libraries = [] if '-DHAVE_LIBNUMA_SUPPORT' in cflags: - extra_libraries = [ 'numa' ] + extra_libraries += [ 'numa' ] if '-DHAVE_LIBCAP_SUPPORT' in cflags: extra_libraries += [ 'cap' ] diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 2e7330867e2ef..c7a97b33e1347 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -22,7 +22,6 @@ #include "srcline.h" #include "strlist.h" #include "strbuf.h" -#include #include "mem-events.h" #include "annotate.h" #include "event.h" @@ -32,6 +31,10 @@ #include #include +#ifdef HAVE_LIBTRACEEVENT +#include +#endif + regex_t parent_regex; const char default_parent_pattern[] = "^sys_|^do_page_fault"; const char *parent_pattern = default_parent_pattern; @@ -743,6 +746,7 @@ struct sort_entry sort_time = { /* --sort trace */ +#ifdef HAVE_LIBTRACEEVENT static char *get_trace_output(struct hist_entry *he) { struct trace_seq seq; @@ -806,6 +810,7 @@ struct sort_entry sort_trace = { .se_snprintf = hist_entry__trace_snprintf, .se_width_idx = HISTC_TRACE, }; +#endif /* HAVE_LIBTRACEEVENT */ /* sort keys for branch stacks */ @@ -2022,7 +2027,9 @@ static struct sort_dimension common_sort_dimensions[] = { DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), DIM(SORT_TRANSACTION, "transaction", sort_transaction), +#ifdef HAVE_LIBTRACEEVENT DIM(SORT_TRACE, "trace", sort_trace), +#endif DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size), DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size), DIM(SORT_CGROUP, "cgroup", sort_cgroup), @@ -2206,7 +2213,14 @@ bool perf_hpp__is_ ## key ## _entry(struct perf_hpp_fmt *fmt) \ return hse->se == &sort_ ## key ; \ } +#ifdef HAVE_LIBTRACEEVENT MK_SORT_ENTRY_CHK(trace) +#else +bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt __maybe_unused) +{ + return false; +} +#endif MK_SORT_ENTRY_CHK(srcline) MK_SORT_ENTRY_CHK(srcfile) MK_SORT_ENTRY_CHK(thread) @@ -2347,6 +2361,17 @@ static int __sort_dimension__add_hpp_output(struct sort_dimension *sd, return 0; } +#ifndef HAVE_LIBTRACEEVENT +bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *fmt __maybe_unused) +{ + return false; +} +bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt __maybe_unused, + struct hists *hists __maybe_unused) +{ + return false; +} +#else struct hpp_dynamic_entry { struct perf_hpp_fmt hpp; struct evsel *evsel; @@ -2621,6 +2646,7 @@ __alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field, return hde; } +#endif /* HAVE_LIBTRACEEVENT */ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt) { @@ -2633,6 +2659,7 @@ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt) new_hse = memdup(hse, sizeof(*hse)); if (new_hse) new_fmt = &new_hse->hpp; +#ifdef HAVE_LIBTRACEEVENT } else if (perf_hpp__is_dynamic_entry(fmt)) { struct hpp_dynamic_entry *hde, *new_hde; @@ -2640,6 +2667,7 @@ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt) new_hde = memdup(hde, sizeof(*hde)); if (new_hde) new_fmt = &new_hde->hpp; +#endif } else { new_fmt = memdup(fmt, sizeof(*fmt)); } @@ -2719,6 +2747,7 @@ static struct evsel *find_evsel(struct evlist *evlist, char *event_name) return evsel; } +#ifdef HAVE_LIBTRACEEVENT static int __dynamic_dimension__add(struct evsel *evsel, struct tep_format_field *field, bool raw_trace, int level) @@ -2789,13 +2818,13 @@ static int add_all_matching_fields(struct evlist *evlist, } return ret; } +#endif /* HAVE_LIBTRACEEVENT */ static int add_dynamic_entry(struct evlist *evlist, const char *tok, int level) { char *str, *event_name, *field_name, *opt_name; struct evsel *evsel; - struct tep_format_field *field; bool raw_trace = symbol_conf.raw_trace; int ret = 0; @@ -2820,6 +2849,7 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, raw_trace = true; } +#ifdef HAVE_LIBTRACEEVENT if (!strcmp(field_name, "trace_fields")) { ret = add_all_dynamic_fields(evlist, raw_trace, level); goto out; @@ -2829,6 +2859,7 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, ret = add_all_matching_fields(evlist, field_name, raw_trace, level); goto out; } +#endif evsel = find_evsel(evlist, event_name); if (evsel == NULL) { @@ -2843,10 +2874,12 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, goto out; } +#ifdef HAVE_LIBTRACEEVENT if (!strcmp(field_name, "*")) { ret = add_evsel_fields(evsel, raw_trace, level); } else { - field = tep_find_any_field(evsel->tp_format, field_name); + struct tep_format_field *field = tep_find_any_field(evsel->tp_format, field_name); + if (field == NULL) { pr_debug("Cannot find event field for %s.%s\n", event_name, field_name); @@ -2855,6 +2888,10 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, ret = __dynamic_dimension__add(evsel, field, raw_trace, level); } +#else + (void)level; + (void)raw_trace; +#endif /* HAVE_LIBTRACEEVENT */ out: free(str); @@ -2955,11 +2992,11 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { struct sort_dimension *sd = &common_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; for (j = 0; j < ARRAY_SIZE(dynamic_headers); j++) { - if (!strcmp(dynamic_headers[j], sd->name)) + if (sd->name && !strcmp(dynamic_headers[j], sd->name)) sort_dimension_add_dynamic_header(sd); } @@ -3009,7 +3046,7 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { struct sort_dimension *sd = &bstack_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; if (sort__mode != SORT_MODE__BRANCH) @@ -3025,7 +3062,7 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { struct sort_dimension *sd = &memory_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; if (sort__mode != SORT_MODE__MEMORY) @@ -3339,7 +3376,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok) for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { struct sort_dimension *sd = &common_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; return __sort_dimension__add_output(list, sd); @@ -3357,7 +3394,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok) for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { struct sort_dimension *sd = &bstack_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; if (sort__mode != SORT_MODE__BRANCH) @@ -3369,7 +3406,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok) for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { struct sort_dimension *sd = &memory_sort_dimensions[i]; - if (strncasecmp(tok, sd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; if (sort__mode != SORT_MODE__MEMORY) @@ -3508,6 +3545,9 @@ void reset_output_field(void) static void add_key(struct strbuf *sb, const char *str, int *llen) { + if (!str) + return; + if (*llen >= 75) { strbuf_addstr(sb, "\n\t\t\t "); *llen = INDENT; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 0645795ff0806..3ab6a92b1a6dc 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2157,6 +2157,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr * return err; } +#ifdef HAVE_LIBTRACEEVENT int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, perf_event__handler_t process) { @@ -2203,6 +2204,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct e return aligned_size; } +#endif int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, perf_event__handler_t process, struct machine *machine) @@ -2355,6 +2357,7 @@ int perf_event__synthesize_for_pipe(struct perf_tool *tool, } ret += err; +#ifdef HAVE_LIBTRACEEVENT if (have_tracepoints(&evlist->core.entries)) { int fd = perf_data__fd(data); @@ -2374,6 +2377,9 @@ int perf_event__synthesize_for_pipe(struct perf_tool *tool, } ret += err; } +#else + (void)data; +#endif return ret; } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index c9c83a40647c7..2d3c2576bab7f 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -11,6 +11,8 @@ #include "trace-event.h" #include +#include +#include static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 43146a4ce2fb2..1162c49b80825 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 636a010d929b9..56175c53f9af7 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "debug.h" #include "trace-event.h" diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index b3ee651e3d91c..8ad75b31e09b8 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 - #include #include #include diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 8f39f5bcb2c26..add6c5d9531cd 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -2,9 +2,11 @@ #ifndef _PERF_UTIL_TRACE_EVENT_H #define _PERF_UTIL_TRACE_EVENT_H -#include -#include "parse-events.h" +#include +#include +#include +struct evlist; struct machine; struct perf_sample; union perf_event; @@ -18,6 +20,11 @@ struct trace_event { struct tep_plugin_list *plugin_list; }; +typedef char *(tep_func_resolver_t)(void *priv, + unsigned long long *addrp, char **modp); + +bool have_tracepoints(struct list_head *evlist); + int trace_event__init(struct trace_event *t); void trace_event__cleanup(struct trace_event *t); int trace_event__register_resolver(struct machine *machine, -- GitLab From 4171925aa9f3f7bf57b100238f148b50c45c3b1b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 29 Nov 2022 22:29:35 -0800 Subject: [PATCH 1449/1480] tools lib traceevent: Remove libtraceevent libtraceevent is now out-of-date and it is better to depend on the system version. Remove this code that is no longer depended upon by any builds. Committer notes: Removed the removed tools/lib/traceevent/ from tools/perf/MANIFEST, so that 'make perf-tar-src-pkg' works. Signed-off-by: Ian Rogers Acked-by: Steven Rostedt (VMware) Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20221130062935.2219247-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/.gitignore | 4 - tools/lib/traceevent/Build | 8 - tools/lib/traceevent/Documentation/Makefile | 207 - .../traceevent/Documentation/asciidoc.conf | 120 - .../Documentation/libtraceevent-commands.txt | 153 - .../Documentation/libtraceevent-cpus.txt | 77 - .../libtraceevent-endian_read.txt | 78 - .../libtraceevent-event_find.txt | 103 - .../Documentation/libtraceevent-event_get.txt | 99 - .../libtraceevent-event_list.txt | 122 - .../libtraceevent-event_print.txt | 130 - .../libtraceevent-field_find.txt | 118 - .../libtraceevent-field_get_val.txt | 122 - .../libtraceevent-field_print.txt | 126 - .../libtraceevent-field_read.txt | 81 - .../Documentation/libtraceevent-fields.txt | 105 - .../libtraceevent-file_endian.txt | 91 - .../Documentation/libtraceevent-filter.txt | 209 - .../Documentation/libtraceevent-func_apis.txt | 183 - .../Documentation/libtraceevent-func_find.txt | 88 - .../Documentation/libtraceevent-handle.txt | 101 - .../libtraceevent-header_page.txt | 102 - .../libtraceevent-host_endian.txt | 104 - .../Documentation/libtraceevent-long_size.txt | 78 - .../Documentation/libtraceevent-page_size.txt | 82 - .../libtraceevent-parse_event.txt | 90 - .../libtraceevent-parse_head.txt | 82 - .../Documentation/libtraceevent-plugins.txt | 122 - .../libtraceevent-record_parse.txt | 137 - .../libtraceevent-reg_event_handler.txt | 156 - .../libtraceevent-reg_print_func.txt | 155 - .../Documentation/libtraceevent-set_flag.txt | 104 - .../Documentation/libtraceevent-strerror.txt | 85 - .../Documentation/libtraceevent-tseq.txt | 158 - .../Documentation/libtraceevent.txt | 192 - .../traceevent/Documentation/manpage-1.72.xsl | 14 - .../traceevent/Documentation/manpage-base.xsl | 35 - .../Documentation/manpage-bold-literal.xsl | 17 - .../Documentation/manpage-normal.xsl | 13 - .../Documentation/manpage-suppress-sp.xsl | 21 - tools/lib/traceevent/Makefile | 300 - tools/lib/traceevent/event-parse-api.c | 333 - tools/lib/traceevent/event-parse-local.h | 123 - tools/lib/traceevent/event-parse.c | 7624 ----------------- tools/lib/traceevent/event-parse.h | 750 -- tools/lib/traceevent/event-plugin.c | 711 -- tools/lib/traceevent/event-utils.h | 67 - tools/lib/traceevent/kbuffer-parse.c | 809 -- tools/lib/traceevent/kbuffer.h | 68 - .../lib/traceevent/libtraceevent.pc.template | 10 - tools/lib/traceevent/parse-filter.c | 2281 ----- tools/lib/traceevent/parse-utils.c | 71 - tools/lib/traceevent/plugins/Build | 12 - tools/lib/traceevent/plugins/Makefile | 225 - .../lib/traceevent/plugins/plugin_cfg80211.c | 43 - .../lib/traceevent/plugins/plugin_function.c | 282 - tools/lib/traceevent/plugins/plugin_futex.c | 123 - tools/lib/traceevent/plugins/plugin_hrtimer.c | 74 - tools/lib/traceevent/plugins/plugin_jbd2.c | 61 - tools/lib/traceevent/plugins/plugin_kmem.c | 80 - tools/lib/traceevent/plugins/plugin_kvm.c | 527 -- .../lib/traceevent/plugins/plugin_mac80211.c | 88 - .../traceevent/plugins/plugin_sched_switch.c | 146 - tools/lib/traceevent/plugins/plugin_scsi.c | 434 - tools/lib/traceevent/plugins/plugin_tlb.c | 66 - tools/lib/traceevent/plugins/plugin_xen.c | 138 - tools/lib/traceevent/tep_strerror.c | 53 - tools/lib/traceevent/trace-seq.c | 249 - tools/lib/traceevent/trace-seq.h | 55 - tools/perf/MANIFEST | 1 - 70 files changed, 19876 deletions(-) delete mode 100644 tools/lib/traceevent/.gitignore delete mode 100644 tools/lib/traceevent/Build delete mode 100644 tools/lib/traceevent/Documentation/Makefile delete mode 100644 tools/lib/traceevent/Documentation/asciidoc.conf delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-commands.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-cpus.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_find.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_get.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_list.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_print.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_find.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_print.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-field_read.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-fields.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-filter.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-func_find.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-handle.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-header_page.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-long_size.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-page_size.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-plugins.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-strerror.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent-tseq.txt delete mode 100644 tools/lib/traceevent/Documentation/libtraceevent.txt delete mode 100644 tools/lib/traceevent/Documentation/manpage-1.72.xsl delete mode 100644 tools/lib/traceevent/Documentation/manpage-base.xsl delete mode 100644 tools/lib/traceevent/Documentation/manpage-bold-literal.xsl delete mode 100644 tools/lib/traceevent/Documentation/manpage-normal.xsl delete mode 100644 tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl delete mode 100644 tools/lib/traceevent/Makefile delete mode 100644 tools/lib/traceevent/event-parse-api.c delete mode 100644 tools/lib/traceevent/event-parse-local.h delete mode 100644 tools/lib/traceevent/event-parse.c delete mode 100644 tools/lib/traceevent/event-parse.h delete mode 100644 tools/lib/traceevent/event-plugin.c delete mode 100644 tools/lib/traceevent/event-utils.h delete mode 100644 tools/lib/traceevent/kbuffer-parse.c delete mode 100644 tools/lib/traceevent/kbuffer.h delete mode 100644 tools/lib/traceevent/libtraceevent.pc.template delete mode 100644 tools/lib/traceevent/parse-filter.c delete mode 100644 tools/lib/traceevent/parse-utils.c delete mode 100644 tools/lib/traceevent/plugins/Build delete mode 100644 tools/lib/traceevent/plugins/Makefile delete mode 100644 tools/lib/traceevent/plugins/plugin_cfg80211.c delete mode 100644 tools/lib/traceevent/plugins/plugin_function.c delete mode 100644 tools/lib/traceevent/plugins/plugin_futex.c delete mode 100644 tools/lib/traceevent/plugins/plugin_hrtimer.c delete mode 100644 tools/lib/traceevent/plugins/plugin_jbd2.c delete mode 100644 tools/lib/traceevent/plugins/plugin_kmem.c delete mode 100644 tools/lib/traceevent/plugins/plugin_kvm.c delete mode 100644 tools/lib/traceevent/plugins/plugin_mac80211.c delete mode 100644 tools/lib/traceevent/plugins/plugin_sched_switch.c delete mode 100644 tools/lib/traceevent/plugins/plugin_scsi.c delete mode 100644 tools/lib/traceevent/plugins/plugin_tlb.c delete mode 100644 tools/lib/traceevent/plugins/plugin_xen.c delete mode 100644 tools/lib/traceevent/tep_strerror.c delete mode 100644 tools/lib/traceevent/trace-seq.c delete mode 100644 tools/lib/traceevent/trace-seq.h diff --git a/tools/lib/traceevent/.gitignore b/tools/lib/traceevent/.gitignore deleted file mode 100644 index 7123c70b9ebc8..0000000000000 --- a/tools/lib/traceevent/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -TRACEEVENT-CFLAGS -libtraceevent-dynamic-list -libtraceevent.so.* diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build deleted file mode 100644 index f9a5d79578f51..0000000000000 --- a/tools/lib/traceevent/Build +++ /dev/null @@ -1,8 +0,0 @@ -libtraceevent-y += event-parse.o -libtraceevent-y += event-plugin.o -libtraceevent-y += trace-seq.o -libtraceevent-y += parse-filter.o -libtraceevent-y += parse-utils.o -libtraceevent-y += kbuffer-parse.o -libtraceevent-y += tep_strerror.o -libtraceevent-y += event-parse-api.o diff --git a/tools/lib/traceevent/Documentation/Makefile b/tools/lib/traceevent/Documentation/Makefile deleted file mode 100644 index aa72ab96c3c1d..0000000000000 --- a/tools/lib/traceevent/Documentation/Makefile +++ /dev/null @@ -1,207 +0,0 @@ -include ../../../scripts/Makefile.include -include ../../../scripts/utilities.mak - -# This Makefile and manpage XSL files were taken from tools/perf/Documentation -# and modified for libtraceevent. - -MAN3_TXT= \ - $(wildcard libtraceevent-*.txt) \ - libtraceevent.txt - -MAN_TXT = $(MAN3_TXT) -_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) -_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) -_DOC_MAN3=$(patsubst %.txt,%.3,$(MAN3_TXT)) - -MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML)) -MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML)) -DOC_MAN3=$(addprefix $(OUTPUT),$(_DOC_MAN3)) - -# Make the path relative to DESTDIR, not prefix -ifndef DESTDIR -prefix?=$(HOME) -endif -bindir?=$(prefix)/bin -htmldir?=$(prefix)/share/doc/libtraceevent-doc -pdfdir?=$(prefix)/share/doc/libtraceevent-doc -mandir?=$(prefix)/share/man -man3dir=$(mandir)/man3 - -ASCIIDOC=asciidoc -ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf -ASCIIDOC_HTML = xhtml11 -MANPAGE_XSL = manpage-normal.xsl -XMLTO_EXTRA = -INSTALL?=install -RM ?= rm -f - -ifdef USE_ASCIIDOCTOR -ASCIIDOC = asciidoctor -ASCIIDOC_EXTRA = -a compat-mode -ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions -ASCIIDOC_EXTRA += -a mansource="libtraceevent" -a manmanual="libtraceevent Manual" -ASCIIDOC_HTML = xhtml5 -endif - -XMLTO=xmlto - -_tmp_tool_path := $(call get-executable,$(ASCIIDOC)) -ifeq ($(_tmp_tool_path),) - missing_tools = $(ASCIIDOC) -endif - -ifndef USE_ASCIIDOCTOR -_tmp_tool_path := $(call get-executable,$(XMLTO)) -ifeq ($(_tmp_tool_path),) - missing_tools += $(XMLTO) -endif -endif - -# -# For asciidoc ... -# -7.1.2, no extra settings are needed. -# 8.0-, set ASCIIDOC8. -# - -# -# For docbook-xsl ... -# -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0) -# 1.69.0, no extra settings are needed? -# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP? -# 1.71.1, no extra settings are needed? -# 1.72.0, set DOCBOOK_XSL_172. -# 1.73.0-, set ASCIIDOC_NO_ROFF -# - -# -# If you had been using DOCBOOK_XSL_172 in an attempt to get rid -# of 'the ".ft C" problem' in your generated manpages, and you -# instead ended up with weird characters around callouts, try -# using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8). -# - -ifdef ASCIIDOC8 -ASCIIDOC_EXTRA += -a asciidoc7compatible -endif -ifdef DOCBOOK_XSL_172 -ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff -MANPAGE_XSL = manpage-1.72.xsl -else - ifdef ASCIIDOC_NO_ROFF - # docbook-xsl after 1.72 needs the regular XSL, but will not - # pass-thru raw roff codes from asciidoc.conf, so turn them off. - ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff - endif -endif -ifdef MAN_BOLD_LITERAL -XMLTO_EXTRA += -m manpage-bold-literal.xsl -endif -ifdef DOCBOOK_SUPPRESS_SP -XMLTO_EXTRA += -m manpage-suppress-sp.xsl -endif - -SHELL_PATH ?= $(SHELL) -# Shell quote; -SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) - -DESTDIR ?= -DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' - -export DESTDIR DESTDIR_SQ - -# -# Please note that there is a minor bug in asciidoc. -# The version after 6.0.3 _will_ include the patch found here: -# http://marc.theaimsgroup.com/?l=libtraceevent&m=111558757202243&w=2 -# -# Until that version is released you may have to apply the patch -# yourself - yes, all 6 characters of it! -# -QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir -QUIET_SUBDIR1 = - -ifneq ($(findstring $(MAKEFLAGS),w),w) -PRINT_DIR = --no-print-directory -else # "make -w" -NO_SUBDIR = : -endif - -ifneq ($(findstring $(MAKEFLAGS),s),s) -ifneq ($(V),1) - QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@; - QUIET_XMLTO = @echo ' XMLTO '$@; - QUIET_SUBDIR0 = +@subdir= - QUIET_SUBDIR1 = ;$(NO_SUBDIR) \ - echo ' SUBDIR ' $$subdir; \ - $(MAKE) $(PRINT_DIR) -C $$subdir - export V -endif -endif - -all: html man - -man: man3 -man3: $(DOC_MAN3) - -html: $(MAN_HTML) - -$(MAN_HTML) $(DOC_MAN3): asciidoc.conf - -install: install-man - -check-man-tools: -ifdef missing_tools - $(error "You need to install $(missing_tools) for man pages") -endif - -do-install-man: man - $(call QUIET_INSTALL, Documentation-man) \ - $(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \ - $(INSTALL) -m 644 $(DOC_MAN3) $(DESTDIR)$(man3dir); - -install-man: check-man-tools man do-install-man - -uninstall: uninstall-man - -uninstall-man: - $(call QUIET_UNINST, Documentation-man) \ - $(Q)$(RM) $(addprefix $(DESTDIR)$(man3dir)/,$(DOC_MAN3)) - - -ifdef missing_tools - DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed) -else - DO_INSTALL_MAN = do-install-man -endif - -CLEAN_FILES = \ - $(MAN_XML) $(addsuffix +,$(MAN_XML)) \ - $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ - $(DOC_MAN3) *.3 - -clean: - $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) - -ifdef USE_ASCIIDOCTOR -$(OUTPUT)%.3 : $(OUTPUT)%.txt - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(ASCIIDOC) -b manpage -d manpage \ - $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ - mv $@+ $@ -endif - -$(OUTPUT)%.3 : $(OUTPUT)%.xml - $(QUIET_XMLTO)$(RM) $@ && \ - $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< - -$(OUTPUT)%.xml : %.txt - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(ASCIIDOC) -b docbook -d manpage \ - $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ - mv $@+ $@ - -$(MAN_HTML): $(OUTPUT)%.html : %.txt - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \ - $(ASCIIDOC_EXTRA) -aperf_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ - mv $@+ $@ diff --git a/tools/lib/traceevent/Documentation/asciidoc.conf b/tools/lib/traceevent/Documentation/asciidoc.conf deleted file mode 100644 index 07595717f06e3..0000000000000 --- a/tools/lib/traceevent/Documentation/asciidoc.conf +++ /dev/null @@ -1,120 +0,0 @@ -## linktep: macro -# -# Usage: linktep:command[manpage-section] -# -# Note, {0} is the manpage section, while {target} is the command. -# -# Show TEP link as: (
); if section is defined, else just show -# the command. - -[macros] -(?su)[\\]?(?Plinktep):(?P\S*?)\[(?P.*?)\]= - -[attributes] -asterisk=* -plus=+ -caret=^ -startsb=[ -endsb=] -tilde=~ - -ifdef::backend-docbook[] -[linktep-inlinemacro] -{0%{target}} -{0#} -{0#{target}{0}} -{0#} -endif::backend-docbook[] - -ifdef::backend-docbook[] -ifndef::tep-asciidoc-no-roff[] -# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. -# v1.72 breaks with this because it replaces dots not in roff requests. -[listingblock] -{title} - -ifdef::doctype-manpage[] - .ft C -endif::doctype-manpage[] -| -ifdef::doctype-manpage[] - .ft -endif::doctype-manpage[] - -{title#} -endif::tep-asciidoc-no-roff[] - -ifdef::tep-asciidoc-no-roff[] -ifdef::doctype-manpage[] -# The following two small workarounds insert a simple paragraph after screen -[listingblock] -{title} - -| - -{title#} - -[verseblock] -{title} -{title%} -{title#} -| - -{title#} -{title%} -endif::doctype-manpage[] -endif::tep-asciidoc-no-roff[] -endif::backend-docbook[] - -ifdef::doctype-manpage[] -ifdef::backend-docbook[] -[header] -template::[header-declarations] - - -{mantitle} -{manvolnum} -libtraceevent -{libtraceevent_version} -libtraceevent Manual - - - {manname1} - {manname2} - {manname3} - {manname4} - {manname5} - {manname6} - {manname7} - {manname8} - {manname9} - {manname10} - {manname11} - {manname12} - {manname13} - {manname14} - {manname15} - {manname16} - {manname17} - {manname18} - {manname19} - {manname20} - {manname21} - {manname22} - {manname23} - {manname24} - {manname25} - {manname26} - {manname27} - {manname28} - {manname29} - {manname30} - {manpurpose} - -endif::backend-docbook[] -endif::doctype-manpage[] - -ifdef::backend-xhtml11[] -[linktep-inlinemacro] -{target}{0?({0})} -endif::backend-xhtml11[] diff --git a/tools/lib/traceevent/Documentation/libtraceevent-commands.txt b/tools/lib/traceevent/Documentation/libtraceevent-commands.txt deleted file mode 100644 index bec552001f8e3..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-commands.txt +++ /dev/null @@ -1,153 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_register_comm, tep_override_comm, tep_pid_is_registered, -tep_data_comm_from_pid, tep_data_pid_from_comm, tep_cmdline_pid - -Manage pid to process name mappings. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); -int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); -bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); -const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_pevent_, int _pid_); -struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_pevent_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); -int *tep_cmdline_pid*(struct tep_handle pass:[*]_pevent_, struct cmdline pass:[*]_cmdline_); --- - -DESCRIPTION ------------ -These functions can be used to handle the mapping between pid and process name. -The library builds a cache of these mappings, which is used to display the name -of the process, instead of its pid. This information can be retrieved from -tracefs/saved_cmdlines file. - -The _tep_register_comm()_ function registers a _pid_ / process name mapping. -If a command with the same _pid_ is already registered, an error is returned. -The _pid_ argument is the process ID, the _comm_ argument is the process name, -_tep_ is the event context. The _comm_ is duplicated internally. - -The _tep_override_comm()_ function registers a _pid_ / process name mapping. -If a process with the same pid is already registered, the process name string is -udapted with the new one. The _pid_ argument is the process ID, the _comm_ -argument is the process name, _tep_ is the event context. The _comm_ is -duplicated internally. - -The _tep_is_pid_registered()_ function checks if a pid has a process name -mapping registered. The _pid_ argument is the process ID, _tep_ is the event -context. - -The _tep_data_comm_from_pid()_ function returns the process name for a given -pid. The _pid_ argument is the process ID, _tep_ is the event context. -The returned string should not be freed, but will be freed when the _tep_ -handler is closed. - -The _tep_data_pid_from_comm()_ function returns a pid for a given process name. -The _comm_ argument is the process name, _tep_ is the event context. -The argument _next_ is the cmdline structure to search for the next pid. -As there may be more than one pid for a given process, the result of this call -can be passed back into a recurring call in the _next_ parameter, to search for -the next pid. If _next_ is NULL, it will return the first pid associated with -the _comm_. The function performs a linear search, so it may be slow. - -The _tep_cmdline_pid()_ function returns the pid associated with a given -_cmdline_. The _tep_ argument is the event context. - -RETURN VALUE ------------- -_tep_register_comm()_ function returns 0 on success. In case of an error -1 is -returned and errno is set to indicate the cause of the problem: ENOMEM, if there -is not enough memory to duplicate the _comm_ or EEXIST if a mapping for this -_pid_ is already registered. - -_tep_override_comm()_ function returns 0 on success. In case of an error -1 is -returned and errno is set to indicate the cause of the problem: ENOMEM, if there -is not enough memory to duplicate the _comm_. - -_tep_is_pid_registered()_ function returns true if the _pid_ has a process name -mapped to it, false otherwise. - -_tep_data_comm_from_pid()_ function returns the process name as string, or the -string "<...>" if there is no mapping for the given pid. - -_tep_data_pid_from_comm()_ function returns a pointer to a struct cmdline, that -holds a pid for a given process, or NULL if none is found. This result can be -passed back into a recurring call as the _next_ parameter of the function. - -_tep_cmdline_pid()_ functions returns the pid for the give cmdline. If _cmdline_ - is NULL, then -1 is returned. - -EXAMPLE -------- -The following example registers pid for command "ls", in context of event _tep_ -and performs various searches for pid / process name mappings: -[source,c] --- -#include -... -int ret; -int ls_pid = 1021; -struct tep_handle *tep = tep_alloc(); -... - ret = tep_register_comm(tep, "ls", ls_pid); - if (ret != 0 && errno == EEXIST) - ret = tep_override_comm(tep, "ls", ls_pid); - if (ret != 0) { - /* Failed to register pid / command mapping */ - } -... - if (tep_is_pid_registered(tep, ls_pid) == 0) { - /* Command mapping for ls_pid is not registered */ - } -... - const char *comm = tep_data_comm_from_pid(tep, ls_pid); - if (comm) { - /* Found process name for ls_pid */ - } -... - int pid; - struct cmdline *cmd = tep_data_pid_from_comm(tep, "ls", NULL); - while (cmd) { - pid = tep_cmdline_pid(tep, cmd); - /* Found pid for process "ls" */ - cmd = tep_data_pid_from_comm(tep, "ls", cmd); - } --- -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt b/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt deleted file mode 100644 index 5ad70e43b7529..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-cpus.txt +++ /dev/null @@ -1,77 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_cpus, tep_set_cpus - Get / set the number of CPUs, which have a tracing -buffer representing it. Note, the buffer may be empty. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); -void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); --- - -DESCRIPTION ------------ -The _tep_get_cpus()_ function gets the number of CPUs, which have a tracing -buffer representing it. The _tep_ argument is trace event parser context. - -The _tep_set_cpus()_ function sets the number of CPUs, which have a tracing -buffer representing it. The _tep_ argument is trace event parser context. -The _cpu_ argument is the number of CPUs with tracing data. - -RETURN VALUE ------------- -The _tep_get_cpus()_ functions returns the number of CPUs, which have tracing -data recorded. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... - tep_set_cpus(tep, 5); -... - printf("We have tracing data for %d CPUs", tep_get_cpus(tep)); --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt deleted file mode 100644 index e64851b6e189e..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-endian_read.txt +++ /dev/null @@ -1,78 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_read_number - Reads a number from raw data. - -SYNOPSIS --------- -[verse] --- -*#include * - -unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); --- - -DESCRIPTION ------------ -The _tep_read_number()_ function reads an integer from raw data, taking into -account the endianness of the raw data and the current host. The _tep_ argument -is the trace event parser context. The _ptr_ is a pointer to the raw data, where -the integer is, and the _size_ is the size of the integer. - -RETURN VALUE ------------- -The _tep_read_number()_ function returns the integer in the byte order of -the current host. In case of an error, 0 is returned. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -void process_record(struct tep_record *record) -{ - int offset = 24; - int data = tep_read_number(tep, record->data + offset, 4); - - /* Read the 4 bytes at the offset 24 of data as an integer */ -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt deleted file mode 100644 index 7bc062c9f76f5..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-event_find.txt +++ /dev/null @@ -1,103 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_find_event,tep_find_event_by_name,tep_find_event_by_record - -Find events by given key. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); -struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); -struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); --- - -DESCRIPTION ------------ -This set of functions can be used to search for an event, based on a given -criteria. All functions require a pointer to a _tep_, trace event parser -context. - -The _tep_find_event()_ function searches for an event by given event _id_. The -event ID is assigned dynamically and can be viewed in event's format file, -"ID" field. - -The tep_find_event_by_name()_ function searches for an event by given -event _name_, under the system _sys_. If the _sys_ is NULL (not specified), -the first event with _name_ is returned. - -The tep_find_event_by_record()_ function searches for an event from a given -_record_. - -RETURN VALUE ------------- -All these functions return a pointer to the found event, or NULL if there is no -such event. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -struct tep_event *event; - -event = tep_find_event(tep, 1857); -if (event == NULL) { - /* There is no event with ID 1857 */ -} - -event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); -if (event == NULL) { - /* There is no kvm_exit event, from kvm system */ -} - -void event_from_record(struct tep_record *record) -{ - struct tep_event *event = tep_find_event_by_record(tep, record); - if (event == NULL) { - /* There is no event from given record */ - } -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt deleted file mode 100644 index 6525092fc417a..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-event_get.txt +++ /dev/null @@ -1,99 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_event, tep_get_first_event, tep_get_events_count - Access events. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); -struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); -int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); --- - -DESCRIPTION ------------ -The _tep_get_event()_ function returns a pointer to event at the given _index_. -The _tep_ argument is trace event parser context, the _index_ is the index of -the requested event. - -The _tep_get_first_event()_ function returns a pointer to the first event. -As events are stored in an array, this function returns the pointer to the -beginning of the array. The _tep_ argument is trace event parser context. - -The _tep_get_events_count()_ function returns the number of the events -in the array. The _tep_ argument is trace event parser context. - -RETURN VALUE ------------- -The _tep_get_event()_ returns a pointer to the event located at _index_. -NULL is returned in case of error, in case there are no events or _index_ is -out of range. - -The _tep_get_first_event()_ returns a pointer to the first event. NULL is -returned in case of error, or in case there are no events. - -The _tep_get_events_count()_ returns the number of the events. 0 is -returned in case of error, or in case there are no events. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -int i,count = tep_get_events_count(tep); -struct tep_event *event, *events = tep_get_first_event(tep); - -if (events == NULL) { - /* There are no events */ -} else { - for (i = 0; i < count; i++) { - event = (events+i); - /* process events[i] */ - } - - /* Get the last event */ - event = tep_get_event(tep, count-1); -} --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt deleted file mode 100644 index fba350e5a4cb9..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-event_list.txt +++ /dev/null @@ -1,122 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_list_events, tep_list_events_copy - -Get list of events, sorted by given criteria. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_event_sort_type* { - _TEP_EVENT_SORT_ID_, - _TEP_EVENT_SORT_NAME_, - _TEP_EVENT_SORT_SYSTEM_, -}; - -struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); -struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); --- - -DESCRIPTION ------------ -The _tep_list_events()_ function returns an array of pointers to the events, -sorted by the _sort_type_ criteria. The last element of the array is NULL. -The returned memory must not be freed, it is managed by the library. -The function is not thread safe. The _tep_ argument is trace event parser -context. The _sort_type_ argument is the required sort criteria: -[verse] --- - _TEP_EVENT_SORT_ID_ - sort by the event ID. - _TEP_EVENT_SORT_NAME_ - sort by the event (name, system, id) triplet. - _TEP_EVENT_SORT_SYSTEM_ - sort by the event (system, name, id) triplet. --- - -The _tep_list_events_copy()_ is a thread safe version of _tep_list_events()_. -It has the same behavior, but the returned array is allocated internally and -must be freed by the caller. Note that the content of the array must not be -freed (see the EXAMPLE below). - -RETURN VALUE ------------- -The _tep_list_events()_ function returns an array of pointers to events. -In case of an error, NULL is returned. The returned array must not be freed, -it is managed by the library. - -The _tep_list_events_copy()_ function returns an array of pointers to events. -In case of an error, NULL is returned. The returned array must be freed by -the caller. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -int i; -struct tep_event_format **events; - -i=0; -events = tep_list_events(tep, TEP_EVENT_SORT_ID); -if (events == NULL) { - /* Failed to get the events, sorted by ID */ -} else { - while(events[i]) { - /* walk through the list of the events, sorted by ID */ - i++; - } -} - -i=0; -events = tep_list_events_copy(tep, TEP_EVENT_SORT_NAME); -if (events == NULL) { - /* Failed to get the events, sorted by name */ -} else { - while(events[i]) { - /* walk through the list of the events, sorted by name */ - i++; - } - free(events); -} - -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt deleted file mode 100644 index 2c6a61811118f..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt +++ /dev/null @@ -1,130 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_print_event - Writes event information into a trace sequence. - -SYNOPSIS --------- -[verse] --- -*#include * -*#include * - -void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seqpass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._) --- - -DESCRIPTION ------------ - -The _tep_print_event()_ function parses the event information of the given -_record_ and writes it into the trace sequence _s_, according to the format -string _fmt_. The desired information is specified after the format string. -The _fmt_ is printf-like format string, following arguments are supported: -[verse] --- - TEP_PRINT_PID, "%d" - PID of the event. - TEP_PRINT_CPU, "%d" - Event CPU. - TEP_PRINT_COMM, "%s" - Event command string. - TEP_PRINT_NAME, "%s" - Event name. - TEP_PRINT_LATENCY, "%s" - Latency of the event. It prints 4 or more - fields - interrupt state, scheduling state, - current context, and preemption count. - Field 1 is the interrupt enabled state: - d : Interrupts are disabled - . : Interrupts are enabled - X : The architecture does not support this - information - Field 2 is the "need resched" state. - N : The task is set to call the scheduler when - possible, as another higher priority task - may need to be scheduled in. - . : The task is not set to call the scheduler. - Field 3 is the context state. - . : Normal context - s : Soft interrupt context - h : Hard interrupt context - H : Hard interrupt context which triggered - during soft interrupt context. - z : NMI context - Z : NMI context which triggered during hard - interrupt context - Field 4 is the preemption count. - . : The preempt count is zero. - On preemptible kernels (where the task can be scheduled - out in arbitrary locations while in kernel context), the - preempt count, when non zero, will prevent the kernel - from scheduling out the current task. The preempt count - number is displayed when it is not zero. - Depending on the kernel, it may show other fields - (lock depth, or migration disabled, which are unique to - specialized kernels). - TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be - specified as part of this format string: - "%precision.divisord". Example: - "%3.1000d" - divide the time by 1000 and print the first - 3 digits before the dot. Thus, the time stamp - "123456000" will be printed as "123.456" - TEP_PRINT_INFO, "%s" - event information. - TEP_PRINT_INFO_RAW, "%s" - event information, in raw format. - --- -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct trace_seq seq; -trace_seq_init(&seq); -struct tep_handle *tep = tep_alloc(); -... -void print_my_event(struct tep_record *record) -{ - trace_seq_reset(&seq); - tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s", - TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, - TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, - TEP_PRINT_INFO); -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences related APIs. - Trace sequences are used to allow a function to call several other functions - to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt deleted file mode 100644 index 0896af5b9eff5..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-field_find.txt +++ /dev/null @@ -1,118 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_find_common_field, tep_find_field, tep_find_any_field - -Search for a field in an event. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); -struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); -struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); --- - -DESCRIPTION ------------ -These functions search for a field with given name in an event. The field -returned can be used to find the field content from within a data record. - -The _tep_find_common_field()_ function searches for a common field with _name_ -in the _event_. - -The _tep_find_field()_ function searches for an event specific field with -_name_ in the _event_. - -The _tep_find_any_field()_ function searches for any field with _name_ in the -_event_. - -RETURN VALUE ------------- -The _tep_find_common_field(), _tep_find_field()_ and _tep_find_any_field()_ -functions return a pointer to the found field, or NULL in case there is no field -with the requested name. - -EXAMPLE -------- -[source,c] --- -#include -... -void get_htimer_info(struct tep_handle *tep, struct tep_record *record) -{ - struct tep_format_field *field; - struct tep_event *event; - long long softexpires; - int mode; - int pid; - - event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); - - field = tep_find_common_field(event, "common_pid"); - if (field == NULL) { - /* Cannot find "common_pid" field in the event */ - } else { - /* Get pid from the data record */ - pid = tep_read_number(tep, record->data + field->offset, - field->size); - } - - field = tep_find_field(event, "softexpires"); - if (field == NULL) { - /* Cannot find "softexpires" event specific field in the event */ - } else { - /* Get softexpires parameter from the data record */ - softexpires = tep_read_number(tep, record->data + field->offset, - field->size); - } - - field = tep_find_any_field(event, "mode"); - if (field == NULL) { - /* Cannot find "mode" field in the event */ - } else - { - /* Get mode parameter from the data record */ - mode = tep_read_number(tep, record->data + field->offset, - field->size); - } -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt deleted file mode 100644 index 6324f0d48aebe..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-field_get_val.txt +++ /dev/null @@ -1,122 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_any_field_val, tep_get_common_field_val, tep_get_field_val, -tep_get_field_raw - Get value of a field. - -SYNOPSIS --------- -[verse] --- -*#include * -*#include * - -int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); -int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); -int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); -void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); --- - -DESCRIPTION ------------ -These functions can be used to find a field and retrieve its value. - -The _tep_get_any_field_val()_ function searches in the _record_ for a field -with _name_, part of the _event_. If the field is found, its value is stored in -_val_. If there is an error and _err_ is not zero, then an error string is -written into _s_. - -The _tep_get_common_field_val()_ function does the same as -_tep_get_any_field_val()_, but searches only in the common fields. This works -for any event as all events include the common fields. - -The _tep_get_field_val()_ function does the same as _tep_get_any_field_val()_, -but searches only in the event specific fields. - -The _tep_get_field_raw()_ function searches in the _record_ for a field with -_name_, part of the _event_. If the field is found, a pointer to where the field -exists in the record's raw data is returned. The size of the data is stored in -_len_. If there is an error and _err_ is not zero, then an error string is -written into _s_. - -RETURN VALUE ------------- -The _tep_get_any_field_val()_, _tep_get_common_field_val()_ and -_tep_get_field_val()_ functions return 0 on success, or -1 in case of an error. - -The _tep_get_field_raw()_ function returns a pointer to field's raw data, and -places the length of this data in _len_. In case of an error NULL is returned. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep = tep_alloc(); -... -struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); -... -void process_record(struct tep_record *record) -{ - int len; - char *comm; - struct tep_event_format *event; - unsigned long long val; - - event = tep_find_event_by_record(pevent, record); - if (event != NULL) { - if (tep_get_common_field_val(NULL, event, "common_type", - record, &val, 0) == 0) { - /* Got the value of common type field */ - } - if (tep_get_field_val(NULL, event, "pid", record, &val, 0) == 0) { - /* Got the value of pid specific field */ - } - comm = tep_get_field_raw(NULL, event, "comm", record, &len, 0); - if (comm != NULL) { - /* Got a pointer to the comm event specific field */ - } - } -} --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences - related APIs. Trace sequences are used to allow a function to call - several other functions to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt deleted file mode 100644 index 9a9df98ac44d4..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-field_print.txt +++ /dev/null @@ -1,126 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_print_field, tep_print_fields, tep_print_num_field, tep_print_func_field - -Print the field content. - -SYNOPSIS --------- -[verse] --- -*#include * -*#include * - -void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_); -void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_); -int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); -int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); --- - -DESCRIPTION ------------ -These functions print recorded field's data, according to the field's type. - -The _tep_print_field()_ function extracts from the recorded raw _data_ value of -the _field_ and prints it into _s_, according to the field type. - -The _tep_print_fields()_ prints each field name followed by the record's field -value according to the field's type: -[verse] --- -"field1_name=field1_value field2_name=field2_value ..." --- -It iterates all fields of the _event_, and calls _tep_print_field()_ for each of -them. - -The _tep_print_num_field()_ function prints a numeric field with given format -string. A search is performed in the _event_ for a field with _name_. If such -field is found, its value is extracted from the _record_ and is printed in the -_s_, according to the given format string _fmt_. If the argument _err_ is -non-zero, and an error occures - it is printed in the _s_. - -The _tep_print_func_field()_ function prints a function field with given format -string. A search is performed in the _event_ for a field with _name_. If such -field is found, its value is extracted from the _record_. The value is assumed -to be a function address, and a search is perform to find the name of this -function. The function name (if found) and its address are printed in the _s_, -according to the given format string _fmt_. If the argument _err_ is non-zero, -and an error occures - it is printed in _s_. - -RETURN VALUE ------------- -The _tep_print_num_field()_ and _tep_print_func_field()_ functions return 1 -on success, -1 in case of an error or 0 if the print buffer _s_ is full. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep = tep_alloc(); -... -struct trace_seq seq; -trace_seq_init(&seq); -struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); -... -void process_record(struct tep_record *record) -{ - struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); - - trace_seq_reset(&seq); - - /* Print the value of "common_pid" */ - tep_print_field(&seq, record->data, field_pid); - - /* Print all fields of the "hrtimer_start" event */ - tep_print_fields(&seq, record->data, record->size, event); - - /* Print the value of "expires" field with custom format string */ - tep_print_num_field(&seq, " timer expires in %llu ", event, "expires", record, 0); - - /* Print the address and the name of "function" field with custom format string */ - tep_print_func_field(&seq, " timer function is %s ", event, "function", record, 0); - } - ... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences related APIs. - Trace sequences are used to allow a function to call several other functions - to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt b/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt deleted file mode 100644 index 64e9e25d3fd9a..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-field_read.txt +++ /dev/null @@ -1,81 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_read_number_field - Reads a number from raw data. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_); --- - -DESCRIPTION ------------ -The _tep_read_number_field()_ function reads the value of the _field_ from the -raw _data_ and stores it in the _value_. The function sets the _value_ according -to the endianness of the raw data and the current machine and stores it in -_value_. - -RETURN VALUE ------------- -The _tep_read_number_field()_ function retunrs 0 in case of success, or -1 in -case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); -... -void process_record(struct tep_record *record) -{ - unsigned long long pid; - struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); - - if (tep_read_number_field(field_pid, record->data, &pid) != 0) { - /* Failed to get "common_pid" value */ - } -} -... --- -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-fields.txt b/tools/lib/traceevent/Documentation/libtraceevent-fields.txt deleted file mode 100644 index 1ccb531d5114f..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-fields.txt +++ /dev/null @@ -1,105 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_event_common_fields, tep_event_fields - Get a list of fields for an event. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); -struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); --- - -DESCRIPTION ------------ -The _tep_event_common_fields()_ function returns an array of pointers to common -fields for the _event_. The array is allocated in the function and must be freed -by free(). The last element of the array is NULL. - -The _tep_event_fields()_ function returns an array of pointers to event specific -fields for the _event_. The array is allocated in the function and must be freed -by free(). The last element of the array is NULL. - -RETURN VALUE ------------- -Both _tep_event_common_fields()_ and _tep_event_fields()_ functions return -an array of pointers to tep_format_field structures in case of success, or -NULL in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -int i; -struct tep_format_field **fields; -struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); -if (event != NULL) { - fields = tep_event_common_fields(event); - if (fields != NULL) { - i = 0; - while (fields[i]) { - /* - walk through the list of the common fields - of the kvm_exit event - */ - i++; - } - free(fields); - } - fields = tep_event_fields(event); - if (fields != NULL) { - i = 0; - while (fields[i]) { - /* - walk through the list of the event specific - fields of the kvm_exit event - */ - i++; - } - free(fields); - } -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt deleted file mode 100644 index f401ad311047b..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-file_endian.txt +++ /dev/null @@ -1,91 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_is_file_bigendian, tep_set_file_bigendian - Get / set the endianness of the -raw data being accessed by the tep handler. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_endian* { - TEP_LITTLE_ENDIAN = 0, - TEP_BIG_ENDIAN -}; - -bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); -void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); - --- -DESCRIPTION ------------ -The _tep_is_file_bigendian()_ function gets the endianness of the raw data, -being accessed by the tep handler. The _tep_ argument is trace event parser -context. - -The _tep_set_file_bigendian()_ function sets the endianness of raw data being -accessed by the tep handler. The _tep_ argument is trace event parser context. -[verse] --- -The _endian_ argument is the endianness: - _TEP_LITTLE_ENDIAN_ - the raw data is in little endian format, - _TEP_BIG_ENDIAN_ - the raw data is in big endian format. --- -RETURN VALUE ------------- -The _tep_is_file_bigendian()_ function returns true if the data is in bigendian -format, false otherwise. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... - tep_set_file_bigendian(tep, TEP_LITTLE_ENDIAN); -... - if (tep_is_file_bigendian(tep)) { - /* The raw data is in big endian */ - } else { - /* The raw data is in little endian */ - } --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-filter.txt b/tools/lib/traceevent/Documentation/libtraceevent-filter.txt deleted file mode 100644 index 4a9962d8cb594..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-filter.txt +++ /dev/null @@ -1,209 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_filter_alloc, tep_filter_free, tep_filter_reset, tep_filter_make_string, -tep_filter_copy, tep_filter_compare, tep_filter_match, tep_event_filtered, -tep_filter_remove_event, tep_filter_strerror, tep_filter_add_filter_str - -Event filter related APIs. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); -void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); -void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); -enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); -int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); -int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); -enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); -int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); -int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); -char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); -int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); --- - -DESCRIPTION ------------ -Filters can be attached to traced events. They can be used to filter out various -events when outputting them. Each event can be filtered based on its parameters, -described in the event's format file. This set of functions can be used to -create, delete, modify and attach event filters. - -The _tep_filter_alloc()_ function creates a new event filter. The _tep_ argument -is the trace event parser context. - -The _tep_filter_free()_ function frees an event filter and all resources that it -had used. - -The _tep_filter_reset()_ function removes all rules from an event filter and -resets it. - -The _tep_filter_add_filter_str()_ function adds a new rule to the _filter_. The -_filter_str_ argument is the filter string, that contains the rule. - -The _tep_event_filtered()_ function checks if the event with _event_id_ has -_filter_. - -The _tep_filter_remove_event()_ function removes a _filter_ for an event with -_event_id_. - -The _tep_filter_match()_ function tests if a _record_ matches given _filter_. - -The _tep_filter_copy()_ function copies a _source_ filter into a _dest_ filter. - -The _tep_filter_compare()_ function compares two filers - _filter1_ and _filter2_. - -The _tep_filter_make_string()_ function constructs a string, displaying -the _filter_ contents for given _event_id_. - -The _tep_filter_strerror()_ function copies the _filter_ error buffer into the -given _buf_ with the size _buflen_. If the error buffer is empty, in the _buf_ -is copied a string, describing the error _err_. - -RETURN VALUE ------------- -The _tep_filter_alloc()_ function returns a pointer to the newly created event -filter, or NULL in case of an error. - -The _tep_filter_add_filter_str()_ function returns 0 if the rule was -successfully added or a negative error code. Use _tep_filter_strerror()_ to see -actual error message in case of an error. - -The _tep_event_filtered()_ function returns 1 if the filter is found for given -event, or 0 otherwise. - -The _tep_filter_remove_event()_ function returns 1 if the vent was removed, or -0 if the event was not found. - -The _tep_filter_match()_ function returns _tep_errno_, according to the result: -[verse] --- -_pass:[TEP_ERRNO__FILTER_MATCH]_ - filter found for event, the record matches. -_pass:[TEP_ERRNO__FILTER_MISS]_ - filter found for event, the record does not match. -_pass:[TEP_ERRNO__FILTER_NOT_FOUND]_ - no filter found for record's event. -_pass:[TEP_ERRNO__NO_FILTER]_ - no rules in the filter. --- -or any other _tep_errno_, if an error occurred during the test. - -The _tep_filter_copy()_ function returns 0 on success or -1 if not all rules - were copied. - -The _tep_filter_compare()_ function returns 1 if the two filters hold the same -content, or 0 if they do not. - -The _tep_filter_make_string()_ function returns a string, which must be freed -with free(), or NULL in case of an error. - -The _tep_filter_strerror()_ function returns 0 if message was filled -successfully, or -1 in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -char errstr[200]; -int ret; - -struct tep_event_filter *filter = tep_filter_alloc(tep); -struct tep_event_filter *filter1 = tep_filter_alloc(tep); -ret = tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu==1"); -if(ret < 0) { - tep_filter_strerror(filter, ret, errstr, sizeof(errstr)); - /* Failed to add a new rule to the filter, the error string is in errstr */ -} -if (tep_filter_copy(filter1, filter) != 0) { - /* Failed to copy filter in filter1 */ -} -... -if (tep_filter_compare(filter, filter1) != 1) { - /* Both filters are different */ -} -... -void process_record(struct tep_handle *tep, struct tep_record *record) -{ - struct tep_event *event; - char *fstring; - - event = tep_find_event_by_record(tep, record); - - if (tep_event_filtered(filter, event->id) == 1) { - /* The event has filter */ - fstring = tep_filter_make_string(filter, event->id); - if (fstring != NULL) { - /* The filter for the event is in fstring */ - free(fstring); - } - } - - switch (tep_filter_match(filter, record)) { - case TEP_ERRNO__FILTER_MATCH: - /* The filter matches the record */ - break; - case TEP_ERRNO__FILTER_MISS: - /* The filter does not match the record */ - break; - case TEP_ERRNO__FILTER_NOT_FOUND: - /* No filter found for record's event */ - break; - case TEP_ERRNO__NO_FILTER: - /* There are no rules in the filter */ - break - default: - /* An error occurred during the test */ - break; - } - - if (tep_filter_remove_event(filter, event->id) == 1) { - /* The event was removed from the filter */ - } -} - -... -tep_filter_reset(filter); -... -tep_filter_free(filter); -tep_filter_free(filter1); -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt deleted file mode 100644 index f6aca0df2151a..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt +++ /dev/null @@ -1,183 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_find_function, tep_find_function_address, tep_set_function_resolver, -tep_reset_function_resolver, tep_register_function, tep_register_print_string - -function related tep APIs - -SYNOPSIS --------- -[verse] --- -*#include * - -typedef char pass:[*](*tep_func_resolver_t*)(void pass:[*]_priv_, unsigned long long pass:[*]_addrp_, char pass:[**]_modp_); -int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); -void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); -const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); -unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); -int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); -int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); --- - -DESCRIPTION ------------ -Some tools may have already a way to resolve the kernel functions. These APIs -allow them to keep using it instead of duplicating all the entries inside. - -The _tep_func_resolver_t_ type is the prototype of the alternative kernel -functions resolver. This function receives a pointer to its custom context -(set with the _tep_set_function_resolver()_ call ) and the address of a kernel -function, which has to be resolved. In case of success, it should return -the name of the function and its module (if any) in _modp_. - -The _tep_set_function_resolver()_ function registers _func_ as an alternative -kernel functions resolver. The _tep_ argument is trace event parser context. -The _priv_ argument is a custom context of the _func_ function. The function -resolver is used by the APIs _tep_find_function()_, -_tep_find_function_address()_, and _tep_print_func_field()_ to resolve -a function address to a function name. - -The _tep_reset_function_resolver()_ function resets the kernel functions -resolver to the default function. The _tep_ argument is trace event parser -context. - - -These APIs can be used to find function name and start address, by given -address. The given address does not have to be exact, it will select -the function that would contain it. - -The _tep_find_function()_ function returns the function name, which contains the -given address _addr_. The _tep_ argument is the trace event parser context. - -The _tep_find_function_address()_ function returns the function start address, -by given address _addr_. The _addr_ does not have to be exact, it will select -the function that would contain it. The _tep_ argument is the trace event -parser context. - -The _tep_register_function()_ function registers a function name mapped to an -address and (optional) module. This mapping is used in case the function tracer -or events have "%pS" parameter in its format string. It is common to pass in -the kallsyms function names with their corresponding addresses with this -function. The _tep_ argument is the trace event parser context. The _name_ is -the name of the function, the string is copied internally. The _addr_ is the -start address of the function. The _mod_ is the kernel module the function may -be in (NULL for none). - -The _tep_register_print_string()_ function registers a string by the address -it was stored in the kernel. Some strings internal to the kernel with static -address are passed to certain events. The "%s" in the event's format field -which has an address needs to know what string would be at that address. The -tep_register_print_string() supplies the parsing with the mapping between kernel -addresses and those strings. The _tep_ argument is the trace event parser -context. The _fmt_ is the string to register, it is copied internally. -The _addr_ is the address the string was located at. - - -RETURN VALUE ------------- -The _tep_set_function_resolver()_ function returns 0 in case of success, or -1 -in case of an error. - -The _tep_find_function()_ function returns the function name, or NULL in case -it cannot be found. - -The _tep_find_function_address()_ function returns the function start address, -or 0 in case it cannot be found. - -The _tep_register_function()_ function returns 0 in case of success. In case of -an error -1 is returned, and errno is set to the appropriate error number. - -The _tep_register_print_string()_ function returns 0 in case of success. In case -of an error -1 is returned, and errno is set to the appropriate error number. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -char *my_resolve_kernel_addr(void *context, - unsigned long long *addrp, char **modp) -{ - struct db *function_database = context; - struct symbol *sym = sql_lookup(function_database, *addrp); - - if (!sym) - return NULL; - - *modp = sym->module_name; - return sym->name; -} - -void show_function( unsigned long long addr) -{ - unsigned long long fstart; - const char *fname; - - if (tep_set_function_resolver(tep, my_resolve_kernel_addr, - function_database) != 0) { - /* failed to register my_resolve_kernel_addr */ - } - - /* These APIs use my_resolve_kernel_addr() to resolve the addr */ - fname = tep_find_function(tep, addr); - fstart = tep_find_function_address(tep, addr); - - /* - addr is in function named fname, starting at fstart address, - at offset (addr - fstart) - */ - - tep_reset_function_resolver(tep); - -} -... - if (tep_register_function(tep, "kvm_exit", - (unsigned long long) 0x12345678, "kvm") != 0) { - /* Failed to register kvm_exit address mapping */ - } -... - if (tep_register_print_string(tep, "print string", - (unsigned long long) 0x87654321, NULL) != 0) { - /* Failed to register "print string" address mapping */ - } -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt deleted file mode 100644 index 04840e244445d..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-func_find.txt +++ /dev/null @@ -1,88 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_find_function,tep_find_function_address - Find function name / start address. - -SYNOPSIS --------- -[verse] --- -*#include * - -const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); -unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); --- - -DESCRIPTION ------------ -These functions can be used to find function name and start address, by given -address. The given address does not have to be exact, it will select the function -that would contain it. - -The _tep_find_function()_ function returns the function name, which contains the -given address _addr_. The _tep_ argument is the trace event parser context. - -The _tep_find_function_address()_ function returns the function start address, -by given address _addr_. The _addr_ does not have to be exact, it will select the -function that would contain it. The _tep_ argument is the trace event parser context. - -RETURN VALUE ------------- -The _tep_find_function()_ function returns the function name, or NULL in case -it cannot be found. - -The _tep_find_function_address()_ function returns the function start address, -or 0 in case it cannot be found. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -void show_function( unsigned long long addr) -{ - const char *fname = tep_find_function(tep, addr); - unsigned long long fstart = tep_find_function_address(tep, addr); - - /* addr is in function named fname, starting at fstart address, at offset (addr - fstart) */ -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt deleted file mode 100644 index 45b20172e2622..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt +++ /dev/null @@ -1,101 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref - Create, destroy, manage -references of trace event parser context. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_handle pass:[*]*tep_alloc*(void); -void *tep_free*(struct tep_handle pass:[*]_tep_); -void *tep_ref*(struct tep_handle pass:[*]_tep_); -void *tep_unref*(struct tep_handle pass:[*]_tep_); -int *tep_get_ref*(struct tep_handle pass:[*]_tep_); --- - -DESCRIPTION ------------ -These are the main functions to create and destroy tep_handle - the main -structure, representing the trace event parser context. This context is used as -the input parameter of most library APIs. - -The _tep_alloc()_ function allocates and initializes the tep context. - -The _tep_free()_ function will decrement the reference of the _tep_ handler. -When there is no more references, then it will free the handler, as well -as clean up all its resources that it had used. The argument _tep_ is -the pointer to the trace event parser context. - -The _tep_ref()_ function adds a reference to the _tep_ handler. - -The _tep_unref()_ function removes a reference from the _tep_ handler. When -the last reference is removed, the _tep_ is destroyed, and all resources that -it had used are cleaned up. - -The _tep_ref_get()_ functions gets the current references of the _tep_ handler. - -RETURN VALUE ------------- -_tep_alloc()_ returns a pointer to a newly created tep_handle structure. -NULL is returned in case there is not enough free memory to allocate it. - -_tep_ref_get()_ returns the current references of _tep_. -If _tep_ is NULL, 0 is returned. - -EXAMPLE -------- -[source,c] --- -#include - -... -struct tep_handle *tep = tep_alloc(); -... -int ref = tep_get_ref(tep); -tep_ref(tep); -if ( (ref+1) != tep_get_ref(tep)) { - /* Something wrong happened, the counter is not incremented by 1 */ -} -tep_unref(tep); -... -tep_free(tep); -... --- -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt b/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt deleted file mode 100644 index 615d117dc39fd..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-header_page.txt +++ /dev/null @@ -1,102 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_header_page_size, tep_get_header_timestamp_size, tep_is_old_format - -Get the data stored in the header page, in kernel context. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); -int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); -bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); --- -DESCRIPTION ------------ -These functions retrieve information from kernel context, stored in tracefs -events/header_page. Old kernels do not have header page info, so default values -from user space context are used. - -The _tep_get_header_page_size()_ function returns the size of a long integer, -in kernel context. The _tep_ argument is trace event parser context. -This information is retrieved from tracefs events/header_page, "commit" field. - -The _tep_get_header_timestamp_size()_ function returns the size of timestamps, -in kernel context. The _tep_ argument is trace event parser context. This -information is retrieved from tracefs events/header_page, "timestamp" field. - -The _tep_is_old_format()_ function returns true if the kernel predates -the addition of events/header_page, otherwise it returns false. - -RETURN VALUE ------------- -The _tep_get_header_page_size()_ function returns the size of a long integer, -in bytes. - -The _tep_get_header_timestamp_size()_ function returns the size of timestamps, -in bytes. - -The _tep_is_old_format()_ function returns true, if an old kernel is used to -generate the tracing data, which has no event/header_page. If the kernel is new, -or _tep_ is NULL, false is returned. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... - int longsize; - int timesize; - bool old; - - longsize = tep_get_header_page_size(tep); - timesize = tep_get_header_timestamp_size(tep); - old = tep_is_old_format(tep); - - printf ("%s kernel is used to generate the tracing data.\n", - old?"Old":"New"); - printf("The size of a long integer is %d bytes.\n", longsize); - printf("The timestamps size is %d bytes.\n", timesize); -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt b/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt deleted file mode 100644 index d5d375eb8d1e9..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-host_endian.txt +++ /dev/null @@ -1,104 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_is_bigendian, tep_is_local_bigendian, tep_set_local_bigendian - Get / set -the endianness of the local machine. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_endian* { - TEP_LITTLE_ENDIAN = 0, - TEP_BIG_ENDIAN -}; - -int *tep_is_bigendian*(void); -bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); -void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); --- - -DESCRIPTION ------------ - -The _tep_is_bigendian()_ gets the endianness of the machine, executing -the function. - -The _tep_is_local_bigendian()_ function gets the endianness of the local -machine, saved in the _tep_ handler. The _tep_ argument is the trace event -parser context. This API is a bit faster than _tep_is_bigendian()_, as it -returns cached endianness of the local machine instead of checking it each time. - -The _tep_set_local_bigendian()_ function sets the endianness of the local -machine in the _tep_ handler. The _tep_ argument is trace event parser context. -The _endian_ argument is the endianness: -[verse] --- - _TEP_LITTLE_ENDIAN_ - the machine is little endian, - _TEP_BIG_ENDIAN_ - the machine is big endian. --- - -RETURN VALUE ------------- -The _tep_is_bigendian()_ function returns non zero if the endianness of the -machine, executing the code, is big endian and zero otherwise. - -The _tep_is_local_bigendian()_ function returns true, if the endianness of the -local machine, saved in the _tep_ handler, is big endian, or false otherwise. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... - if (tep_is_bigendian()) - tep_set_local_bigendian(tep, TEP_BIG_ENDIAN); - else - tep_set_local_bigendian(tep, TEP_LITTLE_ENDIAN); -... - if (tep_is_local_bigendian(tep)) - printf("This machine you are running on is bigendian\n"); - else - printf("This machine you are running on is little endian\n"); - --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt deleted file mode 100644 index 01d78ea2519aa..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-long_size.txt +++ /dev/null @@ -1,78 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_long_size, tep_set_long_size - Get / set the size of a long integer on -the machine, where the trace is generated, in bytes - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); -void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); --- - -DESCRIPTION ------------ -The _tep_get_long_size()_ function returns the size of a long integer on the machine, -where the trace is generated. The _tep_ argument is trace event parser context. - -The _tep_set_long_size()_ function sets the size of a long integer on the machine, -where the trace is generated. The _tep_ argument is trace event parser context. -The _long_size_ is the size of a long integer, in bytes. - -RETURN VALUE ------------- -The _tep_get_long_size()_ function returns the size of a long integer on the machine, -where the trace is generated, in bytes. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -tep_set_long_size(tep, 4); -... -int long_size = tep_get_long_size(tep); -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt b/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt deleted file mode 100644 index 452c0cfa1822c..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-page_size.txt +++ /dev/null @@ -1,82 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_get_page_size, tep_set_page_size - Get / set the size of a memory page on -the machine, where the trace is generated - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); -void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); --- - -DESCRIPTION ------------ -The _tep_get_page_size()_ function returns the size of a memory page on -the machine, where the trace is generated. The _tep_ argument is trace -event parser context. - -The _tep_set_page_size()_ function stores in the _tep_ context the size of a -memory page on the machine, where the trace is generated. -The _tep_ argument is trace event parser context. -The _page_size_ argument is the size of a memory page, in bytes. - -RETURN VALUE ------------- -The _tep_get_page_size()_ function returns size of the memory page, in bytes. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep = tep_alloc(); -... - int page_size = getpagesize(); - - tep_set_page_size(tep, page_size); - - printf("The page size for this machine is %d\n", tep_get_page_size(tep)); - --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt deleted file mode 100644 index f248114ca1ff2..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-parse_event.txt +++ /dev/null @@ -1,90 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_parse_event, tep_parse_format - Parse the event format information - -SYNOPSIS --------- -[verse] --- -*#include * - -enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); -enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); --- - -DESCRIPTION ------------ -The _tep_parse_event()_ function parses the event format and creates an event -structure to quickly parse raw data for a given event. The _tep_ argument is -the trace event parser context. The created event structure is stored in the -_tep_ context. The _buf_ argument is a buffer with _size_, where the event -format data is. The event format data can be taken from -tracefs/events/.../.../format files. The _sys_ argument is the system of -the event. - -The _tep_parse_format()_ function does the same as _tep_parse_event()_. The only -difference is in the extra _eventp_ argument, where the newly created event -structure is returned. - -RETURN VALUE ------------- -Both _tep_parse_event()_ and _tep_parse_format()_ functions return 0 on success, -or TEP_ERRNO__... in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -char *buf; -int size; -struct tep_event *event = NULL; -buf = read_file("/sys/kernel/tracing/events/ftrace/print/format", &size); -if (tep_parse_event(tep, buf, size, "ftrace") != 0) { - /* Failed to parse the ftrace print format */ -} - -if (tep_parse_format(tep, &event, buf, size, "ftrace") != 0) { - /* Failed to parse the ftrace print format */ -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt b/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt deleted file mode 100644 index c90f16c7d8e6b..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-parse_head.txt +++ /dev/null @@ -1,82 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_parse_header_page - Parses the data stored in the header page. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); --- - -DESCRIPTION ------------ -The _tep_parse_header_page()_ function parses the header page data from _buf_, -and initializes the _tep_, trace event parser context, with it. The buffer -_buf_ is with _size_, and is supposed to be copied from -tracefs/events/header_page. - -Some old kernels do not have header page info, in this case the -_tep_parse_header_page()_ function can be called with _size_ equal to 0. The -_tep_ context is initialized with default values. The _long_size_ can be used in -this use case, to set the size of a long integer to be used. - -RETURN VALUE ------------- -The _tep_parse_header_page()_ function returns 0 in case of success, or -1 -in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -char *buf; -int size; -buf = read_file("/sys/kernel/tracing/events/header_page", &size); -if (tep_parse_header_page(tep, buf, size, sizeof(unsigned long)) != 0) { - /* Failed to parse the header page */ -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt b/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt deleted file mode 100644 index 4d6394397d92e..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt +++ /dev/null @@ -1,122 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_load_plugins, tep_unload_plugins, tep_load_plugins_hook - Load / unload traceevent plugins. - -SYNOPSIS --------- -[verse] --- -*#include * - -struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); -void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); -void *tep_load_plugins_hook*(struct tep_handle pass:[*]_tep_, const char pass:[*]_suffix_, - void (pass:[*]_load_plugin_)(struct tep_handle pass:[*]tep, - const char pass:[*]path, - const char pass:[*]name, - void pass:[*]data), - void pass:[*]_data_); --- - -DESCRIPTION ------------ -The _tep_load_plugins()_ function loads all plugins, located in the plugin -directories. The _tep_ argument is trace event parser context. -The plugin directories are : -[verse] --- - - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_FIRST - - System's plugin directory, defined at the library compile time. It - depends on the library installation prefix and usually is - _(install_preffix)/lib/traceevent/plugins_ - - Directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ - - User's plugin directory, located at _~/.local/lib/traceevent/plugins_ - - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_LAST --- -Loading of plugins can be controlled by the _tep_flags_, using the -_tep_set_flag()_ API: -[verse] --- - _TEP_DISABLE_SYS_PLUGINS_ - do not load plugins, located in - the system's plugin directory. - _TEP_DISABLE_PLUGINS_ - do not load any plugins. --- -The _tep_set_flag()_ API needs to be called before _tep_load_plugins()_, if -loading of all plugins is not the desired case. - -The _tep_unload_plugins()_ function unloads the plugins, previously loaded by -_tep_load_plugins()_. The _tep_ argument is trace event parser context. The -_plugin_list_ is the list of loaded plugins, returned by -the _tep_load_plugins()_ function. - -The _tep_load_plugins_hook_ function walks through all directories with plugins -and calls user specified _load_plugin()_ hook for each plugin file. Only files -with given _suffix_ are considered to be plugins. The _data_ is a user specified -context, passed to _load_plugin()_. Directories and the walk order are the same -as in _tep_load_plugins()_ API. - -RETURN VALUE ------------- -The _tep_load_plugins()_ function returns a list of successfully loaded plugins, -or NULL in case no plugins are loaded. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -struct tep_plugin_list *plugins = tep_load_plugins(tep); -if (plugins == NULL) { - /* no plugins are loaded */ -} -... -tep_unload_plugins(plugins, tep); -... -void print_plugin(struct tep_handle *tep, const char *path, - const char *name, void *data) -{ - pritnf("Found libtraceevent plugin %s/%s\n", path, name); -} -... -tep_load_plugins_hook(tep, ".so", print_plugin, NULL); -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_, _tep_set_flag(3)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt b/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt deleted file mode 100644 index e9a69116c78b7..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-record_parse.txt +++ /dev/null @@ -1,137 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_data_type, tep_data_pid,tep_data_preempt_count, tep_data_flags - -Extract common fields from a record. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *trace_flag_type* { - _TRACE_FLAG_IRQS_OFF_, - _TRACE_FLAG_IRQS_NOSUPPORT_, - _TRACE_FLAG_NEED_RESCHED_, - _TRACE_FLAG_HARDIRQ_, - _TRACE_FLAG_SOFTIRQ_, -}; - -int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); -int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); -int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); -int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); --- - -DESCRIPTION ------------ -This set of functions can be used to extract common fields from a record. - -The _tep_data_type()_ function gets the event id from the record _rec_. -It reads the "common_type" field. The _tep_ argument is the trace event parser -context. - -The _tep_data_pid()_ function gets the process id from the record _rec_. -It reads the "common_pid" field. The _tep_ argument is the trace event parser -context. - -The _tep_data_preempt_count()_ function gets the preemption count from the -record _rec_. It reads the "common_preempt_count" field. The _tep_ argument is -the trace event parser context. - -The _tep_data_flags()_ function gets the latency flags from the record _rec_. -It reads the "common_flags" field. The _tep_ argument is the trace event parser -context. Supported latency flags are: -[verse] --- - _TRACE_FLAG_IRQS_OFF_, Interrupts are disabled. - _TRACE_FLAG_IRQS_NOSUPPORT_, Reading IRQ flag is not supported by the architecture. - _TRACE_FLAG_NEED_RESCHED_, Task needs rescheduling. - _TRACE_FLAG_HARDIRQ_, Hard IRQ is running. - _TRACE_FLAG_SOFTIRQ_, Soft IRQ is running. --- - -RETURN VALUE ------------- -The _tep_data_type()_ function returns an integer, representing the event id. - -The _tep_data_pid()_ function returns an integer, representing the process id - -The _tep_data_preempt_count()_ function returns an integer, representing the -preemption count. - -The _tep_data_flags()_ function returns an integer, representing the latency -flags. Look at the _trace_flag_type_ enum for supported flags. - -All these functions in case of an error return a negative integer. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -void process_record(struct tep_record *record) -{ - int data; - - data = tep_data_type(tep, record); - if (data >= 0) { - /* Got the ID of the event */ - } - - data = tep_data_pid(tep, record); - if (data >= 0) { - /* Got the process ID */ - } - - data = tep_data_preempt_count(tep, record); - if (data >= 0) { - /* Got the preemption count */ - } - - data = tep_data_flags(tep, record); - if (data >= 0) { - /* Got the latency flags */ - } -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt deleted file mode 100644 index 53d37d72a1c1f..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-reg_event_handler.txt +++ /dev/null @@ -1,156 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_register_event_handler, tep_unregister_event_handler - Register / -unregisters a callback function to parse an event information. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_reg_handler* { - _TEP_REGISTER_SUCCESS_, - _TEP_REGISTER_SUCCESS_OVERWRITE_, -}; - -int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); -int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); - -typedef int (*pass:[*]tep_event_handler_func*)(struct trace_seq pass:[*]s, struct tep_record pass:[*]record, struct tep_event pass:[*]event, void pass:[*]context); --- - -DESCRIPTION ------------ -The _tep_register_event_handler()_ function registers a handler function, -which is going to be called to parse the information for a given event. -The _tep_ argument is the trace event parser context. The _id_ argument is -the id of the event. The _sys_name_ argument is the name of the system, -the event belongs to. The _event_name_ argument is the name of the event. -If _id_ is >= 0, it is used to find the event, otherwise _sys_name_ and -_event_name_ are used. The _func_ is a pointer to the function, which is going -to be called to parse the event information. The _context_ argument is a pointer -to the context data, which will be passed to the _func_. If a handler function -for the same event is already registered, it will be overridden with the new -one. This mechanism allows a developer to override the parsing of a given event. -If for some reason the default print format is not sufficient, the developer -can register a function for an event to be used to parse the data instead. - -The _tep_unregister_event_handler()_ function unregisters the handler function, -previously registered with _tep_register_event_handler()_. The _tep_ argument -is the trace event parser context. The _id_, _sys_name_, _event_name_, _func_, -and _context_ are the same arguments, as when the callback function _func_ was -registered. - -The _tep_event_handler_func_ is the type of the custom event handler -function. The _s_ argument is the trace sequence, it can be used to create a -custom string, describing the event. A _record_ to get the event from is passed -as input parameter and also the _event_ - the handle to the record's event. The -_context_ is custom context, set when the custom event handler is registered. - -RETURN VALUE ------------- -The _tep_register_event_handler()_ function returns _TEP_REGISTER_SUCCESS_ -if the new handler is registered successfully or -_TEP_REGISTER_SUCCESS_OVERWRITE_ if an existing handler is overwritten. -If there is not enough memory to complete the registration, -TEP_ERRNO__MEM_ALLOC_FAILED is returned. - -The _tep_unregister_event_handler()_ function returns 0 if _func_ was removed -successful or, -1 if the event was not found. - -The _tep_event_handler_func_ should return -1 in case of an error, -or 0 otherwise. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct tep_handle *tep = tep_alloc(); -... -int timer_expire_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - trace_seq_printf(s, "hrtimer="); - - if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) == -1) - tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1); - - trace_seq_printf(s, " now="); - - tep_print_num_field(s, "%llu", event, "now", record, 1); - - tep_print_func_field(s, " function=%s", event, "function", record, 0); - - return 0; -} -... - int ret; - - ret = tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entry", - timer_expire_handler, NULL); - if (ret < 0) { - char buf[32]; - - tep_strerror(tep, ret, buf, 32) - printf("Failed to register handler for hrtimer_expire_entry: %s\n", buf); - } else { - switch (ret) { - case TEP_REGISTER_SUCCESS: - printf ("Registered handler for hrtimer_expire_entry\n"); - break; - case TEP_REGISTER_SUCCESS_OVERWRITE: - printf ("Overwrote handler for hrtimer_expire_entry\n"); - break; - } - } -... - ret = tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_entry", - timer_expire_handler, NULL); - if ( ret ) - printf ("Failed to unregister handler for hrtimer_expire_entry\n"); - --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences - related APIs. Trace sequences are used to allow a function to call - several other functions to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt b/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt deleted file mode 100644 index 708dce91ebd86..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-reg_print_func.txt +++ /dev/null @@ -1,155 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_register_print_function,tep_unregister_print_function - -Registers / Unregisters a helper function. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_func_arg_type* { - TEP_FUNC_ARG_VOID, - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_LONG, - TEP_FUNC_ARG_STRING, - TEP_FUNC_ARG_PTR, - TEP_FUNC_ARG_MAX_TYPES -}; - -typedef unsigned long long (*pass:[*]tep_func_handler*)(struct trace_seq pass:[*]s, unsigned long long pass:[*]args); - -int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); -int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); --- - -DESCRIPTION ------------ -Some events may have helper functions in the print format arguments. -This allows a plugin to dynamically create a way to process one of -these functions. - -The _tep_register_print_function()_ registers such helper function. The _tep_ -argument is the trace event parser context. The _func_ argument is a pointer -to the helper function. The _ret_type_ argument is the return type of the -helper function, value from the _tep_func_arg_type_ enum. The _name_ is the name -of the helper function, as seen in the print format arguments. The _..._ is a -variable list of _tep_func_arg_type_ enums, the _func_ function arguments. -This list must end with _TEP_FUNC_ARG_VOID_. See 'EXAMPLE' section. - -The _tep_unregister_print_function()_ unregisters a helper function, previously -registered with _tep_register_print_function()_. The _tep_ argument is the -trace event parser context. The _func_ and _name_ arguments are the same, used -when the helper function was registered. - -The _tep_func_handler_ is the type of the helper function. The _s_ argument is -the trace sequence, it can be used to create a custom string. -The _args_ is a list of arguments, defined when the helper function was -registered. - -RETURN VALUE ------------- -The _tep_register_print_function()_ function returns 0 in case of success. -In case of an error, TEP_ERRNO_... code is returned. - -The _tep_unregister_print_function()_ returns 0 in case of success, or -1 in -case of an error. - -EXAMPLE -------- -Some events have internal functions calls, that appear in the print format -output. For example "tracefs/events/i915/g4x_wm/format" has: -[source,c] --- -print fmt: "pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s", - ((REC->pipe) + 'A'), REC->frame, REC->scanline, REC->primary, - REC->sprite, REC->cursor, yesno(REC->cxsr), REC->sr_plane, - REC->sr_cursor, REC->sr_fbc, yesno(REC->hpll), REC->hpll_plane, - REC->hpll_cursor, REC->hpll_fbc, yesno(REC->fbc) --- -Notice the call to function _yesno()_ in the print arguments. In the kernel -context, this function has the following implementation: -[source,c] --- -static const char *yesno(int x) -{ - static const char *yes = "yes"; - static const char *no = "no"; - - return x ? yes : no; -} --- -The user space event parser has no idea how to handle this _yesno()_ function. -The _tep_register_print_function()_ API can be used to register a user space -helper function, mapped to the kernel's _yesno()_: -[source,c] --- -#include -#include -... -struct tep_handle *tep = tep_alloc(); -... -static const char *yes_no_helper(int x) -{ - return x ? "yes" : "no"; -} -... - if ( tep_register_print_function(tep, - yes_no_helper, - TEP_FUNC_ARG_STRING, - "yesno", - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_VOID) != 0) { - /* Failed to register yes_no_helper function */ - } - -/* - Now, when the event parser encounters this yesno() function, it will know - how to handle it. -*/ -... - if (tep_unregister_print_function(tep, yes_no_helper, "yesno") != 0) { - /* Failed to unregister yes_no_helper function */ - } --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences - related APIs. Trace sequences are used to allow a function to call - several other functions to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt b/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt deleted file mode 100644 index b0599780b9a61..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-set_flag.txt +++ /dev/null @@ -1,104 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_set_flag, tep_clear_flag, tep_test_flag - -Manage flags of trace event parser context. - -SYNOPSIS --------- -[verse] --- -*#include * - -enum *tep_flag* { - _TEP_NSEC_OUTPUT_, - _TEP_DISABLE_SYS_PLUGINS_, - _TEP_DISABLE_PLUGINS_ -}; -void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); -void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); -bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); --- - -DESCRIPTION ------------ -Trace event parser context flags are defined in *enum tep_flag*: -[verse] --- -_TEP_NSEC_OUTPUT_ - print event's timestamp in nano seconds, instead of micro seconds. -_TEP_DISABLE_SYS_PLUGINS_ - disable plugins, located in system's plugin - directory. This directory is defined at library compile - time, and usually depends on library installation - prefix: (install_preffix)/lib/traceevent/plugins -_TEP_DISABLE_PLUGINS_ - disable all library plugins: - - in system's plugin directory - - in directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ - - in user's home directory, _~/.traceevent/plugins_ --- -Note: plugin related flags must me set before calling _tep_load_plugins()_ API. - -The _tep_set_flag()_ function sets _flag_ to _tep_ context. - -The _tep_clear_flag()_ function clears _flag_ from _tep_ context. - -The _tep_test_flag()_ function tests if _flag_ is set to _tep_ context. - -RETURN VALUE ------------- -_tep_test_flag()_ function returns true if _flag_ is set, false otherwise. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -/* Print timestamps in nanoseconds */ -tep_set_flag(tep, TEP_NSEC_OUTPUT); -... -if (tep_test_flag(tep, TEP_NSEC_OUTPUT)) { - /* print timestamps in nanoseconds */ -} else { - /* print timestamps in microseconds */ -} -... -/* Print timestamps in microseconds */ -tep_clear_flag(tep, TEP_NSEC_OUTPUT); -... --- -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt b/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt deleted file mode 100644 index ee4062a00c9f9..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-strerror.txt +++ /dev/null @@ -1,85 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -tep_strerror - Returns a string describing regular errno and tep error number. - -SYNOPSIS --------- -[verse] --- -*#include * - -int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); - --- -DESCRIPTION ------------ -The _tep_strerror()_ function converts tep error number into a human -readable string. -The _tep_ argument is trace event parser context. The _errnum_ is a regular -errno, defined in errno.h, or a tep error number. The string, describing this -error number is copied in the _buf_ argument. The _buflen_ argument is -the size of the _buf_. - -It as a thread safe wrapper around strerror_r(). The library function has two -different behaviors - POSIX and GNU specific. The _tep_strerror()_ API always -behaves as the POSIX version - the error string is copied in the user supplied -buffer. - -RETURN VALUE ------------- -The _tep_strerror()_ function returns 0, if a valid _errnum_ is passed and the -string is copied into _buf_. If _errnum_ is not a valid error number, --1 is returned and _buf_ is not modified. - -EXAMPLE -------- -[source,c] --- -#include -... -struct tep_handle *tep = tep_alloc(); -... -char buf[32]; -char *pool = calloc(1, 128); -if (tep == NULL) { - tep_strerror(tep, TEP_ERRNO__MEM_ALLOC_FAILED, buf, 32); - printf ("The pool is not initialized, %s", buf); -} -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt b/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt deleted file mode 100644 index 8ac6aa174e12a..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent-tseq.txt +++ /dev/null @@ -1,158 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -trace_seq_init, trace_seq_destroy, trace_seq_reset, trace_seq_terminate, -trace_seq_putc, trace_seq_puts, trace_seq_printf, trace_seq_vprintf, -trace_seq_do_fprintf, trace_seq_do_printf - -Initialize / destroy a trace sequence. - -SYNOPSIS --------- -[verse] --- -*#include * -*#include * - -void *trace_seq_init*(struct trace_seq pass:[*]_s_); -void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); -void *trace_seq_reset*(struct trace_seq pass:[*]_s_); -void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); -int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); -int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); -int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, _..._); -int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); -int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); -int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); --- - -DESCRIPTION ------------ -Trace sequences are used to allow a function to call several other functions -to create a string of data to use. - -The _trace_seq_init()_ function initializes the trace sequence _s_. - -The _trace_seq_destroy()_ function destroys the trace sequence _s_ and frees -all its resources that it had used. - -The _trace_seq_reset()_ function re-initializes the trace sequence _s_. All -characters already written in _s_ will be deleted. - -The _trace_seq_terminate()_ function terminates the trace sequence _s_. It puts -the null character pass:['\0'] at the end of the buffer. - -The _trace_seq_putc()_ function puts a single character _c_ in the trace -sequence _s_. - -The _trace_seq_puts()_ function puts a NULL terminated string _str_ in the -trace sequence _s_. - -The _trace_seq_printf()_ function puts a formated string _fmt _with -variable arguments _..._ in the trace sequence _s_. - -The _trace_seq_vprintf()_ function puts a formated string _fmt _with -list of arguments _args_ in the trace sequence _s_. - -The _trace_seq_do_printf()_ function prints the buffer of trace sequence _s_ to -the standard output stdout. - -The _trace_seq_do_fprintf()_ function prints the buffer of trace sequence _s_ -to the given file _fp_. - -RETURN VALUE ------------- -Both _trace_seq_putc()_ and _trace_seq_puts()_ functions return the number of -characters put in the trace sequence, or 0 in case of an error - -Both _trace_seq_printf()_ and _trace_seq_vprintf()_ functions return 0 if the -trace oversizes the buffer's free space, the number of characters printed, or -a negative value in case of an error. - -Both _trace_seq_do_printf()_ and _trace_seq_do_fprintf()_ functions return the -number of printed characters, or -1 in case of an error. - -EXAMPLE -------- -[source,c] --- -#include -#include -... -struct trace_seq seq; -trace_seq_init(&seq); -... -void foo_seq_print(struct trace_seq *tseq, char *format, ...) -{ - va_list ap; - va_start(ap, format); - if (trace_seq_vprintf(tseq, format, ap) <= 0) { - /* Failed to print in the trace sequence */ - } - va_end(ap); -} - -trace_seq_reset(&seq); - -char *str = " MAN page example"; -if (trace_seq_puts(&seq, str) != strlen(str)) { - /* Failed to put str in the trace sequence */ -} -if (trace_seq_putc(&seq, ':') != 1) { - /* Failed to put ':' in the trace sequence */ -} -if (trace_seq_printf(&seq, " trace sequence: %d", 1) <= 0) { - /* Failed to print in the trace sequence */ -} -foo_seq_print( &seq, " %d\n", 2); - -trace_seq_terminate(&seq); -... - -if (trace_seq_do_printf(&seq) < 0 ) { - /* Failed to print the sequence buffer to the standard output */ -} -FILE *fp = fopen("trace.txt", "w"); -if (trace_seq_do_fprintf(&seq, fp) < 0 ) [ - /* Failed to print the sequence buffer to the trace.txt file */ -} - -trace_seq_destroy(&seq); -... --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences related APIs. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_libtraceevent(3)_, _trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/libtraceevent.txt b/tools/lib/traceevent/Documentation/libtraceevent.txt deleted file mode 100644 index d530a7ce8fb23..0000000000000 --- a/tools/lib/traceevent/Documentation/libtraceevent.txt +++ /dev/null @@ -1,192 +0,0 @@ -libtraceevent(3) -================ - -NAME ----- -libtraceevent - Linux kernel trace event library - -SYNOPSIS --------- -[verse] --- -*#include * - -Management of tep handler data structure and access of its members: - struct tep_handle pass:[*]*tep_alloc*(void); - void *tep_free*(struct tep_handle pass:[*]_tep_); - void *tep_ref*(struct tep_handle pass:[*]_tep_); - void *tep_unref*(struct tep_handle pass:[*]_tep_); - int *tep_get_ref*(struct tep_handle pass:[*]_tep_); - void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); - void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); - bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_); - int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); - void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); - int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); - void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); - int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); - void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); - int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); - int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); - bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); - int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); - -Register / unregister APIs: - int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); - int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); - int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); - int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); - int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); - int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); - -Plugins management: - struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); - void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); - char pass:[*]pass:[*]*tep_plugin_list_options*(void); - void *tep_plugin_free_options_list*(char pass:[*]pass:[*]_list_); - int *tep_plugin_add_options*(const char pass:[*]_name_, struct tep_plugin_option pass:[*]_options_); - void *tep_plugin_remove_options*(struct tep_plugin_option pass:[*]_options_); - void *tep_print_plugins*(struct trace_seq pass:[*]_s_, const char pass:[*]_prefix_, const char pass:[*]_suffix_, const struct tep_plugin_list pass:[*]_list_); - -Event related APIs: - struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); - struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); - int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); - struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); - struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); - void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._); - -Event finding: - struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); - struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); - struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); - -Parsing of event files: - int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); - enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); - enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); - -APIs related to fields from event's format files: - struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); - struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); - void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); - int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); - int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); - int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); - int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_); - -Event fields printing: - void *tep_print_field*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, struct tep_format_field pass:[*]_field_); - void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_); - int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); - int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); - -Event fields finding: - struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); - struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); - struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); - -Functions resolver: - int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); - void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); - const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); - unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); - -Filter management: - struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); - enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); - enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); - int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); - int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); - void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); - void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); - char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); - int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); - int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); - int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); - -Parsing various data from the records: - int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); - int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); - int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); - int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); - -Command and task related APIs: - const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_tep_, int _pid_); - struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); - int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); - int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); - bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); - int *tep_cmdline_pid*(struct tep_handle pass:[*]_tep_, struct cmdline pass:[*]_cmdline_); - -Endian related APIs: - int *tep_is_bigendian*(void); - unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); - bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); - void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); - bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); - void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); - -Trace sequences: -*#include * - void *trace_seq_init*(struct trace_seq pass:[*]_s_); - void *trace_seq_reset*(struct trace_seq pass:[*]_s_); - void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); - int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, ...); - int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); - int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); - int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); - void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); - int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); - int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); --- - -DESCRIPTION ------------ -The libtraceevent(3) library provides APIs to access kernel tracepoint events, -located in the tracefs file system under the events directory. - -ENVIRONMENT ------------ -[verse] --- -TRACEEVENT_PLUGIN_DIR - Additional plugin directory. All shared object files, located in this directory will be loaded as traceevent plugins. --- - -FILES ------ -[verse] --- -*event-parse.h* - Header file to include in order to have access to the library APIs. -*trace-seq.h* - Header file to include in order to have access to trace sequences related APIs. - Trace sequences are used to allow a function to call several other functions - to create a string of data to use. -*-ltraceevent* - Linker switch to add when building a program that uses the library. --- - -SEE ALSO --------- -_trace-cmd(1)_ - -AUTHOR ------- -[verse] --- -*Steven Rostedt* , author of *libtraceevent*. -*Tzvetomir Stoyanov* , author of this man page. --- -REPORTING BUGS --------------- -Report bugs to - -LICENSE -------- -libtraceevent is Free Software licensed under the GNU LGPL 2.1 - -RESOURCES ---------- -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git diff --git a/tools/lib/traceevent/Documentation/manpage-1.72.xsl b/tools/lib/traceevent/Documentation/manpage-1.72.xsl deleted file mode 100644 index b4d315cb8c479..0000000000000 --- a/tools/lib/traceevent/Documentation/manpage-1.72.xsl +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - diff --git a/tools/lib/traceevent/Documentation/manpage-base.xsl b/tools/lib/traceevent/Documentation/manpage-base.xsl deleted file mode 100644 index a264fa616093c..0000000000000 --- a/tools/lib/traceevent/Documentation/manpage-base.xsl +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - sp - - - - - - - - br - - - diff --git a/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl b/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl deleted file mode 100644 index 608eb5df62814..0000000000000 --- a/tools/lib/traceevent/Documentation/manpage-bold-literal.xsl +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - fB - - - fR - - - diff --git a/tools/lib/traceevent/Documentation/manpage-normal.xsl b/tools/lib/traceevent/Documentation/manpage-normal.xsl deleted file mode 100644 index a48f5b11f3dcc..0000000000000 --- a/tools/lib/traceevent/Documentation/manpage-normal.xsl +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -\ -. - - diff --git a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl b/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl deleted file mode 100644 index a63c7632a87d4..0000000000000 --- a/tools/lib/traceevent/Documentation/manpage-suppress-sp.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile deleted file mode 100644 index 98dfd4badea3b..0000000000000 --- a/tools/lib/traceevent/Makefile +++ /dev/null @@ -1,300 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# trace-cmd version -EP_VERSION = 1 -EP_PATCHLEVEL = 1 -EP_EXTRAVERSION = 0 - -# file format version -FILE_VERSION = 6 - -MAKEFLAGS += --no-print-directory - - -# Makefiles suck: This macro sets a default value of $(2) for the -# variable named by $(1), unless the variable has been set by -# environment or command line. This is necessary for CC and AR -# because make sets default values, so the simpler ?= approach -# won't work as expected. -define allow-override - $(if $(or $(findstring environment,$(origin $(1))),\ - $(findstring command line,$(origin $(1)))),,\ - $(eval $(1) = $(2))) -endef - -# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. -$(call allow-override,CC,$(CROSS_COMPILE)gcc) -$(call allow-override,AR,$(CROSS_COMPILE)ar) -$(call allow-override,NM,$(CROSS_COMPILE)nm) -$(call allow-override,PKG_CONFIG,pkg-config) - -EXT = -std=gnu99 -INSTALL = install - -# Use DESTDIR for installing into a different root directory. -# This is useful for building a package. The program will be -# installed in this directory as if it was the root directory. -# Then the build tool can move it later. -DESTDIR ?= -DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' - -LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) -ifeq ($(LP64), 1) - libdir_relative_temp = lib64 -else - libdir_relative_temp = lib -endif - -libdir_relative ?= $(libdir_relative_temp) -prefix ?= /usr/local -libdir = $(prefix)/$(libdir_relative) -man_dir = $(prefix)/share/man -man_dir_SQ = '$(subst ','\'',$(man_dir))' -pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \ - --variable pc_path pkg-config | tr ":" " ")) -includedir_relative = traceevent -includedir = $(prefix)/include/$(includedir_relative) -includedir_SQ = '$(subst ','\'',$(includedir))' - -export man_dir man_dir_SQ INSTALL -export DESTDIR DESTDIR_SQ -export EVENT_PARSE_VERSION - -include ../../scripts/Makefile.include - -# copy a bit from Linux kbuild - -ifeq ("$(origin V)", "command line") - VERBOSE = $(V) -endif -ifndef VERBOSE - VERBOSE = 0 -endif - -ifeq ($(srctree),) -srctree := $(patsubst %/,%,$(dir $(CURDIR))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -#$(info Determined 'srctree' to be $(srctree)) -endif - -export prefix libdir src obj - -# Shell quotes -libdir_SQ = $(subst ','\'',$(libdir)) -libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) - -CONFIG_INCLUDES = -CONFIG_LIBS = -CONFIG_FLAGS = - -VERSION = $(EP_VERSION) -PATCHLEVEL = $(EP_PATCHLEVEL) -EXTRAVERSION = $(EP_EXTRAVERSION) - -OBJ = $@ -N = - -EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) - -LIB_TARGET = libtraceevent.a libtraceevent.so.$(EVENT_PARSE_VERSION) -LIB_INSTALL = libtraceevent.a libtraceevent.so* -LIB_INSTALL := $(addprefix $(OUTPUT),$(LIB_INSTALL)) - -INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES) - -# Set compile option CFLAGS -ifdef EXTRA_CFLAGS - CFLAGS := $(EXTRA_CFLAGS) -else - CFLAGS := -g -Wall -endif - -# Append required CFLAGS -override CFLAGS += -fPIC -override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) -override CFLAGS += $(udis86-flags) -D_GNU_SOURCE - -ifeq ($(VERBOSE),1) - Q = -else - Q = @ -endif - -# Disable command line variables (CFLAGS) override from top -# level Makefile (perf), otherwise build Makefile will get -# the same command line setup. -MAKEOVERRIDES= - -export srctree OUTPUT CC LD CFLAGS V -build := -f $(srctree)/tools/build/Makefile.build dir=. obj - -TE_IN := $(OUTPUT)libtraceevent-in.o -LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) - -CMD_TARGETS = $(LIB_TARGET) - -TARGETS = $(CMD_TARGETS) - -all: all_cmd plugins - -all_cmd: $(CMD_TARGETS) - -$(TE_IN): force - $(Q)$(MAKE) $(build)=libtraceevent - -$(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN) - $(QUIET_LINK)$(CC) --shared $(LDFLAGS) $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ - @ln -sf $(@F) $(OUTPUT)libtraceevent.so - @ln -sf $(@F) $(OUTPUT)libtraceevent.so.$(EP_VERSION) - -$(OUTPUT)libtraceevent.a: $(TE_IN) - $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ - -$(OUTPUT)%.so: $(OUTPUT)%-in.o - $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ - -define make_version.h - (echo '/* This file is automatically generated. Do not modify. */'; \ - echo \#define VERSION_CODE $(shell \ - expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ - echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ - echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ - echo '#define FILE_VERSION '$(FILE_VERSION); \ - ) > $1 -endef - -define update_version.h - ($(call make_version.h, $@.tmp); \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); -endef - -ep_version.h: force - $(Q)$(N)$(call update_version.h) - -VERSION_FILES = ep_version.h - -define update_dir - (echo $1 > $@.tmp; \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); -endef - -tags: force - $(RM) tags - find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ - --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/' - -TAGS: force - $(RM) TAGS - find . -name '*.[ch]' | xargs etags \ - --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/' - -define do_install_mkdir - if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ - fi -endef - -define do_install - $(call do_install_mkdir,$2); \ - $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2' -endef - -PKG_CONFIG_SOURCE_FILE = libtraceevent.pc -PKG_CONFIG_FILE := $(addprefix $(OUTPUT),$(PKG_CONFIG_SOURCE_FILE)) -define do_install_pkgconfig_file - if [ -n "${pkgconfig_dir}" ]; then \ - cp -f ${PKG_CONFIG_SOURCE_FILE}.template ${PKG_CONFIG_FILE}; \ - sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \ - sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \ - sed -i "s|LIB_DIR|${libdir}|g" ${PKG_CONFIG_FILE}; \ - sed -i "s|HEADER_DIR|$(includedir)|g" ${PKG_CONFIG_FILE}; \ - $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \ - else \ - (echo Failed to locate pkg-config directory) 1>&2; \ - fi -endef - -install_lib: all_cmd install_plugins install_headers install_pkgconfig - $(call QUIET_INSTALL, $(LIB_TARGET)) \ - $(call do_install_mkdir,$(libdir_SQ)); \ - cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ) - -install_pkgconfig: - $(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \ - $(call do_install_pkgconfig_file,$(prefix)) - -install_headers: - $(call QUIET_INSTALL, traceevent_headers) \ - $(call do_install,event-parse.h,$(includedir_SQ),644); \ - $(call do_install,event-utils.h,$(includedir_SQ),644); \ - $(call do_install,trace-seq.h,$(includedir_SQ),644); \ - $(call do_install,kbuffer.h,$(includedir_SQ),644); - -install: install_lib - -clean: clean_plugins - $(call QUIET_CLEAN, libtraceevent) \ - $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \ - $(RM) TRACEEVENT-CFLAGS tags TAGS; \ - $(RM) $(PKG_CONFIG_FILE) - -PHONY += doc -doc: - $(call descend,Documentation) - -PHONY += doc-clean -doc-clean: - $(call descend,Documentation,clean) - -PHONY += doc-install -doc-install: - $(call descend,Documentation,install) - -PHONY += doc-uninstall -doc-uninstall: - $(call descend,Documentation,uninstall) - -PHONY += help -help: - @echo 'Possible targets:' - @echo'' - @echo ' all - default, compile the library and the'\ - 'plugins' - @echo ' plugins - compile the plugins' - @echo ' install - install the library, the plugins,'\ - 'the header and pkgconfig files' - @echo ' clean - clean the library and the plugins object files' - @echo ' doc - compile the documentation files - man'\ - 'and html pages, in the Documentation directory' - @echo ' doc-clean - clean the documentation files' - @echo ' doc-install - install the man pages' - @echo ' doc-uninstall - uninstall the man pages' - @echo'' - -PHONY += plugins -plugins: - $(call descend,plugins) - -PHONY += install_plugins -install_plugins: - $(call descend,plugins,install) - -PHONY += clean_plugins -clean_plugins: - $(call descend,plugins,clean) - -force: - -# Declare the contents of the .PHONY variable as phony. We keep that -# information in a variable so we can use it in if_changed and friends. -.PHONY: $(PHONY) diff --git a/tools/lib/traceevent/event-parse-api.c b/tools/lib/traceevent/event-parse-api.c deleted file mode 100644 index f8361e45d446f..0000000000000 --- a/tools/lib/traceevent/event-parse-api.c +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - */ - -#include "event-parse.h" -#include "event-parse-local.h" -#include "event-utils.h" - -/** - * tep_get_event - returns the event with the given index - * @tep: a handle to the tep_handle - * @index: index of the requested event, in the range 0 .. nr_events - * - * This returns pointer to the element of the events array with the given index - * If @tep is NULL, or @index is not in the range 0 .. nr_events, NULL is returned. - */ -struct tep_event *tep_get_event(struct tep_handle *tep, int index) -{ - if (tep && tep->events && index < tep->nr_events) - return tep->events[index]; - - return NULL; -} - -/** - * tep_get_first_event - returns the first event in the events array - * @tep: a handle to the tep_handle - * - * This returns pointer to the first element of the events array - * If @tep is NULL, NULL is returned. - */ -struct tep_event *tep_get_first_event(struct tep_handle *tep) -{ - return tep_get_event(tep, 0); -} - -/** - * tep_get_events_count - get the number of defined events - * @tep: a handle to the tep_handle - * - * This returns number of elements in event array - * If @tep is NULL, 0 is returned. - */ -int tep_get_events_count(struct tep_handle *tep) -{ - if (tep) - return tep->nr_events; - return 0; -} - -/** - * tep_set_flag - set event parser flag - * @tep: a handle to the tep_handle - * @flag: flag, or combination of flags to be set - * can be any combination from enum tep_flag - * - * This sets a flag or combination of flags from enum tep_flag - */ -void tep_set_flag(struct tep_handle *tep, int flag) -{ - if (tep) - tep->flags |= flag; -} - -/** - * tep_clear_flag - clear event parser flag - * @tep: a handle to the tep_handle - * @flag: flag to be cleared - * - * This clears a tep flag - */ -void tep_clear_flag(struct tep_handle *tep, enum tep_flag flag) -{ - if (tep) - tep->flags &= ~flag; -} - -/** - * tep_test_flag - check the state of event parser flag - * @tep: a handle to the tep_handle - * @flag: flag to be checked - * - * This returns the state of the requested tep flag. - * Returns: true if the flag is set, false otherwise. - */ -bool tep_test_flag(struct tep_handle *tep, enum tep_flag flag) -{ - if (tep) - return tep->flags & flag; - return false; -} - -__hidden unsigned short data2host2(struct tep_handle *tep, unsigned short data) -{ - unsigned short swap; - - if (!tep || tep->host_bigendian == tep->file_bigendian) - return data; - - swap = ((data & 0xffULL) << 8) | - ((data & (0xffULL << 8)) >> 8); - - return swap; -} - -__hidden unsigned int data2host4(struct tep_handle *tep, unsigned int data) -{ - unsigned int swap; - - if (!tep || tep->host_bigendian == tep->file_bigendian) - return data; - - swap = ((data & 0xffULL) << 24) | - ((data & (0xffULL << 8)) << 8) | - ((data & (0xffULL << 16)) >> 8) | - ((data & (0xffULL << 24)) >> 24); - - return swap; -} - -__hidden unsigned long long -data2host8(struct tep_handle *tep, unsigned long long data) -{ - unsigned long long swap; - - if (!tep || tep->host_bigendian == tep->file_bigendian) - return data; - - swap = ((data & 0xffULL) << 56) | - ((data & (0xffULL << 8)) << 40) | - ((data & (0xffULL << 16)) << 24) | - ((data & (0xffULL << 24)) << 8) | - ((data & (0xffULL << 32)) >> 8) | - ((data & (0xffULL << 40)) >> 24) | - ((data & (0xffULL << 48)) >> 40) | - ((data & (0xffULL << 56)) >> 56); - - return swap; -} - -/** - * tep_get_header_page_size - get size of the header page - * @tep: a handle to the tep_handle - * - * This returns size of the header page - * If @tep is NULL, 0 is returned. - */ -int tep_get_header_page_size(struct tep_handle *tep) -{ - if (tep) - return tep->header_page_size_size; - return 0; -} - -/** - * tep_get_header_timestamp_size - get size of the timestamp in the header page - * @tep: a handle to the tep_handle - * - * This returns size of the timestamp in the header page - * If @tep is NULL, 0 is returned. - */ -int tep_get_header_timestamp_size(struct tep_handle *tep) -{ - if (tep) - return tep->header_page_ts_size; - return 0; -} - -/** - * tep_get_cpus - get the number of CPUs - * @tep: a handle to the tep_handle - * - * This returns the number of CPUs - * If @tep is NULL, 0 is returned. - */ -int tep_get_cpus(struct tep_handle *tep) -{ - if (tep) - return tep->cpus; - return 0; -} - -/** - * tep_set_cpus - set the number of CPUs - * @tep: a handle to the tep_handle - * - * This sets the number of CPUs - */ -void tep_set_cpus(struct tep_handle *tep, int cpus) -{ - if (tep) - tep->cpus = cpus; -} - -/** - * tep_get_long_size - get the size of a long integer on the traced machine - * @tep: a handle to the tep_handle - * - * This returns the size of a long integer on the traced machine - * If @tep is NULL, 0 is returned. - */ -int tep_get_long_size(struct tep_handle *tep) -{ - if (tep) - return tep->long_size; - return 0; -} - -/** - * tep_set_long_size - set the size of a long integer on the traced machine - * @tep: a handle to the tep_handle - * @size: size, in bytes, of a long integer - * - * This sets the size of a long integer on the traced machine - */ -void tep_set_long_size(struct tep_handle *tep, int long_size) -{ - if (tep) - tep->long_size = long_size; -} - -/** - * tep_get_page_size - get the size of a memory page on the traced machine - * @tep: a handle to the tep_handle - * - * This returns the size of a memory page on the traced machine - * If @tep is NULL, 0 is returned. - */ -int tep_get_page_size(struct tep_handle *tep) -{ - if (tep) - return tep->page_size; - return 0; -} - -/** - * tep_set_page_size - set the size of a memory page on the traced machine - * @tep: a handle to the tep_handle - * @_page_size: size of a memory page, in bytes - * - * This sets the size of a memory page on the traced machine - */ -void tep_set_page_size(struct tep_handle *tep, int _page_size) -{ - if (tep) - tep->page_size = _page_size; -} - -/** - * tep_is_file_bigendian - return the endian of the file - * @tep: a handle to the tep_handle - * - * This returns true if the file is in big endian order - * If @tep is NULL, false is returned. - */ -bool tep_is_file_bigendian(struct tep_handle *tep) -{ - if (tep) - return (tep->file_bigendian == TEP_BIG_ENDIAN); - return false; -} - -/** - * tep_set_file_bigendian - set if the file is in big endian order - * @tep: a handle to the tep_handle - * @endian: non zero, if the file is in big endian order - * - * This sets if the file is in big endian order - */ -void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian) -{ - if (tep) - tep->file_bigendian = endian; -} - -/** - * tep_is_local_bigendian - return the endian of the saved local machine - * @tep: a handle to the tep_handle - * - * This returns true if the saved local machine in @tep is big endian. - * If @tep is NULL, false is returned. - */ -bool tep_is_local_bigendian(struct tep_handle *tep) -{ - if (tep) - return (tep->host_bigendian == TEP_BIG_ENDIAN); - return 0; -} - -/** - * tep_set_local_bigendian - set the stored local machine endian order - * @tep: a handle to the tep_handle - * @endian: non zero, if the local host has big endian order - * - * This sets the endian order for the local machine. - */ -void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian) -{ - if (tep) - tep->host_bigendian = endian; -} - -/** - * tep_is_old_format - get if an old kernel is used - * @tep: a handle to the tep_handle - * - * This returns true, if an old kernel is used to generate the tracing events or - * false if a new kernel is used. Old kernels did not have header page info. - * If @tep is NULL, false is returned. - */ -bool tep_is_old_format(struct tep_handle *tep) -{ - if (tep) - return tep->old_format; - return false; -} - -/** - * tep_set_test_filters - set a flag to test a filter string - * @tep: a handle to the tep_handle - * @test_filters: the new value of the test_filters flag - * - * This sets a flag to test a filter string. If this flag is set, when - * tep_filter_add_filter_str() API as called,it will print the filter string - * instead of adding it. - */ -void tep_set_test_filters(struct tep_handle *tep, int test_filters) -{ - if (tep) - tep->test_filters = test_filters; -} diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h deleted file mode 100644 index fd4bbcfbb8493..0000000000000 --- a/tools/lib/traceevent/event-parse-local.h +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - */ - -#ifndef _PARSE_EVENTS_INT_H -#define _PARSE_EVENTS_INT_H - -struct tep_cmdline; -struct cmdline_list; -struct func_map; -struct func_list; -struct event_handler; -struct func_resolver; -struct tep_plugins_dir; - -#define __hidden __attribute__((visibility ("hidden"))) - -struct tep_handle { - int ref_count; - - int header_page_ts_offset; - int header_page_ts_size; - int header_page_size_offset; - int header_page_size_size; - int header_page_data_offset; - int header_page_data_size; - int header_page_overwrite; - - enum tep_endian file_bigendian; - enum tep_endian host_bigendian; - - int old_format; - - int cpus; - int long_size; - int page_size; - - struct tep_cmdline *cmdlines; - struct cmdline_list *cmdlist; - int cmdline_count; - - struct func_map *func_map; - struct func_resolver *func_resolver; - struct func_list *funclist; - unsigned int func_count; - - struct printk_map *printk_map; - struct printk_list *printklist; - unsigned int printk_count; - - struct tep_event **events; - int nr_events; - struct tep_event **sort_events; - enum tep_event_sort_type last_type; - - int type_offset; - int type_size; - - int pid_offset; - int pid_size; - - int pc_offset; - int pc_size; - - int flags_offset; - int flags_size; - - int ld_offset; - int ld_size; - - int test_filters; - - int flags; - - struct tep_format_field *bprint_ip_field; - struct tep_format_field *bprint_fmt_field; - struct tep_format_field *bprint_buf_field; - - struct event_handler *handlers; - struct tep_function_handler *func_handlers; - - /* cache */ - struct tep_event *last_event; - - struct tep_plugins_dir *plugins_dir; -}; - -enum tep_print_parse_type { - PRINT_FMT_STRING, - PRINT_FMT_ARG_DIGIT, - PRINT_FMT_ARG_POINTER, - PRINT_FMT_ARG_STRING, -}; - -struct tep_print_parse { - struct tep_print_parse *next; - - char *format; - int ls; - enum tep_print_parse_type type; - struct tep_print_arg *arg; - struct tep_print_arg *len_as_arg; -}; - -void free_tep_event(struct tep_event *event); -void free_tep_format_field(struct tep_format_field *field); -void free_tep_plugin_paths(struct tep_handle *tep); - -unsigned short data2host2(struct tep_handle *tep, unsigned short data); -unsigned int data2host4(struct tep_handle *tep, unsigned int data); -unsigned long long data2host8(struct tep_handle *tep, unsigned long long data); - -/* access to the internal parser */ -int peek_char(void); -void init_input_buf(const char *buf, unsigned long long size); -unsigned long long get_input_buf_ptr(void); -const char *get_input_buf(void); -enum tep_event_type read_token(char **tok); -void free_token(char *tok); - -#endif /* _PARSE_EVENTS_INT_H */ diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c deleted file mode 100644 index 8e24c4c78c7f0..0000000000000 --- a/tools/lib/traceevent/event-parse.c +++ /dev/null @@ -1,7624 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - * - * The parts for function graph printing was taken and modified from the - * Linux Kernel that were written by - * - Copyright (C) 2009 Frederic Weisbecker, - * Frederic Weisbecker gave his permission to relicense the code to - * the Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "event-parse.h" - -#include "event-parse-local.h" -#include "event-utils.h" -#include "trace-seq.h" - -static const char *input_buf; -static unsigned long long input_buf_ptr; -static unsigned long long input_buf_siz; - -static int is_flag_field; -static int is_symbolic_field; - -static int show_warning = 1; - -#define do_warning(fmt, ...) \ - do { \ - if (show_warning) \ - warning(fmt, ##__VA_ARGS__); \ - } while (0) - -#define do_warning_event(event, fmt, ...) \ - do { \ - if (!show_warning) \ - continue; \ - \ - if (event) \ - warning("[%s:%s] " fmt, event->system, \ - event->name, ##__VA_ARGS__); \ - else \ - warning(fmt, ##__VA_ARGS__); \ - } while (0) - -/** - * init_input_buf - init buffer for parsing - * @buf: buffer to parse - * @size: the size of the buffer - * - * Initializes the internal buffer that tep_read_token() will parse. - */ -__hidden void init_input_buf(const char *buf, unsigned long long size) -{ - input_buf = buf; - input_buf_siz = size; - input_buf_ptr = 0; -} - -__hidden const char *get_input_buf(void) -{ - return input_buf; -} - -__hidden unsigned long long get_input_buf_ptr(void) -{ - return input_buf_ptr; -} - -struct event_handler { - struct event_handler *next; - int id; - const char *sys_name; - const char *event_name; - tep_event_handler_func func; - void *context; -}; - -struct func_params { - struct func_params *next; - enum tep_func_arg_type type; -}; - -struct tep_function_handler { - struct tep_function_handler *next; - enum tep_func_arg_type ret_type; - char *name; - tep_func_handler func; - struct func_params *params; - int nr_args; -}; - -static unsigned long long -process_defined_func(struct trace_seq *s, void *data, int size, - struct tep_event *event, struct tep_print_arg *arg); - -static void free_func_handle(struct tep_function_handler *func); - -void breakpoint(void) -{ - static int x; - x++; -} - -static struct tep_print_arg *alloc_arg(void) -{ - return calloc(1, sizeof(struct tep_print_arg)); -} - -struct tep_cmdline { - char *comm; - int pid; -}; - -static int cmdline_cmp(const void *a, const void *b) -{ - const struct tep_cmdline *ca = a; - const struct tep_cmdline *cb = b; - - if (ca->pid < cb->pid) - return -1; - if (ca->pid > cb->pid) - return 1; - - return 0; -} - -/* Looking for where to place the key */ -static int cmdline_slot_cmp(const void *a, const void *b) -{ - const struct tep_cmdline *ca = a; - const struct tep_cmdline *cb = b; - const struct tep_cmdline *cb1 = cb + 1; - - if (ca->pid < cb->pid) - return -1; - - if (ca->pid > cb->pid) { - if (ca->pid <= cb1->pid) - return 0; - return 1; - } - - return 0; -} - -struct cmdline_list { - struct cmdline_list *next; - char *comm; - int pid; -}; - -static int cmdline_init(struct tep_handle *tep) -{ - struct cmdline_list *cmdlist = tep->cmdlist; - struct cmdline_list *item; - struct tep_cmdline *cmdlines; - int i; - - cmdlines = malloc(sizeof(*cmdlines) * tep->cmdline_count); - if (!cmdlines) - return -1; - - i = 0; - while (cmdlist) { - cmdlines[i].pid = cmdlist->pid; - cmdlines[i].comm = cmdlist->comm; - i++; - item = cmdlist; - cmdlist = cmdlist->next; - free(item); - } - - qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp); - - tep->cmdlines = cmdlines; - tep->cmdlist = NULL; - - return 0; -} - -static const char *find_cmdline(struct tep_handle *tep, int pid) -{ - const struct tep_cmdline *comm; - struct tep_cmdline key; - - if (!pid) - return ""; - - if (!tep->cmdlines && cmdline_init(tep)) - return ""; - - key.pid = pid; - - comm = bsearch(&key, tep->cmdlines, tep->cmdline_count, - sizeof(*tep->cmdlines), cmdline_cmp); - - if (comm) - return comm->comm; - return "<...>"; -} - -/** - * tep_is_pid_registered - return if a pid has a cmdline registered - * @tep: a handle to the trace event parser context - * @pid: The pid to check if it has a cmdline registered with. - * - * Returns true if the pid has a cmdline mapped to it - * false otherwise. - */ -bool tep_is_pid_registered(struct tep_handle *tep, int pid) -{ - const struct tep_cmdline *comm; - struct tep_cmdline key; - - if (!pid) - return true; - - if (!tep->cmdlines && cmdline_init(tep)) - return false; - - key.pid = pid; - - comm = bsearch(&key, tep->cmdlines, tep->cmdline_count, - sizeof(*tep->cmdlines), cmdline_cmp); - - if (comm) - return true; - return false; -} - -/* - * If the command lines have been converted to an array, then - * we must add this pid. This is much slower than when cmdlines - * are added before the array is initialized. - */ -static int add_new_comm(struct tep_handle *tep, - const char *comm, int pid, bool override) -{ - struct tep_cmdline *cmdlines = tep->cmdlines; - struct tep_cmdline *cmdline; - struct tep_cmdline key; - char *new_comm; - int cnt; - - if (!pid) - return 0; - - /* avoid duplicates */ - key.pid = pid; - - cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count, - sizeof(*tep->cmdlines), cmdline_cmp); - if (cmdline) { - if (!override) { - errno = EEXIST; - return -1; - } - new_comm = strdup(comm); - if (!new_comm) { - errno = ENOMEM; - return -1; - } - free(cmdline->comm); - cmdline->comm = new_comm; - - return 0; - } - - cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + 1)); - if (!cmdlines) { - errno = ENOMEM; - return -1; - } - tep->cmdlines = cmdlines; - - key.comm = strdup(comm); - if (!key.comm) { - errno = ENOMEM; - return -1; - } - - if (!tep->cmdline_count) { - /* no entries yet */ - tep->cmdlines[0] = key; - tep->cmdline_count++; - return 0; - } - - /* Now find where we want to store the new cmdline */ - cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1, - sizeof(*tep->cmdlines), cmdline_slot_cmp); - - cnt = tep->cmdline_count; - if (cmdline) { - /* cmdline points to the one before the spot we want */ - cmdline++; - cnt -= cmdline - tep->cmdlines; - - } else { - /* The new entry is either before or after the list */ - if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) { - tep->cmdlines[tep->cmdline_count++] = key; - return 0; - } - cmdline = &tep->cmdlines[0]; - } - memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline))); - *cmdline = key; - - tep->cmdline_count++; - - return 0; -} - -static int _tep_register_comm(struct tep_handle *tep, - const char *comm, int pid, bool override) -{ - struct cmdline_list *item; - - if (tep->cmdlines) - return add_new_comm(tep, comm, pid, override); - - item = malloc(sizeof(*item)); - if (!item) - return -1; - - if (comm) - item->comm = strdup(comm); - else - item->comm = strdup("<...>"); - if (!item->comm) { - free(item); - return -1; - } - item->pid = pid; - item->next = tep->cmdlist; - - tep->cmdlist = item; - tep->cmdline_count++; - - return 0; -} - -/** - * tep_register_comm - register a pid / comm mapping - * @tep: a handle to the trace event parser context - * @comm: the command line to register - * @pid: the pid to map the command line to - * - * This adds a mapping to search for command line names with - * a given pid. The comm is duplicated. If a command with the same pid - * already exist, -1 is returned and errno is set to EEXIST - */ -int tep_register_comm(struct tep_handle *tep, const char *comm, int pid) -{ - return _tep_register_comm(tep, comm, pid, false); -} - -/** - * tep_override_comm - register a pid / comm mapping - * @tep: a handle to the trace event parser context - * @comm: the command line to register - * @pid: the pid to map the command line to - * - * This adds a mapping to search for command line names with - * a given pid. The comm is duplicated. If a command with the same pid - * already exist, the command string is udapted with the new one - */ -int tep_override_comm(struct tep_handle *tep, const char *comm, int pid) -{ - if (!tep->cmdlines && cmdline_init(tep)) { - errno = ENOMEM; - return -1; - } - return _tep_register_comm(tep, comm, pid, true); -} - -struct func_map { - unsigned long long addr; - char *func; - char *mod; -}; - -struct func_list { - struct func_list *next; - unsigned long long addr; - char *func; - char *mod; -}; - -static int func_cmp(const void *a, const void *b) -{ - const struct func_map *fa = a; - const struct func_map *fb = b; - - if (fa->addr < fb->addr) - return -1; - if (fa->addr > fb->addr) - return 1; - - return 0; -} - -/* - * We are searching for a record in between, not an exact - * match. - */ -static int func_bcmp(const void *a, const void *b) -{ - const struct func_map *fa = a; - const struct func_map *fb = b; - - if ((fa->addr == fb->addr) || - - (fa->addr > fb->addr && - fa->addr < (fb+1)->addr)) - return 0; - - if (fa->addr < fb->addr) - return -1; - - return 1; -} - -static int func_map_init(struct tep_handle *tep) -{ - struct func_list *funclist; - struct func_list *item; - struct func_map *func_map; - int i; - - func_map = malloc(sizeof(*func_map) * (tep->func_count + 1)); - if (!func_map) - return -1; - - funclist = tep->funclist; - - i = 0; - while (funclist) { - func_map[i].func = funclist->func; - func_map[i].addr = funclist->addr; - func_map[i].mod = funclist->mod; - i++; - item = funclist; - funclist = funclist->next; - free(item); - } - - qsort(func_map, tep->func_count, sizeof(*func_map), func_cmp); - - /* - * Add a special record at the end. - */ - func_map[tep->func_count].func = NULL; - func_map[tep->func_count].addr = 0; - func_map[tep->func_count].mod = NULL; - - tep->func_map = func_map; - tep->funclist = NULL; - - return 0; -} - -static struct func_map * -__find_func(struct tep_handle *tep, unsigned long long addr) -{ - struct func_map *func; - struct func_map key; - - if (!tep->func_map) - func_map_init(tep); - - key.addr = addr; - - func = bsearch(&key, tep->func_map, tep->func_count, - sizeof(*tep->func_map), func_bcmp); - - return func; -} - -struct func_resolver { - tep_func_resolver_t *func; - void *priv; - struct func_map map; -}; - -/** - * tep_set_function_resolver - set an alternative function resolver - * @tep: a handle to the trace event parser context - * @resolver: function to be used - * @priv: resolver function private state. - * - * Some tools may have already a way to resolve kernel functions, allow them to - * keep using it instead of duplicating all the entries inside tep->funclist. - */ -int tep_set_function_resolver(struct tep_handle *tep, - tep_func_resolver_t *func, void *priv) -{ - struct func_resolver *resolver = malloc(sizeof(*resolver)); - - if (resolver == NULL) - return -1; - - resolver->func = func; - resolver->priv = priv; - - free(tep->func_resolver); - tep->func_resolver = resolver; - - return 0; -} - -/** - * tep_reset_function_resolver - reset alternative function resolver - * @tep: a handle to the trace event parser context - * - * Stop using whatever alternative resolver was set, use the default - * one instead. - */ -void tep_reset_function_resolver(struct tep_handle *tep) -{ - free(tep->func_resolver); - tep->func_resolver = NULL; -} - -static struct func_map * -find_func(struct tep_handle *tep, unsigned long long addr) -{ - struct func_map *map; - - if (!tep->func_resolver) - return __find_func(tep, addr); - - map = &tep->func_resolver->map; - map->mod = NULL; - map->addr = addr; - map->func = tep->func_resolver->func(tep->func_resolver->priv, - &map->addr, &map->mod); - if (map->func == NULL) - return NULL; - - return map; -} - -/** - * tep_find_function - find a function by a given address - * @tep: a handle to the trace event parser context - * @addr: the address to find the function with - * - * Returns a pointer to the function stored that has the given - * address. Note, the address does not have to be exact, it - * will select the function that would contain the address. - */ -const char *tep_find_function(struct tep_handle *tep, unsigned long long addr) -{ - struct func_map *map; - - map = find_func(tep, addr); - if (!map) - return NULL; - - return map->func; -} - -/** - * tep_find_function_address - find a function address by a given address - * @tep: a handle to the trace event parser context - * @addr: the address to find the function with - * - * Returns the address the function starts at. This can be used in - * conjunction with tep_find_function to print both the function - * name and the function offset. - */ -unsigned long long -tep_find_function_address(struct tep_handle *tep, unsigned long long addr) -{ - struct func_map *map; - - map = find_func(tep, addr); - if (!map) - return 0; - - return map->addr; -} - -/** - * tep_register_function - register a function with a given address - * @tep: a handle to the trace event parser context - * @function: the function name to register - * @addr: the address the function starts at - * @mod: the kernel module the function may be in (NULL for none) - * - * This registers a function name with an address and module. - * The @func passed in is duplicated. - */ -int tep_register_function(struct tep_handle *tep, char *func, - unsigned long long addr, char *mod) -{ - struct func_list *item = malloc(sizeof(*item)); - - if (!item) - return -1; - - item->next = tep->funclist; - item->func = strdup(func); - if (!item->func) - goto out_free; - - if (mod) { - item->mod = strdup(mod); - if (!item->mod) - goto out_free_func; - } else - item->mod = NULL; - item->addr = addr; - - tep->funclist = item; - tep->func_count++; - - return 0; - -out_free_func: - free(item->func); - item->func = NULL; -out_free: - free(item); - errno = ENOMEM; - return -1; -} - -/** - * tep_print_funcs - print out the stored functions - * @tep: a handle to the trace event parser context - * - * This prints out the stored functions. - */ -void tep_print_funcs(struct tep_handle *tep) -{ - int i; - - if (!tep->func_map) - func_map_init(tep); - - for (i = 0; i < (int)tep->func_count; i++) { - printf("%016llx %s", - tep->func_map[i].addr, - tep->func_map[i].func); - if (tep->func_map[i].mod) - printf(" [%s]\n", tep->func_map[i].mod); - else - printf("\n"); - } -} - -struct printk_map { - unsigned long long addr; - char *printk; -}; - -struct printk_list { - struct printk_list *next; - unsigned long long addr; - char *printk; -}; - -static int printk_cmp(const void *a, const void *b) -{ - const struct printk_map *pa = a; - const struct printk_map *pb = b; - - if (pa->addr < pb->addr) - return -1; - if (pa->addr > pb->addr) - return 1; - - return 0; -} - -static int printk_map_init(struct tep_handle *tep) -{ - struct printk_list *printklist; - struct printk_list *item; - struct printk_map *printk_map; - int i; - - printk_map = malloc(sizeof(*printk_map) * (tep->printk_count + 1)); - if (!printk_map) - return -1; - - printklist = tep->printklist; - - i = 0; - while (printklist) { - printk_map[i].printk = printklist->printk; - printk_map[i].addr = printklist->addr; - i++; - item = printklist; - printklist = printklist->next; - free(item); - } - - qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp); - - tep->printk_map = printk_map; - tep->printklist = NULL; - - return 0; -} - -static struct printk_map * -find_printk(struct tep_handle *tep, unsigned long long addr) -{ - struct printk_map *printk; - struct printk_map key; - - if (!tep->printk_map && printk_map_init(tep)) - return NULL; - - key.addr = addr; - - printk = bsearch(&key, tep->printk_map, tep->printk_count, - sizeof(*tep->printk_map), printk_cmp); - - return printk; -} - -/** - * tep_register_print_string - register a string by its address - * @tep: a handle to the trace event parser context - * @fmt: the string format to register - * @addr: the address the string was located at - * - * This registers a string by the address it was stored in the kernel. - * The @fmt passed in is duplicated. - */ -int tep_register_print_string(struct tep_handle *tep, const char *fmt, - unsigned long long addr) -{ - struct printk_list *item = malloc(sizeof(*item)); - char *p; - - if (!item) - return -1; - - item->next = tep->printklist; - item->addr = addr; - - /* Strip off quotes and '\n' from the end */ - if (fmt[0] == '"') - fmt++; - item->printk = strdup(fmt); - if (!item->printk) - goto out_free; - - p = item->printk + strlen(item->printk) - 1; - if (*p == '"') - *p = 0; - - p -= 2; - if (strcmp(p, "\\n") == 0) - *p = 0; - - tep->printklist = item; - tep->printk_count++; - - return 0; - -out_free: - free(item); - errno = ENOMEM; - return -1; -} - -/** - * tep_print_printk - print out the stored strings - * @tep: a handle to the trace event parser context - * - * This prints the string formats that were stored. - */ -void tep_print_printk(struct tep_handle *tep) -{ - int i; - - if (!tep->printk_map) - printk_map_init(tep); - - for (i = 0; i < (int)tep->printk_count; i++) { - printf("%016llx %s\n", - tep->printk_map[i].addr, - tep->printk_map[i].printk); - } -} - -static struct tep_event *alloc_event(void) -{ - return calloc(1, sizeof(struct tep_event)); -} - -static int add_event(struct tep_handle *tep, struct tep_event *event) -{ - int i; - struct tep_event **events = realloc(tep->events, sizeof(event) * - (tep->nr_events + 1)); - if (!events) - return -1; - - tep->events = events; - - for (i = 0; i < tep->nr_events; i++) { - if (tep->events[i]->id > event->id) - break; - } - if (i < tep->nr_events) - memmove(&tep->events[i + 1], - &tep->events[i], - sizeof(event) * (tep->nr_events - i)); - - tep->events[i] = event; - tep->nr_events++; - - event->tep = tep; - - return 0; -} - -static int event_item_type(enum tep_event_type type) -{ - switch (type) { - case TEP_EVENT_ITEM ... TEP_EVENT_SQUOTE: - return 1; - case TEP_EVENT_ERROR ... TEP_EVENT_DELIM: - default: - return 0; - } -} - -static void free_flag_sym(struct tep_print_flag_sym *fsym) -{ - struct tep_print_flag_sym *next; - - while (fsym) { - next = fsym->next; - free(fsym->value); - free(fsym->str); - free(fsym); - fsym = next; - } -} - -static void free_arg(struct tep_print_arg *arg) -{ - struct tep_print_arg *farg; - - if (!arg) - return; - - switch (arg->type) { - case TEP_PRINT_ATOM: - free(arg->atom.atom); - break; - case TEP_PRINT_FIELD: - free(arg->field.name); - break; - case TEP_PRINT_FLAGS: - free_arg(arg->flags.field); - free(arg->flags.delim); - free_flag_sym(arg->flags.flags); - break; - case TEP_PRINT_SYMBOL: - free_arg(arg->symbol.field); - free_flag_sym(arg->symbol.symbols); - break; - case TEP_PRINT_HEX: - case TEP_PRINT_HEX_STR: - free_arg(arg->hex.field); - free_arg(arg->hex.size); - break; - case TEP_PRINT_INT_ARRAY: - free_arg(arg->int_array.field); - free_arg(arg->int_array.count); - free_arg(arg->int_array.el_size); - break; - case TEP_PRINT_TYPE: - free(arg->typecast.type); - free_arg(arg->typecast.item); - break; - case TEP_PRINT_STRING: - case TEP_PRINT_BSTRING: - free(arg->string.string); - break; - case TEP_PRINT_BITMASK: - free(arg->bitmask.bitmask); - break; - case TEP_PRINT_DYNAMIC_ARRAY: - case TEP_PRINT_DYNAMIC_ARRAY_LEN: - free(arg->dynarray.index); - break; - case TEP_PRINT_OP: - free(arg->op.op); - free_arg(arg->op.left); - free_arg(arg->op.right); - break; - case TEP_PRINT_FUNC: - while (arg->func.args) { - farg = arg->func.args; - arg->func.args = farg->next; - free_arg(farg); - } - break; - - case TEP_PRINT_NULL: - default: - break; - } - - free(arg); -} - -static enum tep_event_type get_type(int ch) -{ - if (ch == '\n') - return TEP_EVENT_NEWLINE; - if (isspace(ch)) - return TEP_EVENT_SPACE; - if (isalnum(ch) || ch == '_') - return TEP_EVENT_ITEM; - if (ch == '\'') - return TEP_EVENT_SQUOTE; - if (ch == '"') - return TEP_EVENT_DQUOTE; - if (!isprint(ch)) - return TEP_EVENT_NONE; - if (ch == '(' || ch == ')' || ch == ',') - return TEP_EVENT_DELIM; - - return TEP_EVENT_OP; -} - -static int __read_char(void) -{ - if (input_buf_ptr >= input_buf_siz) - return -1; - - return input_buf[input_buf_ptr++]; -} - -/** - * peek_char - peek at the next character that will be read - * - * Returns the next character read, or -1 if end of buffer. - */ -__hidden int peek_char(void) -{ - if (input_buf_ptr >= input_buf_siz) - return -1; - - return input_buf[input_buf_ptr]; -} - -static int extend_token(char **tok, char *buf, int size) -{ - char *newtok = realloc(*tok, size); - - if (!newtok) { - free(*tok); - *tok = NULL; - return -1; - } - - if (!*tok) - strcpy(newtok, buf); - else - strcat(newtok, buf); - *tok = newtok; - - return 0; -} - -static enum tep_event_type force_token(const char *str, char **tok); - -static enum tep_event_type __read_token(char **tok) -{ - char buf[BUFSIZ]; - int ch, last_ch, quote_ch, next_ch; - int i = 0; - int tok_size = 0; - enum tep_event_type type; - - *tok = NULL; - - - ch = __read_char(); - if (ch < 0) - return TEP_EVENT_NONE; - - type = get_type(ch); - if (type == TEP_EVENT_NONE) - return type; - - buf[i++] = ch; - - switch (type) { - case TEP_EVENT_NEWLINE: - case TEP_EVENT_DELIM: - if (asprintf(tok, "%c", ch) < 0) - return TEP_EVENT_ERROR; - - return type; - - case TEP_EVENT_OP: - switch (ch) { - case '-': - next_ch = peek_char(); - if (next_ch == '>') { - buf[i++] = __read_char(); - break; - } - /* fall through */ - case '+': - case '|': - case '&': - case '>': - case '<': - last_ch = ch; - ch = peek_char(); - if (ch != last_ch) - goto test_equal; - buf[i++] = __read_char(); - switch (last_ch) { - case '>': - case '<': - goto test_equal; - default: - break; - } - break; - case '!': - case '=': - goto test_equal; - default: /* what should we do instead? */ - break; - } - buf[i] = 0; - *tok = strdup(buf); - return type; - - test_equal: - ch = peek_char(); - if (ch == '=') - buf[i++] = __read_char(); - goto out; - - case TEP_EVENT_DQUOTE: - case TEP_EVENT_SQUOTE: - /* don't keep quotes */ - i--; - quote_ch = ch; - last_ch = 0; - concat: - do { - if (i == (BUFSIZ - 1)) { - buf[i] = 0; - tok_size += BUFSIZ; - - if (extend_token(tok, buf, tok_size) < 0) - return TEP_EVENT_NONE; - i = 0; - } - last_ch = ch; - ch = __read_char(); - buf[i++] = ch; - /* the '\' '\' will cancel itself */ - if (ch == '\\' && last_ch == '\\') - last_ch = 0; - } while (ch != quote_ch || last_ch == '\\'); - /* remove the last quote */ - i--; - - /* - * For strings (double quotes) check the next token. - * If it is another string, concatinate the two. - */ - if (type == TEP_EVENT_DQUOTE) { - unsigned long long save_input_buf_ptr = input_buf_ptr; - - do { - ch = __read_char(); - } while (isspace(ch)); - if (ch == '"') - goto concat; - input_buf_ptr = save_input_buf_ptr; - } - - goto out; - - case TEP_EVENT_ERROR ... TEP_EVENT_SPACE: - case TEP_EVENT_ITEM: - default: - break; - } - - while (get_type(peek_char()) == type) { - if (i == (BUFSIZ - 1)) { - buf[i] = 0; - tok_size += BUFSIZ; - - if (extend_token(tok, buf, tok_size) < 0) - return TEP_EVENT_NONE; - i = 0; - } - ch = __read_char(); - buf[i++] = ch; - } - - out: - buf[i] = 0; - if (extend_token(tok, buf, tok_size + i + 1) < 0) - return TEP_EVENT_NONE; - - if (type == TEP_EVENT_ITEM) { - /* - * Older versions of the kernel has a bug that - * creates invalid symbols and will break the mac80211 - * parsing. This is a work around to that bug. - * - * See Linux kernel commit: - * 811cb50baf63461ce0bdb234927046131fc7fa8b - */ - if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { - free(*tok); - *tok = NULL; - return force_token("\"%s\" ", tok); - } else if (strcmp(*tok, "STA_PR_FMT") == 0) { - free(*tok); - *tok = NULL; - return force_token("\" sta:%pM\" ", tok); - } else if (strcmp(*tok, "VIF_PR_FMT") == 0) { - free(*tok); - *tok = NULL; - return force_token("\" vif:%p(%d)\" ", tok); - } - } - - return type; -} - -static enum tep_event_type force_token(const char *str, char **tok) -{ - const char *save_input_buf; - unsigned long long save_input_buf_ptr; - unsigned long long save_input_buf_siz; - enum tep_event_type type; - - /* save off the current input pointers */ - save_input_buf = input_buf; - save_input_buf_ptr = input_buf_ptr; - save_input_buf_siz = input_buf_siz; - - init_input_buf(str, strlen(str)); - - type = __read_token(tok); - - /* reset back to original token */ - input_buf = save_input_buf; - input_buf_ptr = save_input_buf_ptr; - input_buf_siz = save_input_buf_siz; - - return type; -} - -/** - * free_token - free a token returned by tep_read_token - * @token: the token to free - */ -__hidden void free_token(char *tok) -{ - if (tok) - free(tok); -} - -/** - * read_token - access to utilities to use the tep parser - * @tok: The token to return - * - * This will parse tokens from the string given by - * tep_init_data(). - * - * Returns the token type. - */ -__hidden enum tep_event_type read_token(char **tok) -{ - enum tep_event_type type; - - for (;;) { - type = __read_token(tok); - if (type != TEP_EVENT_SPACE) - return type; - - free_token(*tok); - } - - /* not reached */ - *tok = NULL; - return TEP_EVENT_NONE; -} - -/* no newline */ -static enum tep_event_type read_token_item(char **tok) -{ - enum tep_event_type type; - - for (;;) { - type = __read_token(tok); - if (type != TEP_EVENT_SPACE && type != TEP_EVENT_NEWLINE) - return type; - free_token(*tok); - *tok = NULL; - } - - /* not reached */ - *tok = NULL; - return TEP_EVENT_NONE; -} - -static int test_type(enum tep_event_type type, enum tep_event_type expect) -{ - if (type != expect) { - do_warning("Error: expected type %d but read %d", - expect, type); - return -1; - } - return 0; -} - -static int test_type_token(enum tep_event_type type, const char *token, - enum tep_event_type expect, const char *expect_tok) -{ - if (type != expect) { - do_warning("Error: expected type %d but read %d", - expect, type); - return -1; - } - - if (strcmp(token, expect_tok) != 0) { - do_warning("Error: expected '%s' but read '%s'", - expect_tok, token); - return -1; - } - return 0; -} - -static int __read_expect_type(enum tep_event_type expect, char **tok, int newline_ok) -{ - enum tep_event_type type; - - if (newline_ok) - type = read_token(tok); - else - type = read_token_item(tok); - return test_type(type, expect); -} - -static int read_expect_type(enum tep_event_type expect, char **tok) -{ - return __read_expect_type(expect, tok, 1); -} - -static int __read_expected(enum tep_event_type expect, const char *str, - int newline_ok) -{ - enum tep_event_type type; - char *token; - int ret; - - if (newline_ok) - type = read_token(&token); - else - type = read_token_item(&token); - - ret = test_type_token(type, token, expect, str); - - free_token(token); - - return ret; -} - -static int read_expected(enum tep_event_type expect, const char *str) -{ - return __read_expected(expect, str, 1); -} - -static int read_expected_item(enum tep_event_type expect, const char *str) -{ - return __read_expected(expect, str, 0); -} - -static char *event_read_name(void) -{ - char *token; - - if (read_expected(TEP_EVENT_ITEM, "name") < 0) - return NULL; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - return NULL; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - - return token; - - fail: - free_token(token); - return NULL; -} - -static int event_read_id(void) -{ - char *token; - int id; - - if (read_expected_item(TEP_EVENT_ITEM, "ID") < 0) - return -1; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - return -1; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - - id = strtoul(token, NULL, 0); - free_token(token); - return id; - - fail: - free_token(token); - return -1; -} - -static int field_is_string(struct tep_format_field *field) -{ - if ((field->flags & TEP_FIELD_IS_ARRAY) && - (strstr(field->type, "char") || strstr(field->type, "u8") || - strstr(field->type, "s8"))) - return 1; - - return 0; -} - -static int field_is_dynamic(struct tep_format_field *field) -{ - if (strncmp(field->type, "__data_loc", 10) == 0) - return 1; - - return 0; -} - -static int field_is_relative_dynamic(struct tep_format_field *field) -{ - if (strncmp(field->type, "__rel_loc", 9) == 0) - return 1; - - return 0; -} - -static int field_is_long(struct tep_format_field *field) -{ - /* includes long long */ - if (strstr(field->type, "long")) - return 1; - - return 0; -} - -static unsigned int type_size(const char *name) -{ - /* This covers all TEP_FIELD_IS_STRING types. */ - static struct { - const char *type; - unsigned int size; - } table[] = { - { "u8", 1 }, - { "u16", 2 }, - { "u32", 4 }, - { "u64", 8 }, - { "s8", 1 }, - { "s16", 2 }, - { "s32", 4 }, - { "s64", 8 }, - { "char", 1 }, - { }, - }; - int i; - - for (i = 0; table[i].type; i++) { - if (!strcmp(table[i].type, name)) - return table[i].size; - } - - return 0; -} - -static int append(char **buf, const char *delim, const char *str) -{ - char *new_buf; - - new_buf = realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1); - if (!new_buf) - return -1; - strcat(new_buf, delim); - strcat(new_buf, str); - *buf = new_buf; - return 0; -} - -static int event_read_fields(struct tep_event *event, struct tep_format_field **fields) -{ - struct tep_format_field *field = NULL; - enum tep_event_type type; - char *token; - char *last_token; - char *delim = " "; - int count = 0; - int ret; - - do { - unsigned int size_dynamic = 0; - - type = read_token(&token); - if (type == TEP_EVENT_NEWLINE) { - free_token(token); - return count; - } - - count++; - - if (test_type_token(type, token, TEP_EVENT_ITEM, "field")) - goto fail; - free_token(token); - - type = read_token(&token); - /* - * The ftrace fields may still use the "special" name. - * Just ignore it. - */ - if (event->flags & TEP_EVENT_FL_ISFTRACE && - type == TEP_EVENT_ITEM && strcmp(token, "special") == 0) { - free_token(token); - type = read_token(&token); - } - - if (test_type_token(type, token, TEP_EVENT_OP, ":") < 0) - goto fail; - - free_token(token); - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - - last_token = token; - - field = calloc(1, sizeof(*field)); - if (!field) - goto fail; - - field->event = event; - - /* read the rest of the type */ - for (;;) { - type = read_token(&token); - if (type == TEP_EVENT_ITEM || - (type == TEP_EVENT_OP && strcmp(token, "*") == 0) || - /* - * Some of the ftrace fields are broken and have - * an illegal "." in them. - */ - (event->flags & TEP_EVENT_FL_ISFTRACE && - type == TEP_EVENT_OP && strcmp(token, ".") == 0)) { - - if (strcmp(token, "*") == 0) - field->flags |= TEP_FIELD_IS_POINTER; - - if (field->type) { - ret = append(&field->type, delim, last_token); - free(last_token); - if (ret < 0) - goto fail; - } else - field->type = last_token; - last_token = token; - delim = " "; - continue; - } - - /* Handle __attribute__((user)) */ - if ((type == TEP_EVENT_DELIM) && - strcmp("__attribute__", last_token) == 0 && - token[0] == '(') { - int depth = 1; - int ret; - - ret = append(&field->type, " ", last_token); - ret |= append(&field->type, "", "("); - if (ret < 0) - goto fail; - - delim = " "; - while ((type = read_token(&token)) != TEP_EVENT_NONE) { - if (type == TEP_EVENT_DELIM) { - if (token[0] == '(') - depth++; - else if (token[0] == ')') - depth--; - if (!depth) - break; - ret = append(&field->type, "", token); - delim = ""; - } else { - ret = append(&field->type, delim, token); - delim = " "; - } - if (ret < 0) - goto fail; - free(last_token); - last_token = token; - } - continue; - } - break; - } - - if (!field->type) { - do_warning_event(event, "%s: no type found", __func__); - goto fail; - } - field->name = field->alias = last_token; - - if (test_type(type, TEP_EVENT_OP)) - goto fail; - - if (strcmp(token, "[") == 0) { - enum tep_event_type last_type = type; - char *brackets = token; - - field->flags |= TEP_FIELD_IS_ARRAY; - - type = read_token(&token); - - if (type == TEP_EVENT_ITEM) - field->arraylen = strtoul(token, NULL, 0); - else - field->arraylen = 0; - - while (strcmp(token, "]") != 0) { - const char *delim; - - if (last_type == TEP_EVENT_ITEM && - type == TEP_EVENT_ITEM) - delim = " "; - else - delim = ""; - - last_type = type; - - ret = append(&brackets, delim, token); - if (ret < 0) { - free(brackets); - goto fail; - } - /* We only care about the last token */ - field->arraylen = strtoul(token, NULL, 0); - free_token(token); - type = read_token(&token); - if (type == TEP_EVENT_NONE) { - free(brackets); - do_warning_event(event, "failed to find token"); - goto fail; - } - } - - free_token(token); - - ret = append(&brackets, "", "]"); - if (ret < 0) { - free(brackets); - goto fail; - } - - /* add brackets to type */ - - type = read_token(&token); - /* - * If the next token is not an OP, then it is of - * the format: type [] item; - */ - if (type == TEP_EVENT_ITEM) { - ret = append(&field->type, " ", field->name); - if (ret < 0) { - free(brackets); - goto fail; - } - ret = append(&field->type, "", brackets); - - size_dynamic = type_size(field->name); - free_token(field->name); - field->name = field->alias = token; - type = read_token(&token); - } else { - ret = append(&field->type, "", brackets); - if (ret < 0) { - free(brackets); - goto fail; - } - } - free(brackets); - } - - if (field_is_string(field)) - field->flags |= TEP_FIELD_IS_STRING; - if (field_is_dynamic(field)) - field->flags |= TEP_FIELD_IS_DYNAMIC; - if (field_is_relative_dynamic(field)) - field->flags |= TEP_FIELD_IS_DYNAMIC | TEP_FIELD_IS_RELATIVE; - if (field_is_long(field)) - field->flags |= TEP_FIELD_IS_LONG; - - if (test_type_token(type, token, TEP_EVENT_OP, ";")) - goto fail; - free_token(token); - - if (read_expected(TEP_EVENT_ITEM, "offset") < 0) - goto fail_expect; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - goto fail_expect; - - if (read_expect_type(TEP_EVENT_ITEM, &token)) - goto fail; - field->offset = strtoul(token, NULL, 0); - free_token(token); - - if (read_expected(TEP_EVENT_OP, ";") < 0) - goto fail_expect; - - if (read_expected(TEP_EVENT_ITEM, "size") < 0) - goto fail_expect; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - goto fail_expect; - - if (read_expect_type(TEP_EVENT_ITEM, &token)) - goto fail; - field->size = strtoul(token, NULL, 0); - free_token(token); - - if (read_expected(TEP_EVENT_OP, ";") < 0) - goto fail_expect; - - type = read_token(&token); - if (type != TEP_EVENT_NEWLINE) { - /* newer versions of the kernel have a "signed" type */ - if (test_type_token(type, token, TEP_EVENT_ITEM, "signed")) - goto fail; - - free_token(token); - - if (read_expected(TEP_EVENT_OP, ":") < 0) - goto fail_expect; - - if (read_expect_type(TEP_EVENT_ITEM, &token)) - goto fail; - - if (strtoul(token, NULL, 0)) - field->flags |= TEP_FIELD_IS_SIGNED; - - free_token(token); - if (read_expected(TEP_EVENT_OP, ";") < 0) - goto fail_expect; - - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) - goto fail; - } - - free_token(token); - - if (field->flags & TEP_FIELD_IS_ARRAY) { - if (field->arraylen) - field->elementsize = field->size / field->arraylen; - else if (field->flags & TEP_FIELD_IS_DYNAMIC) - field->elementsize = size_dynamic; - else if (field->flags & TEP_FIELD_IS_STRING) - field->elementsize = 1; - else if (field->flags & TEP_FIELD_IS_LONG) - field->elementsize = event->tep ? - event->tep->long_size : - sizeof(long); - } else - field->elementsize = field->size; - - *fields = field; - fields = &field->next; - - } while (1); - - return 0; - -fail: - free_token(token); -fail_expect: - if (field) { - free(field->type); - free(field->name); - free(field); - } - return -1; -} - -static int event_read_format(struct tep_event *event) -{ - char *token; - int ret; - - if (read_expected_item(TEP_EVENT_ITEM, "format") < 0) - return -1; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - return -1; - - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) - goto fail; - free_token(token); - - ret = event_read_fields(event, &event->format.common_fields); - if (ret < 0) - return ret; - event->format.nr_common = ret; - - ret = event_read_fields(event, &event->format.fields); - if (ret < 0) - return ret; - event->format.nr_fields = ret; - - return 0; - - fail: - free_token(token); - return -1; -} - -static enum tep_event_type -process_arg_token(struct tep_event *event, struct tep_print_arg *arg, - char **tok, enum tep_event_type type); - -static enum tep_event_type -process_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - enum tep_event_type type; - char *token; - - type = read_token(&token); - *tok = token; - - return process_arg_token(event, arg, tok, type); -} - -static enum tep_event_type -process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok); - -/* - * For __print_symbolic() and __print_flags, we need to completely - * evaluate the first argument, which defines what to print next. - */ -static enum tep_event_type -process_field_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - enum tep_event_type type; - - type = process_arg(event, arg, tok); - - while (type == TEP_EVENT_OP) { - type = process_op(event, arg, tok); - } - - return type; -} - -static enum tep_event_type -process_cond(struct tep_event *event, struct tep_print_arg *top, char **tok) -{ - struct tep_print_arg *arg, *left, *right; - enum tep_event_type type; - char *token = NULL; - - arg = alloc_arg(); - left = alloc_arg(); - right = alloc_arg(); - - if (!arg || !left || !right) { - do_warning_event(event, "%s: not enough memory!", __func__); - /* arg will be freed at out_free */ - free_arg(left); - free_arg(right); - goto out_free; - } - - arg->type = TEP_PRINT_OP; - arg->op.left = left; - arg->op.right = right; - - *tok = NULL; - type = process_arg(event, left, &token); - - again: - if (type == TEP_EVENT_ERROR) - goto out_free; - - /* Handle other operations in the arguments */ - if (type == TEP_EVENT_OP && strcmp(token, ":") != 0) { - type = process_op(event, left, &token); - goto again; - } - - if (test_type_token(type, token, TEP_EVENT_OP, ":")) - goto out_free; - - arg->op.op = token; - - type = process_arg(event, right, &token); - - top->op.right = arg; - - *tok = token; - return type; - -out_free: - /* Top may point to itself */ - top->op.right = NULL; - free_token(token); - free_arg(arg); - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_array(struct tep_event *event, struct tep_print_arg *top, char **tok) -{ - struct tep_print_arg *arg; - enum tep_event_type type; - char *token = NULL; - - arg = alloc_arg(); - if (!arg) { - do_warning_event(event, "%s: not enough memory!", __func__); - /* '*tok' is set to top->op.op. No need to free. */ - *tok = NULL; - return TEP_EVENT_ERROR; - } - - *tok = NULL; - type = process_arg(event, arg, &token); - if (test_type_token(type, token, TEP_EVENT_OP, "]")) - goto out_free; - - top->op.right = arg; - - free_token(token); - type = read_token_item(&token); - *tok = token; - - return type; - -out_free: - free_token(token); - free_arg(arg); - return TEP_EVENT_ERROR; -} - -static int get_op_prio(char *op) -{ - if (!op[1]) { - switch (op[0]) { - case '~': - case '!': - return 4; - case '*': - case '/': - case '%': - return 6; - case '+': - case '-': - return 7; - /* '>>' and '<<' are 8 */ - case '<': - case '>': - return 9; - /* '==' and '!=' are 10 */ - case '&': - return 11; - case '^': - return 12; - case '|': - return 13; - case '?': - return 16; - default: - do_warning("unknown op '%c'", op[0]); - return -1; - } - } else { - if (strcmp(op, "++") == 0 || - strcmp(op, "--") == 0) { - return 3; - } else if (strcmp(op, ">>") == 0 || - strcmp(op, "<<") == 0) { - return 8; - } else if (strcmp(op, ">=") == 0 || - strcmp(op, "<=") == 0) { - return 9; - } else if (strcmp(op, "==") == 0 || - strcmp(op, "!=") == 0) { - return 10; - } else if (strcmp(op, "&&") == 0) { - return 14; - } else if (strcmp(op, "||") == 0) { - return 15; - } else { - do_warning("unknown op '%s'", op); - return -1; - } - } -} - -static int set_op_prio(struct tep_print_arg *arg) -{ - - /* single ops are the greatest */ - if (!arg->op.left || arg->op.left->type == TEP_PRINT_NULL) - arg->op.prio = 0; - else - arg->op.prio = get_op_prio(arg->op.op); - - return arg->op.prio; -} - -/* Note, *tok does not get freed, but will most likely be saved */ -static enum tep_event_type -process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - struct tep_print_arg *left, *right = NULL; - enum tep_event_type type; - char *token; - - /* the op is passed in via tok */ - token = *tok; - - if (arg->type == TEP_PRINT_OP && !arg->op.left) { - /* handle single op */ - if (token[1]) { - do_warning_event(event, "bad op token %s", token); - goto out_free; - } - switch (token[0]) { - case '~': - case '!': - case '+': - case '-': - break; - default: - do_warning_event(event, "bad op token %s", token); - goto out_free; - - } - - /* make an empty left */ - left = alloc_arg(); - if (!left) - goto out_warn_free; - - left->type = TEP_PRINT_NULL; - arg->op.left = left; - - right = alloc_arg(); - if (!right) - goto out_warn_free; - - arg->op.right = right; - - /* do not free the token, it belongs to an op */ - *tok = NULL; - type = process_arg(event, right, tok); - - } else if (strcmp(token, "?") == 0) { - - left = alloc_arg(); - if (!left) - goto out_warn_free; - - /* copy the top arg to the left */ - *left = *arg; - - arg->type = TEP_PRINT_OP; - arg->op.op = token; - arg->op.left = left; - arg->op.prio = 0; - - /* it will set arg->op.right */ - type = process_cond(event, arg, tok); - - } else if (strcmp(token, ">>") == 0 || - strcmp(token, "<<") == 0 || - strcmp(token, "&") == 0 || - strcmp(token, "|") == 0 || - strcmp(token, "&&") == 0 || - strcmp(token, "||") == 0 || - strcmp(token, "-") == 0 || - strcmp(token, "+") == 0 || - strcmp(token, "*") == 0 || - strcmp(token, "^") == 0 || - strcmp(token, "/") == 0 || - strcmp(token, "%") == 0 || - strcmp(token, "<") == 0 || - strcmp(token, ">") == 0 || - strcmp(token, "<=") == 0 || - strcmp(token, ">=") == 0 || - strcmp(token, "==") == 0 || - strcmp(token, "!=") == 0) { - - left = alloc_arg(); - if (!left) - goto out_warn_free; - - /* copy the top arg to the left */ - *left = *arg; - - arg->type = TEP_PRINT_OP; - arg->op.op = token; - arg->op.left = left; - arg->op.right = NULL; - - if (set_op_prio(arg) == -1) { - event->flags |= TEP_EVENT_FL_FAILED; - /* arg->op.op (= token) will be freed at out_free */ - arg->op.op = NULL; - goto out_free; - } - - type = read_token_item(&token); - *tok = token; - - /* could just be a type pointer */ - if ((strcmp(arg->op.op, "*") == 0) && - type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) { - int ret; - - if (left->type != TEP_PRINT_ATOM) { - do_warning_event(event, "bad pointer type"); - goto out_free; - } - ret = append(&left->atom.atom, " ", "*"); - if (ret < 0) - goto out_warn_free; - - free(arg->op.op); - *arg = *left; - free(left); - - return type; - } - - right = alloc_arg(); - if (!right) - goto out_warn_free; - - type = process_arg_token(event, right, tok, type); - if (type == TEP_EVENT_ERROR) { - free_arg(right); - /* token was freed in process_arg_token() via *tok */ - token = NULL; - goto out_free; - } - - if (right->type == TEP_PRINT_OP && - get_op_prio(arg->op.op) < get_op_prio(right->op.op)) { - struct tep_print_arg tmp; - - /* rotate ops according to the priority */ - arg->op.right = right->op.left; - - tmp = *arg; - *arg = *right; - *right = tmp; - - arg->op.left = right; - } else { - arg->op.right = right; - } - - } else if (strcmp(token, "[") == 0) { - - left = alloc_arg(); - if (!left) - goto out_warn_free; - - *left = *arg; - - arg->type = TEP_PRINT_OP; - arg->op.op = token; - arg->op.left = left; - - arg->op.prio = 0; - - /* it will set arg->op.right */ - type = process_array(event, arg, tok); - - } else { - do_warning_event(event, "unknown op '%s'", token); - event->flags |= TEP_EVENT_FL_FAILED; - /* the arg is now the left side */ - goto out_free; - } - - if (type == TEP_EVENT_OP && strcmp(*tok, ":") != 0) { - int prio; - - /* higher prios need to be closer to the root */ - prio = get_op_prio(*tok); - - if (prio > arg->op.prio) - return process_op(event, arg, tok); - - return process_op(event, right, tok); - } - - return type; - -out_warn_free: - do_warning_event(event, "%s: not enough memory!", __func__); -out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_entry(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, - char **tok) -{ - enum tep_event_type type; - char *field; - char *token; - - if (read_expected(TEP_EVENT_OP, "->") < 0) - goto out_err; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - field = token; - - arg->type = TEP_PRINT_FIELD; - arg->field.name = field; - - if (is_flag_field) { - arg->field.field = tep_find_any_field(event, arg->field.name); - arg->field.field->flags |= TEP_FIELD_IS_FLAG; - is_flag_field = 0; - } else if (is_symbolic_field) { - arg->field.field = tep_find_any_field(event, arg->field.name); - arg->field.field->flags |= TEP_FIELD_IS_SYMBOLIC; - is_symbolic_field = 0; - } - - type = read_token(&token); - *tok = token; - - return type; - - out_free: - free_token(token); - out_err: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static int alloc_and_process_delim(struct tep_event *event, char *next_token, - struct tep_print_arg **print_arg) -{ - struct tep_print_arg *field; - enum tep_event_type type; - char *token; - int ret = 0; - - field = alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - errno = ENOMEM; - return -1; - } - - type = process_arg(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) { - errno = EINVAL; - ret = -1; - free_arg(field); - goto out_free_token; - } - - *print_arg = field; - -out_free_token: - free_token(token); - - return ret; -} - -static char *arg_eval (struct tep_print_arg *arg); - -static unsigned long long -eval_type_str(unsigned long long val, const char *type, int pointer) -{ - int sign = 0; - char *ref; - int len; - - len = strlen(type); - - if (pointer) { - - if (type[len-1] != '*') { - do_warning("pointer expected with non pointer type"); - return val; - } - - ref = malloc(len); - if (!ref) { - do_warning("%s: not enough memory!", __func__); - return val; - } - memcpy(ref, type, len); - - /* chop off the " *" */ - ref[len - 2] = 0; - - val = eval_type_str(val, ref, 0); - free(ref); - return val; - } - - /* check if this is a pointer */ - if (type[len - 1] == '*') - return val; - - /* Try to figure out the arg size*/ - if (strncmp(type, "struct", 6) == 0) - /* all bets off */ - return val; - - if (strcmp(type, "u8") == 0) - return val & 0xff; - - if (strcmp(type, "u16") == 0) - return val & 0xffff; - - if (strcmp(type, "u32") == 0) - return val & 0xffffffff; - - if (strcmp(type, "u64") == 0 || - strcmp(type, "s64") == 0) - return val; - - if (strcmp(type, "s8") == 0) - return (unsigned long long)(char)val & 0xff; - - if (strcmp(type, "s16") == 0) - return (unsigned long long)(short)val & 0xffff; - - if (strcmp(type, "s32") == 0) - return (unsigned long long)(int)val & 0xffffffff; - - if (strncmp(type, "unsigned ", 9) == 0) { - sign = 0; - type += 9; - } - - if (strcmp(type, "char") == 0) { - if (sign) - return (unsigned long long)(char)val & 0xff; - else - return val & 0xff; - } - - if (strcmp(type, "short") == 0) { - if (sign) - return (unsigned long long)(short)val & 0xffff; - else - return val & 0xffff; - } - - if (strcmp(type, "int") == 0) { - if (sign) - return (unsigned long long)(int)val & 0xffffffff; - else - return val & 0xffffffff; - } - - return val; -} - -/* - * Try to figure out the type. - */ -static unsigned long long -eval_type(unsigned long long val, struct tep_print_arg *arg, int pointer) -{ - if (arg->type != TEP_PRINT_TYPE) { - do_warning("expected type argument"); - return 0; - } - - return eval_type_str(val, arg->typecast.type, pointer); -} - -static int arg_num_eval(struct tep_print_arg *arg, long long *val) -{ - long long left, right; - int ret = 1; - - switch (arg->type) { - case TEP_PRINT_ATOM: - *val = strtoll(arg->atom.atom, NULL, 0); - break; - case TEP_PRINT_TYPE: - ret = arg_num_eval(arg->typecast.item, val); - if (!ret) - break; - *val = eval_type(*val, arg, 0); - break; - case TEP_PRINT_OP: - switch (arg->op.op[0]) { - case '|': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - if (arg->op.op[1]) - *val = left || right; - else - *val = left | right; - break; - case '&': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - if (arg->op.op[1]) - *val = left && right; - else - *val = left & right; - break; - case '<': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - switch (arg->op.op[1]) { - case 0: - *val = left < right; - break; - case '<': - *val = left << right; - break; - case '=': - *val = left <= right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret = 0; - } - break; - case '>': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - switch (arg->op.op[1]) { - case 0: - *val = left > right; - break; - case '>': - *val = left >> right; - break; - case '=': - *val = left >= right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret = 0; - } - break; - case '=': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - - if (arg->op.op[1] != '=') { - do_warning("unknown op '%s'", arg->op.op); - ret = 0; - } else - *val = left == right; - break; - case '!': - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - - switch (arg->op.op[1]) { - case '=': - *val = left != right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret = 0; - } - break; - case '-': - /* check for negative */ - if (arg->op.left->type == TEP_PRINT_NULL) - left = 0; - else - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val = left - right; - break; - case '+': - if (arg->op.left->type == TEP_PRINT_NULL) - left = 0; - else - ret = arg_num_eval(arg->op.left, &left); - if (!ret) - break; - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val = left + right; - break; - case '~': - ret = arg_num_eval(arg->op.right, &right); - if (!ret) - break; - *val = ~right; - break; - default: - do_warning("unknown op '%s'", arg->op.op); - ret = 0; - } - break; - - case TEP_PRINT_NULL: - case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL: - case TEP_PRINT_STRING: - case TEP_PRINT_BSTRING: - case TEP_PRINT_BITMASK: - default: - do_warning("invalid eval type %d", arg->type); - ret = 0; - - } - return ret; -} - -static char *arg_eval (struct tep_print_arg *arg) -{ - long long val; - static char buf[24]; - - switch (arg->type) { - case TEP_PRINT_ATOM: - return arg->atom.atom; - case TEP_PRINT_TYPE: - return arg_eval(arg->typecast.item); - case TEP_PRINT_OP: - if (!arg_num_eval(arg, &val)) - break; - sprintf(buf, "%lld", val); - return buf; - - case TEP_PRINT_NULL: - case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL: - case TEP_PRINT_STRING: - case TEP_PRINT_BSTRING: - case TEP_PRINT_BITMASK: - default: - do_warning("invalid eval type %d", arg->type); - break; - } - - return NULL; -} - -static enum tep_event_type -process_fields(struct tep_event *event, struct tep_print_flag_sym **list, char **tok) -{ - enum tep_event_type type; - struct tep_print_arg *arg = NULL; - struct tep_print_flag_sym *field; - char *token = *tok; - char *value; - - do { - free_token(token); - type = read_token_item(&token); - if (test_type_token(type, token, TEP_EVENT_OP, "{")) - break; - - arg = alloc_arg(); - if (!arg) - goto out_free; - - free_token(token); - type = process_arg(event, arg, &token); - - if (type == TEP_EVENT_OP) - type = process_op(event, arg, &token); - - if (type == TEP_EVENT_ERROR) - goto out_free; - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free; - - field = calloc(1, sizeof(*field)); - if (!field) - goto out_free; - - value = arg_eval(arg); - if (value == NULL) - goto out_free_field; - field->value = strdup(value); - if (field->value == NULL) - goto out_free_field; - - free_arg(arg); - arg = alloc_arg(); - if (!arg) - goto out_free; - - free_token(token); - type = process_arg(event, arg, &token); - if (test_type_token(type, token, TEP_EVENT_OP, "}")) - goto out_free_field; - - value = arg_eval(arg); - if (value == NULL) - goto out_free_field; - field->str = strdup(value); - if (field->str == NULL) - goto out_free_field; - free_arg(arg); - arg = NULL; - - *list = field; - list = &field->next; - - free_token(token); - type = read_token_item(&token); - } while (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0); - - *tok = token; - return type; - -out_free_field: - free_flag_sym(field); -out_free: - free_arg(arg); - free_token(token); - *tok = NULL; - - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_flags(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - struct tep_print_arg *field; - enum tep_event_type type; - char *token = NULL; - - memset(arg, 0, sizeof(*arg)); - arg->type = TEP_PRINT_FLAGS; - - field = alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - goto out_free; - } - - type = process_field_arg(event, field, &token); - - /* Handle operations in the first argument */ - while (type == TEP_EVENT_OP) - type = process_op(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free_field; - free_token(token); - - arg->flags.field = field; - - type = read_token_item(&token); - if (event_item_type(type)) { - arg->flags.delim = token; - type = read_token_item(&token); - } - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free; - - type = process_fields(event, &arg->flags.flags, &token); - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type = read_token_item(tok); - return type; - -out_free_field: - free_arg(field); -out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_symbols(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - struct tep_print_arg *field; - enum tep_event_type type; - char *token = NULL; - - memset(arg, 0, sizeof(*arg)); - arg->type = TEP_PRINT_SYMBOL; - - field = alloc_arg(); - if (!field) { - do_warning_event(event, "%s: not enough memory!", __func__); - goto out_free; - } - - type = process_field_arg(event, field, &token); - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto out_free_field; - - arg->symbol.field = field; - - type = process_fields(event, &arg->symbol.symbols, &token); - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type = read_token_item(tok); - return type; - -out_free_field: - free_arg(field); -out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_hex_common(struct tep_event *event, struct tep_print_arg *arg, - char **tok, enum tep_print_arg_type type) -{ - memset(arg, 0, sizeof(*arg)); - arg->type = type; - - if (alloc_and_process_delim(event, ",", &arg->hex.field)) - goto out; - - if (alloc_and_process_delim(event, ")", &arg->hex.size)) - goto free_field; - - return read_token_item(tok); - -free_field: - free_arg(arg->hex.field); - arg->hex.field = NULL; -out: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_hex(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - return process_hex_common(event, arg, tok, TEP_PRINT_HEX); -} - -static enum tep_event_type -process_hex_str(struct tep_event *event, struct tep_print_arg *arg, - char **tok) -{ - return process_hex_common(event, arg, tok, TEP_PRINT_HEX_STR); -} - -static enum tep_event_type -process_int_array(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - memset(arg, 0, sizeof(*arg)); - arg->type = TEP_PRINT_INT_ARRAY; - - if (alloc_and_process_delim(event, ",", &arg->int_array.field)) - goto out; - - if (alloc_and_process_delim(event, ",", &arg->int_array.count)) - goto free_field; - - if (alloc_and_process_delim(event, ")", &arg->int_array.el_size)) - goto free_size; - - return read_token_item(tok); - -free_size: - free_arg(arg->int_array.count); - arg->int_array.count = NULL; -free_field: - free_arg(arg->int_array.field); - arg->int_array.field = NULL; -out: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_dynamic_array(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - struct tep_format_field *field; - enum tep_event_type type; - char *token; - - memset(arg, 0, sizeof(*arg)); - arg->type = TEP_PRINT_DYNAMIC_ARRAY; - - /* - * The item within the parenthesis is another field that holds - * the index into where the array starts. - */ - type = read_token(&token); - *tok = token; - if (type != TEP_EVENT_ITEM) - goto out_free; - - /* Find the field */ - - field = tep_find_field(event, token); - if (!field) - goto out_free; - - arg->dynarray.field = field; - arg->dynarray.index = 0; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_free; - - free_token(token); - type = read_token_item(&token); - *tok = token; - if (type != TEP_EVENT_OP || strcmp(token, "[") != 0) - return type; - - free_token(token); - arg = alloc_arg(); - if (!arg) { - do_warning_event(event, "%s: not enough memory!", __func__); - *tok = NULL; - return TEP_EVENT_ERROR; - } - - type = process_arg(event, arg, &token); - if (type == TEP_EVENT_ERROR) - goto out_free_arg; - - if (!test_type_token(type, token, TEP_EVENT_OP, "]")) - goto out_free_arg; - - free_token(token); - type = read_token_item(tok); - return type; - - out_free_arg: - free_arg(arg); - out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_dynamic_array_len(struct tep_event *event, struct tep_print_arg *arg, - char **tok) -{ - struct tep_format_field *field; - enum tep_event_type type; - char *token; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - - arg->type = TEP_PRINT_DYNAMIC_ARRAY_LEN; - - /* Find the field */ - field = tep_find_field(event, token); - if (!field) - goto out_free; - - arg->dynarray.field = field; - arg->dynarray.index = 0; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - free_token(token); - type = read_token(&token); - *tok = token; - - return type; - - out_free: - free_token(token); - out_err: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_paren(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - struct tep_print_arg *item_arg; - enum tep_event_type type; - char *token; - - type = process_arg(event, arg, &token); - - if (type == TEP_EVENT_ERROR) - goto out_free; - - if (type == TEP_EVENT_OP) - type = process_op(event, arg, &token); - - if (type == TEP_EVENT_ERROR) - goto out_free; - - if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) - goto out_free; - - free_token(token); - type = read_token_item(&token); - - /* - * If the next token is an item or another open paren, then - * this was a typecast. - */ - if (event_item_type(type) || - (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0)) { - - /* make this a typecast and contine */ - - /* prevous must be an atom */ - if (arg->type != TEP_PRINT_ATOM) { - do_warning_event(event, "previous needed to be TEP_PRINT_ATOM"); - goto out_free; - } - - item_arg = alloc_arg(); - if (!item_arg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - goto out_free; - } - - arg->type = TEP_PRINT_TYPE; - arg->typecast.type = arg->atom.atom; - arg->typecast.item = item_arg; - type = process_arg_token(event, item_arg, &token, type); - - } - - *tok = token; - return type; - - out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - - -static enum tep_event_type -process_str(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, - char **tok) -{ - enum tep_event_type type; - char *token; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - - arg->type = TEP_PRINT_STRING; - arg->string.string = token; - arg->string.field = NULL; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - type = read_token(&token); - *tok = token; - - return type; - - out_free: - free_token(token); - out_err: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_arg *arg, - char **tok) -{ - enum tep_event_type type; - char *token; - - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - - arg->type = TEP_PRINT_BITMASK; - arg->bitmask.bitmask = token; - arg->bitmask.field = NULL; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_err; - - type = read_token(&token); - *tok = token; - - return type; - - out_free: - free_token(token); - out_err: - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static struct tep_function_handler * -find_func_handler(struct tep_handle *tep, char *func_name) -{ - struct tep_function_handler *func; - - if (!tep) - return NULL; - - for (func = tep->func_handlers; func; func = func->next) { - if (strcmp(func->name, func_name) == 0) - break; - } - - return func; -} - -static void remove_func_handler(struct tep_handle *tep, char *func_name) -{ - struct tep_function_handler *func; - struct tep_function_handler **next; - - next = &tep->func_handlers; - while ((func = *next)) { - if (strcmp(func->name, func_name) == 0) { - *next = func->next; - free_func_handle(func); - break; - } - next = &func->next; - } -} - -static enum tep_event_type -process_func_handler(struct tep_event *event, struct tep_function_handler *func, - struct tep_print_arg *arg, char **tok) -{ - struct tep_print_arg **next_arg; - struct tep_print_arg *farg; - enum tep_event_type type; - char *token; - int i; - - arg->type = TEP_PRINT_FUNC; - arg->func.func = func; - - *tok = NULL; - - next_arg = &(arg->func.args); - for (i = 0; i < func->nr_args; i++) { - farg = alloc_arg(); - if (!farg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return TEP_EVENT_ERROR; - } - - type = process_arg(event, farg, &token); - if (i < (func->nr_args - 1)) { - if (type != TEP_EVENT_DELIM || strcmp(token, ",") != 0) { - do_warning_event(event, - "Error: function '%s()' expects %d arguments but event %s only uses %d", - func->name, func->nr_args, - event->name, i + 1); - goto err; - } - } else { - if (type != TEP_EVENT_DELIM || strcmp(token, ")") != 0) { - do_warning_event(event, - "Error: function '%s()' only expects %d arguments but event %s has more", - func->name, func->nr_args, event->name); - goto err; - } - } - - *next_arg = farg; - next_arg = &(farg->next); - free_token(token); - } - - type = read_token(&token); - *tok = token; - - return type; - -err: - free_arg(farg); - free_token(token); - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok) -{ - enum tep_event_type type; - char *token = NULL; - - /* Handle __builtin_expect( cond, #) */ - type = process_arg(event, arg, &token); - - if (type != TEP_EVENT_DELIM || token[0] != ',') - goto out_free; - - free_token(token); - - /* We don't care what the second parameter is of the __builtin_expect() */ - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto out_free; - - if (read_expected(TEP_EVENT_DELIM, ")") < 0) - goto out_free; - - free_token(token); - type = read_token_item(tok); - return type; - -out_free: - free_token(token); - *tok = NULL; - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_function(struct tep_event *event, struct tep_print_arg *arg, - char *token, char **tok) -{ - struct tep_function_handler *func; - - if (strcmp(token, "__print_flags") == 0) { - free_token(token); - is_flag_field = 1; - return process_flags(event, arg, tok); - } - if (strcmp(token, "__print_symbolic") == 0) { - free_token(token); - is_symbolic_field = 1; - return process_symbols(event, arg, tok); - } - if (strcmp(token, "__print_hex") == 0) { - free_token(token); - return process_hex(event, arg, tok); - } - if (strcmp(token, "__print_hex_str") == 0) { - free_token(token); - return process_hex_str(event, arg, tok); - } - if (strcmp(token, "__print_array") == 0) { - free_token(token); - return process_int_array(event, arg, tok); - } - if (strcmp(token, "__get_str") == 0 || - strcmp(token, "__get_rel_str") == 0) { - free_token(token); - return process_str(event, arg, tok); - } - if (strcmp(token, "__get_bitmask") == 0 || - strcmp(token, "__get_rel_bitmask") == 0) { - free_token(token); - return process_bitmask(event, arg, tok); - } - if (strcmp(token, "__get_dynamic_array") == 0 || - strcmp(token, "__get_rel_dynamic_array") == 0) { - free_token(token); - return process_dynamic_array(event, arg, tok); - } - if (strcmp(token, "__get_dynamic_array_len") == 0 || - strcmp(token, "__get_rel_dynamic_array_len") == 0) { - free_token(token); - return process_dynamic_array_len(event, arg, tok); - } - if (strcmp(token, "__builtin_expect") == 0) { - free_token(token); - return process_builtin_expect(event, arg, tok); - } - - func = find_func_handler(event->tep, token); - if (func) { - free_token(token); - return process_func_handler(event, func, arg, tok); - } - - do_warning_event(event, "function %s not defined", token); - free_token(token); - return TEP_EVENT_ERROR; -} - -static enum tep_event_type -process_arg_token(struct tep_event *event, struct tep_print_arg *arg, - char **tok, enum tep_event_type type) -{ - char *token; - char *atom; - - token = *tok; - - switch (type) { - case TEP_EVENT_ITEM: - if (strcmp(token, "REC") == 0) { - free_token(token); - type = process_entry(event, arg, &token); - break; - } - atom = token; - /* test the next token */ - type = read_token_item(&token); - - /* - * If the next token is a parenthesis, then this - * is a function. - */ - if (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0) { - free_token(token); - token = NULL; - /* this will free atom. */ - type = process_function(event, arg, atom, &token); - break; - } - /* atoms can be more than one token long */ - while (type == TEP_EVENT_ITEM) { - int ret; - - ret = append(&atom, " ", token); - if (ret < 0) { - free(atom); - *tok = NULL; - free_token(token); - return TEP_EVENT_ERROR; - } - free_token(token); - type = read_token_item(&token); - } - - arg->type = TEP_PRINT_ATOM; - arg->atom.atom = atom; - break; - - case TEP_EVENT_DQUOTE: - case TEP_EVENT_SQUOTE: - arg->type = TEP_PRINT_ATOM; - arg->atom.atom = token; - type = read_token_item(&token); - break; - case TEP_EVENT_DELIM: - if (strcmp(token, "(") == 0) { - free_token(token); - type = process_paren(event, arg, &token); - break; - } - case TEP_EVENT_OP: - /* handle single ops */ - arg->type = TEP_PRINT_OP; - arg->op.op = token; - arg->op.left = NULL; - type = process_op(event, arg, &token); - - /* On error, the op is freed */ - if (type == TEP_EVENT_ERROR) - arg->op.op = NULL; - - /* return error type if errored */ - break; - - case TEP_EVENT_ERROR ... TEP_EVENT_NEWLINE: - default: - do_warning_event(event, "unexpected type %d", type); - return TEP_EVENT_ERROR; - } - *tok = token; - - return type; -} - -static int event_read_print_args(struct tep_event *event, struct tep_print_arg **list) -{ - enum tep_event_type type = TEP_EVENT_ERROR; - struct tep_print_arg *arg; - char *token; - int args = 0; - - do { - if (type == TEP_EVENT_NEWLINE) { - type = read_token_item(&token); - continue; - } - - arg = alloc_arg(); - if (!arg) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return -1; - } - - type = process_arg(event, arg, &token); - - if (type == TEP_EVENT_ERROR) { - free_token(token); - free_arg(arg); - return -1; - } - - *list = arg; - args++; - - if (type == TEP_EVENT_OP) { - type = process_op(event, arg, &token); - free_token(token); - if (type == TEP_EVENT_ERROR) { - *list = NULL; - free_arg(arg); - return -1; - } - list = &arg->next; - continue; - } - - if (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0) { - free_token(token); - *list = arg; - list = &arg->next; - continue; - } - break; - } while (type != TEP_EVENT_NONE); - - if (type != TEP_EVENT_NONE && type != TEP_EVENT_ERROR) - free_token(token); - - return args; -} - -static int event_read_print(struct tep_event *event) -{ - enum tep_event_type type; - char *token; - int ret; - - if (read_expected_item(TEP_EVENT_ITEM, "print") < 0) - return -1; - - if (read_expected(TEP_EVENT_ITEM, "fmt") < 0) - return -1; - - if (read_expected(TEP_EVENT_OP, ":") < 0) - return -1; - - if (read_expect_type(TEP_EVENT_DQUOTE, &token) < 0) - goto fail; - - concat: - event->print_fmt.format = token; - event->print_fmt.args = NULL; - - /* ok to have no arg */ - type = read_token_item(&token); - - if (type == TEP_EVENT_NONE) - return 0; - - /* Handle concatenation of print lines */ - if (type == TEP_EVENT_DQUOTE) { - char *cat; - - if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) - goto fail; - free_token(token); - free_token(event->print_fmt.format); - event->print_fmt.format = NULL; - token = cat; - goto concat; - } - - if (test_type_token(type, token, TEP_EVENT_DELIM, ",")) - goto fail; - - free_token(token); - - ret = event_read_print_args(event, &event->print_fmt.args); - if (ret < 0) - return -1; - - return ret; - - fail: - free_token(token); - return -1; -} - -/** - * tep_find_common_field - return a common field by event - * @event: handle for the event - * @name: the name of the common field to return - * - * Returns a common field from the event by the given @name. - * This only searches the common fields and not all field. - */ -struct tep_format_field * -tep_find_common_field(struct tep_event *event, const char *name) -{ - struct tep_format_field *format; - - for (format = event->format.common_fields; - format; format = format->next) { - if (strcmp(format->name, name) == 0) - break; - } - - return format; -} - -/** - * tep_find_field - find a non-common field - * @event: handle for the event - * @name: the name of the non-common field - * - * Returns a non-common field by the given @name. - * This does not search common fields. - */ -struct tep_format_field * -tep_find_field(struct tep_event *event, const char *name) -{ - struct tep_format_field *format; - - for (format = event->format.fields; - format; format = format->next) { - if (strcmp(format->name, name) == 0) - break; - } - - return format; -} - -/** - * tep_find_any_field - find any field by name - * @event: handle for the event - * @name: the name of the field - * - * Returns a field by the given @name. - * This searches the common field names first, then - * the non-common ones if a common one was not found. - */ -struct tep_format_field * -tep_find_any_field(struct tep_event *event, const char *name) -{ - struct tep_format_field *format; - - format = tep_find_common_field(event, name); - if (format) - return format; - return tep_find_field(event, name); -} - -/** - * tep_read_number - read a number from data - * @tep: a handle to the trace event parser context - * @ptr: the raw data - * @size: the size of the data that holds the number - * - * Returns the number (converted to host) from the - * raw data. - */ -unsigned long long tep_read_number(struct tep_handle *tep, - const void *ptr, int size) -{ - unsigned long long val; - - switch (size) { - case 1: - return *(unsigned char *)ptr; - case 2: - return data2host2(tep, *(unsigned short *)ptr); - case 4: - return data2host4(tep, *(unsigned int *)ptr); - case 8: - memcpy(&val, (ptr), sizeof(unsigned long long)); - return data2host8(tep, val); - default: - /* BUG! */ - return 0; - } -} - -/** - * tep_read_number_field - read a number from data - * @field: a handle to the field - * @data: the raw data to read - * @value: the value to place the number in - * - * Reads raw data according to a field offset and size, - * and translates it into @value. - * - * Returns 0 on success, -1 otherwise. - */ -int tep_read_number_field(struct tep_format_field *field, const void *data, - unsigned long long *value) -{ - if (!field) - return -1; - switch (field->size) { - case 1: - case 2: - case 4: - case 8: - *value = tep_read_number(field->event->tep, - data + field->offset, field->size); - return 0; - default: - return -1; - } -} - -static int get_common_info(struct tep_handle *tep, - const char *type, int *offset, int *size) -{ - struct tep_event *event; - struct tep_format_field *field; - - /* - * All events should have the same common elements. - * Pick any event to find where the type is; - */ - if (!tep->events) { - do_warning("no event_list!"); - return -1; - } - - event = tep->events[0]; - field = tep_find_common_field(event, type); - if (!field) - return -1; - - *offset = field->offset; - *size = field->size; - - return 0; -} - -static int __parse_common(struct tep_handle *tep, void *data, - int *size, int *offset, const char *name) -{ - int ret; - - if (!*size) { - ret = get_common_info(tep, name, offset, size); - if (ret < 0) - return ret; - } - return tep_read_number(tep, data + *offset, *size); -} - -static int trace_parse_common_type(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->type_size, &tep->type_offset, - "common_type"); -} - -static int parse_common_pid(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->pid_size, &tep->pid_offset, - "common_pid"); -} - -static int parse_common_pc(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->pc_size, &tep->pc_offset, - "common_preempt_count"); -} - -static int parse_common_flags(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->flags_size, &tep->flags_offset, - "common_flags"); -} - -static int parse_common_lock_depth(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->ld_size, &tep->ld_offset, - "common_lock_depth"); -} - -static int parse_common_migrate_disable(struct tep_handle *tep, void *data) -{ - return __parse_common(tep, data, - &tep->ld_size, &tep->ld_offset, - "common_migrate_disable"); -} - -static int events_id_cmp(const void *a, const void *b); - -/** - * tep_find_event - find an event by given id - * @tep: a handle to the trace event parser context - * @id: the id of the event - * - * Returns an event that has a given @id. - */ -struct tep_event *tep_find_event(struct tep_handle *tep, int id) -{ - struct tep_event **eventptr; - struct tep_event key; - struct tep_event *pkey = &key; - - /* Check cache first */ - if (tep->last_event && tep->last_event->id == id) - return tep->last_event; - - key.id = id; - - eventptr = bsearch(&pkey, tep->events, tep->nr_events, - sizeof(*tep->events), events_id_cmp); - - if (eventptr) { - tep->last_event = *eventptr; - return *eventptr; - } - - return NULL; -} - -/** - * tep_find_event_by_name - find an event by given name - * @tep: a handle to the trace event parser context - * @sys: the system name to search for - * @name: the name of the event to search for - * - * This returns an event with a given @name and under the system - * @sys. If @sys is NULL the first event with @name is returned. - */ -struct tep_event * -tep_find_event_by_name(struct tep_handle *tep, - const char *sys, const char *name) -{ - struct tep_event *event = NULL; - int i; - - if (tep->last_event && - strcmp(tep->last_event->name, name) == 0 && - (!sys || strcmp(tep->last_event->system, sys) == 0)) - return tep->last_event; - - for (i = 0; i < tep->nr_events; i++) { - event = tep->events[i]; - if (strcmp(event->name, name) == 0) { - if (!sys) - break; - if (strcmp(event->system, sys) == 0) - break; - } - } - if (i == tep->nr_events) - event = NULL; - - tep->last_event = event; - return event; -} - -static unsigned long long -eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg *arg) -{ - struct tep_handle *tep = event->tep; - unsigned long long val = 0; - unsigned long long left, right; - struct tep_print_arg *typearg = NULL; - struct tep_print_arg *larg; - unsigned long offset; - unsigned int field_size; - - switch (arg->type) { - case TEP_PRINT_NULL: - /* ?? */ - return 0; - case TEP_PRINT_ATOM: - return strtoull(arg->atom.atom, NULL, 0); - case TEP_PRINT_FIELD: - if (!arg->field.field) { - arg->field.field = tep_find_any_field(event, arg->field.name); - if (!arg->field.field) - goto out_warning_field; - - } - /* must be a number */ - val = tep_read_number(tep, data + arg->field.field->offset, - arg->field.field->size); - break; - case TEP_PRINT_FLAGS: - case TEP_PRINT_SYMBOL: - case TEP_PRINT_INT_ARRAY: - case TEP_PRINT_HEX: - case TEP_PRINT_HEX_STR: - break; - case TEP_PRINT_TYPE: - val = eval_num_arg(data, size, event, arg->typecast.item); - return eval_type(val, arg, 0); - case TEP_PRINT_STRING: - case TEP_PRINT_BSTRING: - case TEP_PRINT_BITMASK: - return 0; - case TEP_PRINT_FUNC: { - struct trace_seq s; - trace_seq_init(&s); - val = process_defined_func(&s, data, size, event, arg); - trace_seq_destroy(&s); - return val; - } - case TEP_PRINT_OP: - if (strcmp(arg->op.op, "[") == 0) { - /* - * Arrays are special, since we don't want - * to read the arg as is. - */ - right = eval_num_arg(data, size, event, arg->op.right); - - /* handle typecasts */ - larg = arg->op.left; - while (larg->type == TEP_PRINT_TYPE) { - if (!typearg) - typearg = larg; - larg = larg->typecast.item; - } - - /* Default to long size */ - field_size = tep->long_size; - - switch (larg->type) { - case TEP_PRINT_DYNAMIC_ARRAY: - offset = tep_read_number(tep, - data + larg->dynarray.field->offset, - larg->dynarray.field->size); - if (larg->dynarray.field->elementsize) - field_size = larg->dynarray.field->elementsize; - /* - * The actual length of the dynamic array is stored - * in the top half of the field, and the offset - * is in the bottom half of the 32 bit field. - */ - offset &= 0xffff; - offset += right; - break; - case TEP_PRINT_FIELD: - if (!larg->field.field) { - larg->field.field = - tep_find_any_field(event, larg->field.name); - if (!larg->field.field) { - arg = larg; - goto out_warning_field; - } - } - field_size = larg->field.field->elementsize; - offset = larg->field.field->offset + - right * larg->field.field->elementsize; - break; - default: - goto default_op; /* oops, all bets off */ - } - val = tep_read_number(tep, - data + offset, field_size); - if (typearg) - val = eval_type(val, typearg, 1); - break; - } else if (strcmp(arg->op.op, "?") == 0) { - left = eval_num_arg(data, size, event, arg->op.left); - arg = arg->op.right; - if (left) - val = eval_num_arg(data, size, event, arg->op.left); - else - val = eval_num_arg(data, size, event, arg->op.right); - break; - } - default_op: - left = eval_num_arg(data, size, event, arg->op.left); - right = eval_num_arg(data, size, event, arg->op.right); - switch (arg->op.op[0]) { - case '!': - switch (arg->op.op[1]) { - case 0: - val = !right; - break; - case '=': - val = left != right; - break; - default: - goto out_warning_op; - } - break; - case '~': - val = ~right; - break; - case '|': - if (arg->op.op[1]) - val = left || right; - else - val = left | right; - break; - case '&': - if (arg->op.op[1]) - val = left && right; - else - val = left & right; - break; - case '<': - switch (arg->op.op[1]) { - case 0: - val = left < right; - break; - case '<': - val = left << right; - break; - case '=': - val = left <= right; - break; - default: - goto out_warning_op; - } - break; - case '>': - switch (arg->op.op[1]) { - case 0: - val = left > right; - break; - case '>': - val = left >> right; - break; - case '=': - val = left >= right; - break; - default: - goto out_warning_op; - } - break; - case '=': - if (arg->op.op[1] != '=') - goto out_warning_op; - - val = left == right; - break; - case '-': - val = left - right; - break; - case '+': - val = left + right; - break; - case '/': - val = left / right; - break; - case '%': - val = left % right; - break; - case '*': - val = left * right; - break; - default: - goto out_warning_op; - } - break; - case TEP_PRINT_DYNAMIC_ARRAY_LEN: - offset = tep_read_number(tep, - data + arg->dynarray.field->offset, - arg->dynarray.field->size); - /* - * The total allocated length of the dynamic array is - * stored in the top half of the field, and the offset - * is in the bottom half of the 32 bit field. - */ - val = (unsigned long long)(offset >> 16); - break; - case TEP_PRINT_DYNAMIC_ARRAY: - /* Without [], we pass the address to the dynamic data */ - offset = tep_read_number(tep, - data + arg->dynarray.field->offset, - arg->dynarray.field->size); - /* - * The total allocated length of the dynamic array is - * stored in the top half of the field, and the offset - * is in the bottom half of the 32 bit field. - */ - offset &= 0xffff; - val = (unsigned long long)((unsigned long)data + offset); - break; - default: /* not sure what to do there */ - return 0; - } - return val; - -out_warning_op: - do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op); - return 0; - -out_warning_field: - do_warning_event(event, "%s: field %s not found", - __func__, arg->field.name); - return 0; -} - -struct flag { - const char *name; - unsigned long long value; -}; - -static const struct flag flags[] = { - { "HI_SOFTIRQ", 0 }, - { "TIMER_SOFTIRQ", 1 }, - { "NET_TX_SOFTIRQ", 2 }, - { "NET_RX_SOFTIRQ", 3 }, - { "BLOCK_SOFTIRQ", 4 }, - { "IRQ_POLL_SOFTIRQ", 5 }, - { "TASKLET_SOFTIRQ", 6 }, - { "SCHED_SOFTIRQ", 7 }, - { "HRTIMER_SOFTIRQ", 8 }, - { "RCU_SOFTIRQ", 9 }, - - { "HRTIMER_NORESTART", 0 }, - { "HRTIMER_RESTART", 1 }, -}; - -static long long eval_flag(const char *flag) -{ - int i; - - /* - * Some flags in the format files do not get converted. - * If the flag is not numeric, see if it is something that - * we already know about. - */ - if (isdigit(flag[0])) - return strtoull(flag, NULL, 0); - - for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) - if (strcmp(flags[i].name, flag) == 0) - return flags[i].value; - - return -1LL; -} - -static void print_str_to_seq(struct trace_seq *s, const char *format, - int len_arg, const char *str) -{ - if (len_arg >= 0) - trace_seq_printf(s, format, len_arg, str); - else - trace_seq_printf(s, format, str); -} - -static void print_bitmask_to_seq(struct tep_handle *tep, - struct trace_seq *s, const char *format, - int len_arg, const void *data, int size) -{ - int nr_bits = size * 8; - int str_size = (nr_bits + 3) / 4; - int len = 0; - char buf[3]; - char *str; - int index; - int i; - - /* - * The kernel likes to put in commas every 32 bits, we - * can do the same. - */ - str_size += (nr_bits - 1) / 32; - - str = malloc(str_size + 1); - if (!str) { - do_warning("%s: not enough memory!", __func__); - return; - } - str[str_size] = 0; - - /* Start out with -2 for the two chars per byte */ - for (i = str_size - 2; i >= 0; i -= 2) { - /* - * data points to a bit mask of size bytes. - * In the kernel, this is an array of long words, thus - * endianness is very important. - */ - if (tep->file_bigendian) - index = size - (len + 1); - else - index = len; - - snprintf(buf, 3, "%02x", *((unsigned char *)data + index)); - memcpy(str + i, buf, 2); - len++; - if (!(len & 3) && i > 0) { - i--; - str[i] = ','; - } - } - - if (len_arg >= 0) - trace_seq_printf(s, format, len_arg, str); - else - trace_seq_printf(s, format, str); - - free(str); -} - -static void print_str_arg(struct trace_seq *s, void *data, int size, - struct tep_event *event, const char *format, - int len_arg, struct tep_print_arg *arg) -{ - struct tep_handle *tep = event->tep; - struct tep_print_flag_sym *flag; - struct tep_format_field *field; - struct printk_map *printk; - long long val, fval; - unsigned long long addr; - char *str; - unsigned char *hex; - int print; - int i, len; - - switch (arg->type) { - case TEP_PRINT_NULL: - /* ?? */ - return; - case TEP_PRINT_ATOM: - print_str_to_seq(s, format, len_arg, arg->atom.atom); - return; - case TEP_PRINT_FIELD: - field = arg->field.field; - if (!field) { - field = tep_find_any_field(event, arg->field.name); - if (!field) { - str = arg->field.name; - goto out_warning_field; - } - arg->field.field = field; - } - /* Zero sized fields, mean the rest of the data */ - len = field->size ? : size - field->offset; - - /* - * Some events pass in pointers. If this is not an array - * and the size is the same as long_size, assume that it - * is a pointer. - */ - if (!(field->flags & TEP_FIELD_IS_ARRAY) && - field->size == tep->long_size) { - - /* Handle heterogeneous recording and processing - * architectures - * - * CASE I: - * Traces recorded on 32-bit devices (32-bit - * addressing) and processed on 64-bit devices: - * In this case, only 32 bits should be read. - * - * CASE II: - * Traces recorded on 64 bit devices and processed - * on 32-bit devices: - * In this case, 64 bits must be read. - */ - addr = (tep->long_size == 8) ? - *(unsigned long long *)(data + field->offset) : - (unsigned long long)*(unsigned int *)(data + field->offset); - - /* Check if it matches a print format */ - printk = find_printk(tep, addr); - if (printk) - trace_seq_puts(s, printk->printk); - else - trace_seq_printf(s, "%llx", addr); - break; - } - str = malloc(len + 1); - if (!str) { - do_warning_event(event, "%s: not enough memory!", - __func__); - return; - } - memcpy(str, data + field->offset, len); - str[len] = 0; - print_str_to_seq(s, format, len_arg, str); - free(str); - break; - case TEP_PRINT_FLAGS: - val = eval_num_arg(data, size, event, arg->flags.field); - print = 0; - for (flag = arg->flags.flags; flag; flag = flag->next) { - fval = eval_flag(flag->value); - if (!val && fval < 0) { - print_str_to_seq(s, format, len_arg, flag->str); - break; - } - if (fval > 0 && (val & fval) == fval) { - if (print && arg->flags.delim) - trace_seq_puts(s, arg->flags.delim); - print_str_to_seq(s, format, len_arg, flag->str); - print = 1; - val &= ~fval; - } - } - if (val) { - if (print && arg->flags.delim) - trace_seq_puts(s, arg->flags.delim); - trace_seq_printf(s, "0x%llx", val); - } - break; - case TEP_PRINT_SYMBOL: - val = eval_num_arg(data, size, event, arg->symbol.field); - for (flag = arg->symbol.symbols; flag; flag = flag->next) { - fval = eval_flag(flag->value); - if (val == fval) { - print_str_to_seq(s, format, len_arg, flag->str); - break; - } - } - if (!flag) - trace_seq_printf(s, "0x%llx", val); - break; - case TEP_PRINT_HEX: - case TEP_PRINT_HEX_STR: - if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) { - unsigned long offset; - offset = tep_read_number(tep, - data + arg->hex.field->dynarray.field->offset, - arg->hex.field->dynarray.field->size); - hex = data + (offset & 0xffff); - } else { - field = arg->hex.field->field.field; - if (!field) { - str = arg->hex.field->field.name; - field = tep_find_any_field(event, str); - if (!field) - goto out_warning_field; - arg->hex.field->field.field = field; - } - hex = data + field->offset; - } - len = eval_num_arg(data, size, event, arg->hex.size); - for (i = 0; i < len; i++) { - if (i && arg->type == TEP_PRINT_HEX) - trace_seq_putc(s, ' '); - trace_seq_printf(s, "%02x", hex[i]); - } - break; - - case TEP_PRINT_INT_ARRAY: { - void *num; - int el_size; - - if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) { - unsigned long offset; - struct tep_format_field *field = - arg->int_array.field->dynarray.field; - offset = tep_read_number(tep, - data + field->offset, - field->size); - num = data + (offset & 0xffff); - } else { - field = arg->int_array.field->field.field; - if (!field) { - str = arg->int_array.field->field.name; - field = tep_find_any_field(event, str); - if (!field) - goto out_warning_field; - arg->int_array.field->field.field = field; - } - num = data + field->offset; - } - len = eval_num_arg(data, size, event, arg->int_array.count); - el_size = eval_num_arg(data, size, event, - arg->int_array.el_size); - for (i = 0; i < len; i++) { - if (i) - trace_seq_putc(s, ' '); - - if (el_size == 1) { - trace_seq_printf(s, "%u", *(uint8_t *)num); - } else if (el_size == 2) { - trace_seq_printf(s, "%u", *(uint16_t *)num); - } else if (el_size == 4) { - trace_seq_printf(s, "%u", *(uint32_t *)num); - } else if (el_size == 8) { - trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num); - } else { - trace_seq_printf(s, "BAD SIZE:%d 0x%x", - el_size, *(uint8_t *)num); - el_size = 1; - } - - num += el_size; - } - break; - } - case TEP_PRINT_TYPE: - break; - case TEP_PRINT_STRING: { - int str_offset; - - if (!arg->string.field) - arg->string.field = tep_find_any_field(event, arg->string.string); - if (!arg->string.field) - break; - - str_offset = data2host4(tep, - *(unsigned int *)(data + arg->string.field->offset)); - str_offset &= 0xffff; - if (arg->string.field->flags & TEP_FIELD_IS_RELATIVE) - str_offset += arg->string.field->offset + arg->string.field->size; - print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset); - break; - } - case TEP_PRINT_BSTRING: - print_str_to_seq(s, format, len_arg, arg->string.string); - break; - case TEP_PRINT_BITMASK: { - int bitmask_offset; - int bitmask_size; - - if (!arg->bitmask.field) - arg->bitmask.field = tep_find_any_field(event, arg->bitmask.bitmask); - if (!arg->bitmask.field) - break; - bitmask_offset = data2host4(tep, - *(unsigned int *)(data + arg->bitmask.field->offset)); - bitmask_size = bitmask_offset >> 16; - bitmask_offset &= 0xffff; - if (arg->bitmask.field->flags & TEP_FIELD_IS_RELATIVE) - bitmask_offset += arg->bitmask.field->offset + arg->bitmask.field->size; - print_bitmask_to_seq(tep, s, format, len_arg, - data + bitmask_offset, bitmask_size); - break; - } - case TEP_PRINT_OP: - /* - * The only op for string should be ? : - */ - if (arg->op.op[0] != '?') - return; - val = eval_num_arg(data, size, event, arg->op.left); - if (val) - print_str_arg(s, data, size, event, - format, len_arg, arg->op.right->op.left); - else - print_str_arg(s, data, size, event, - format, len_arg, arg->op.right->op.right); - break; - case TEP_PRINT_FUNC: - process_defined_func(s, data, size, event, arg); - break; - default: - /* well... */ - break; - } - - return; - -out_warning_field: - do_warning_event(event, "%s: field %s not found", - __func__, arg->field.name); -} - -static unsigned long long -process_defined_func(struct trace_seq *s, void *data, int size, - struct tep_event *event, struct tep_print_arg *arg) -{ - struct tep_function_handler *func_handle = arg->func.func; - struct func_params *param; - unsigned long long *args; - unsigned long long ret; - struct tep_print_arg *farg; - struct trace_seq str; - struct save_str { - struct save_str *next; - char *str; - } *strings = NULL, *string; - int i; - - if (!func_handle->nr_args) { - ret = (*func_handle->func)(s, NULL); - goto out; - } - - farg = arg->func.args; - param = func_handle->params; - - ret = ULLONG_MAX; - args = malloc(sizeof(*args) * func_handle->nr_args); - if (!args) - goto out; - - for (i = 0; i < func_handle->nr_args; i++) { - switch (param->type) { - case TEP_FUNC_ARG_INT: - case TEP_FUNC_ARG_LONG: - case TEP_FUNC_ARG_PTR: - args[i] = eval_num_arg(data, size, event, farg); - break; - case TEP_FUNC_ARG_STRING: - trace_seq_init(&str); - print_str_arg(&str, data, size, event, "%s", -1, farg); - trace_seq_terminate(&str); - string = malloc(sizeof(*string)); - if (!string) { - do_warning_event(event, "%s(%d): malloc str", - __func__, __LINE__); - goto out_free; - } - string->next = strings; - string->str = strdup(str.buffer); - if (!string->str) { - free(string); - do_warning_event(event, "%s(%d): malloc str", - __func__, __LINE__); - goto out_free; - } - args[i] = (uintptr_t)string->str; - strings = string; - trace_seq_destroy(&str); - break; - default: - /* - * Something went totally wrong, this is not - * an input error, something in this code broke. - */ - do_warning_event(event, "Unexpected end of arguments\n"); - goto out_free; - } - farg = farg->next; - param = param->next; - } - - ret = (*func_handle->func)(s, args); -out_free: - free(args); - while (strings) { - string = strings; - strings = string->next; - free(string->str); - free(string); - } - - out: - /* TBD : handle return type here */ - return ret; -} - -static void free_args(struct tep_print_arg *args) -{ - struct tep_print_arg *next; - - while (args) { - next = args->next; - - free_arg(args); - args = next; - } -} - -static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event *event) -{ - struct tep_handle *tep = event->tep; - struct tep_format_field *field, *ip_field; - struct tep_print_arg *args, *arg, **next; - unsigned long long ip, val; - char *ptr; - void *bptr; - int vsize = 0; - - field = tep->bprint_buf_field; - ip_field = tep->bprint_ip_field; - - if (!field) { - field = tep_find_field(event, "buf"); - if (!field) { - do_warning_event(event, "can't find buffer field for binary printk"); - return NULL; - } - ip_field = tep_find_field(event, "ip"); - if (!ip_field) { - do_warning_event(event, "can't find ip field for binary printk"); - return NULL; - } - tep->bprint_buf_field = field; - tep->bprint_ip_field = ip_field; - } - - ip = tep_read_number(tep, data + ip_field->offset, ip_field->size); - - /* - * The first arg is the IP pointer. - */ - args = alloc_arg(); - if (!args) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - return NULL; - } - arg = args; - arg->next = NULL; - next = &arg->next; - - arg->type = TEP_PRINT_ATOM; - - if (asprintf(&arg->atom.atom, "%lld", ip) < 0) - goto out_free; - - /* skip the first "%ps: " */ - for (ptr = fmt + 5, bptr = data + field->offset; - bptr < data + size && *ptr; ptr++) { - int ls = 0; - - if (*ptr == '%') { - process_again: - ptr++; - switch (*ptr) { - case '%': - break; - case 'l': - ls++; - goto process_again; - case 'L': - ls = 2; - goto process_again; - case '0' ... '9': - goto process_again; - case '.': - goto process_again; - case 'z': - case 'Z': - ls = 1; - goto process_again; - case 'p': - ls = 1; - if (isalnum(ptr[1])) { - ptr++; - /* Check for special pointers */ - switch (*ptr) { - case 's': - case 'S': - case 'x': - break; - case 'f': - case 'F': - /* - * Pre-5.5 kernels use %pf and - * %pF for printing symbols - * while kernels since 5.5 use - * %pfw for fwnodes. So check - * %p[fF] isn't followed by 'w'. - */ - if (ptr[1] != 'w') - break; - /* fall through */ - default: - /* - * Older kernels do not process - * dereferenced pointers. - * Only process if the pointer - * value is a printable. - */ - if (isprint(*(char *)bptr)) - goto process_string; - } - } - /* fall through */ - case 'd': - case 'u': - case 'i': - case 'x': - case 'X': - case 'o': - switch (ls) { - case 0: - vsize = 4; - break; - case 1: - vsize = tep->long_size; - break; - case 2: - vsize = 8; - break; - default: - vsize = ls; /* ? */ - break; - } - /* fall through */ - case '*': - if (*ptr == '*') - vsize = 4; - - /* the pointers are always 4 bytes aligned */ - bptr = (void *)(((unsigned long)bptr + 3) & - ~3); - val = tep_read_number(tep, bptr, vsize); - bptr += vsize; - arg = alloc_arg(); - if (!arg) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - goto out_free; - } - arg->next = NULL; - arg->type = TEP_PRINT_ATOM; - if (asprintf(&arg->atom.atom, "%lld", val) < 0) { - free(arg); - goto out_free; - } - *next = arg; - next = &arg->next; - /* - * The '*' case means that an arg is used as the length. - * We need to continue to figure out for what. - */ - if (*ptr == '*') - goto process_again; - - break; - case 's': - process_string: - arg = alloc_arg(); - if (!arg) { - do_warning_event(event, "%s(%d): not enough memory!", - __func__, __LINE__); - goto out_free; - } - arg->next = NULL; - arg->type = TEP_PRINT_BSTRING; - arg->string.string = strdup(bptr); - if (!arg->string.string) - goto out_free; - bptr += strlen(bptr) + 1; - *next = arg; - next = &arg->next; - default: - break; - } - } - } - - return args; - -out_free: - free_args(args); - return NULL; -} - -static char * -get_bprint_format(void *data, int size __maybe_unused, - struct tep_event *event) -{ - struct tep_handle *tep = event->tep; - unsigned long long addr; - struct tep_format_field *field; - struct printk_map *printk; - char *format; - - field = tep->bprint_fmt_field; - - if (!field) { - field = tep_find_field(event, "fmt"); - if (!field) { - do_warning_event(event, "can't find format field for binary printk"); - return NULL; - } - tep->bprint_fmt_field = field; - } - - addr = tep_read_number(tep, data + field->offset, field->size); - - printk = find_printk(tep, addr); - if (!printk) { - if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0) - return NULL; - return format; - } - - if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0) - return NULL; - - return format; -} - -static int print_mac_arg(struct trace_seq *s, const char *format, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; - bool reverse = false; - unsigned char *buf; - int ret = 0; - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return 0; - } - - if (arg->type != TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", - arg->type); - return 0; - } - - if (format[0] == 'm') { - fmt = "%.2x%.2x%.2x%.2x%.2x%.2x"; - } else if (format[0] == 'M' && format[1] == 'F') { - fmt = "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x"; - ret++; - } - if (format[1] == 'R') { - reverse = true; - ret++; - } - - if (!arg->field.field) { - arg->field.field = - tep_find_any_field(event, arg->field.name); - if (!arg->field.field) { - do_warning_event(event, "%s: field %s not found", - __func__, arg->field.name); - return ret; - } - } - if (arg->field.field->size != 6) { - trace_seq_printf(s, "INVALIDMAC"); - return ret; - } - - buf = data + arg->field.field->offset; - if (reverse) - trace_seq_printf(s, fmt, buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); - else - trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - - return ret; -} - -static int parse_ip4_print_args(struct tep_handle *tep, - const char *ptr, bool *reverse) -{ - int ret = 0; - - *reverse = false; - - /* hnbl */ - switch (*ptr) { - case 'h': - if (tep->file_bigendian) - *reverse = false; - else - *reverse = true; - ret++; - break; - case 'l': - *reverse = true; - ret++; - break; - case 'n': - case 'b': - ret++; - /* fall through */ - default: - *reverse = false; - break; - } - - return ret; -} - -static void print_ip4_addr(struct trace_seq *s, char i, bool reverse, unsigned char *buf) -{ - const char *fmt; - - if (i == 'i') - fmt = "%03d.%03d.%03d.%03d"; - else - fmt = "%d.%d.%d.%d"; - - if (reverse) - trace_seq_printf(s, fmt, buf[3], buf[2], buf[1], buf[0]); - else - trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]); - -} - -static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) -{ - return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) | - (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL; -} - -static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr) -{ - return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); -} - -static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr) -{ - int i, j, range; - unsigned char zerolength[8]; - int longest = 1; - int colonpos = -1; - uint16_t word; - uint8_t hi, lo; - bool needcolon = false; - bool useIPv4; - struct in6_addr in6; - - memcpy(&in6, addr, sizeof(struct in6_addr)); - - useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); - - memset(zerolength, 0, sizeof(zerolength)); - - if (useIPv4) - range = 6; - else - range = 8; - - /* find position of longest 0 run */ - for (i = 0; i < range; i++) { - for (j = i; j < range; j++) { - if (in6.s6_addr16[j] != 0) - break; - zerolength[i]++; - } - } - for (i = 0; i < range; i++) { - if (zerolength[i] > longest) { - longest = zerolength[i]; - colonpos = i; - } - } - if (longest == 1) /* don't compress a single 0 */ - colonpos = -1; - - /* emit address */ - for (i = 0; i < range; i++) { - if (i == colonpos) { - if (needcolon || i == 0) - trace_seq_printf(s, ":"); - trace_seq_printf(s, ":"); - needcolon = false; - i += longest - 1; - continue; - } - if (needcolon) { - trace_seq_printf(s, ":"); - needcolon = false; - } - /* hex u16 without leading 0s */ - word = ntohs(in6.s6_addr16[i]); - hi = word >> 8; - lo = word & 0xff; - if (hi) - trace_seq_printf(s, "%x%02x", hi, lo); - else - trace_seq_printf(s, "%x", lo); - - needcolon = true; - } - - if (useIPv4) { - if (needcolon) - trace_seq_printf(s, ":"); - print_ip4_addr(s, 'I', false, &in6.s6_addr[12]); - } - - return; -} - -static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf) -{ - int j; - - for (j = 0; j < 16; j += 2) { - trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]); - if (i == 'I' && j < 14) - trace_seq_printf(s, ":"); - } -} - -/* - * %pi4 print an IPv4 address with leading zeros - * %pI4 print an IPv4 address without leading zeros - * %pi6 print an IPv6 address without colons - * %pI6 print an IPv6 address with colons - * %pI6c print an IPv6 address in compressed form with colons - * %pISpc print an IP address based on sockaddr; p adds port. - */ -static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - bool reverse = false; - unsigned char *buf; - int ret; - - ret = parse_ip4_print_args(event->tep, ptr, &reverse); - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type != TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - if (!arg->field.field) { - arg->field.field = - tep_find_any_field(event, arg->field.name); - if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); - return ret; - } - } - - buf = data + arg->field.field->offset; - - if (arg->field.field->size != 4) { - trace_seq_printf(s, "INVALIDIPv4"); - return ret; - } - - print_ip4_addr(s, i, reverse, buf); - return ret; - -} - -static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - char have_c = 0; - unsigned char *buf; - int rc = 0; - - /* pI6c */ - if (i == 'I' && *ptr == 'c') { - have_c = 1; - ptr++; - rc++; - } - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return rc; - } - - if (arg->type != TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return rc; - } - - if (!arg->field.field) { - arg->field.field = - tep_find_any_field(event, arg->field.name); - if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); - return rc; - } - } - - buf = data + arg->field.field->offset; - - if (arg->field.field->size != 16) { - trace_seq_printf(s, "INVALIDIPv6"); - return rc; - } - - if (have_c) - print_ip6c_addr(s, buf); - else - print_ip6_addr(s, i, buf); - - return rc; -} - -static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - char have_c = 0, have_p = 0; - unsigned char *buf; - struct sockaddr_storage *sa; - bool reverse = false; - int rc = 0; - int ret; - - /* pISpc */ - if (i == 'I') { - if (*ptr == 'p') { - have_p = 1; - ptr++; - rc++; - } - if (*ptr == 'c') { - have_c = 1; - ptr++; - rc++; - } - } - ret = parse_ip4_print_args(event->tep, ptr, &reverse); - ptr += ret; - rc += ret; - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return rc; - } - - if (arg->type != TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return rc; - } - - if (!arg->field.field) { - arg->field.field = - tep_find_any_field(event, arg->field.name); - if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); - return rc; - } - } - - sa = (struct sockaddr_storage *) (data + arg->field.field->offset); - - if (sa->ss_family == AF_INET) { - struct sockaddr_in *sa4 = (struct sockaddr_in *) sa; - - if (arg->field.field->size < sizeof(struct sockaddr_in)) { - trace_seq_printf(s, "INVALIDIPv4"); - return rc; - } - - print_ip4_addr(s, i, reverse, (unsigned char *) &sa4->sin_addr); - if (have_p) - trace_seq_printf(s, ":%d", ntohs(sa4->sin_port)); - - - } else if (sa->ss_family == AF_INET6) { - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa; - - if (arg->field.field->size < sizeof(struct sockaddr_in6)) { - trace_seq_printf(s, "INVALIDIPv6"); - return rc; - } - - if (have_p) - trace_seq_printf(s, "["); - - buf = (unsigned char *) &sa6->sin6_addr; - if (have_c) - print_ip6c_addr(s, buf); - else - print_ip6_addr(s, i, buf); - - if (have_p) - trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port)); - } - - return rc; -} - -static int print_ip_arg(struct trace_seq *s, const char *ptr, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - char i = *ptr; /* 'i' or 'I' */ - int rc = 1; - - /* IP version */ - ptr++; - - switch (*ptr) { - case '4': - rc += print_ipv4_arg(s, ptr + 1, i, data, size, event, arg); - break; - case '6': - rc += print_ipv6_arg(s, ptr + 1, i, data, size, event, arg); - break; - case 'S': - rc += print_ipsa_arg(s, ptr + 1, i, data, size, event, arg); - break; - default: - return 0; - } - - return rc; -} - -static const int guid_index[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}; -static const int uuid_index[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - -static int print_uuid_arg(struct trace_seq *s, const char *ptr, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - const int *index = uuid_index; - char *format = "%02x"; - int ret = 0; - char *buf; - int i; - - switch (*(ptr + 1)) { - case 'L': - format = "%02X"; - /* fall through */ - case 'l': - index = guid_index; - ret++; - break; - case 'B': - format = "%02X"; - /* fall through */ - case 'b': - ret++; - break; - } - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type != TEP_PRINT_FIELD) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - if (!arg->field.field) { - arg->field.field = - tep_find_any_field(event, arg->field.name); - if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); - return ret; - } - } - - if (arg->field.field->size != 16) { - trace_seq_printf(s, "INVALIDUUID"); - return ret; - } - - buf = data + arg->field.field->offset; - - for (i = 0; i < 16; i++) { - trace_seq_printf(s, format, buf[index[i]] & 0xff); - switch (i) { - case 3: - case 5: - case 7: - case 9: - trace_seq_printf(s, "-"); - break; - } - } - - return ret; -} - -static int print_raw_buff_arg(struct trace_seq *s, const char *ptr, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg, int print_len) -{ - int plen = print_len; - char *delim = " "; - int ret = 0; - char *buf; - int i; - unsigned long offset; - int arr_len; - - switch (*(ptr + 1)) { - case 'C': - delim = ":"; - ret++; - break; - case 'D': - delim = "-"; - ret++; - break; - case 'N': - delim = ""; - ret++; - break; - } - - if (arg->type == TEP_PRINT_FUNC) { - process_defined_func(s, data, size, event, arg); - return ret; - } - - if (arg->type != TEP_PRINT_DYNAMIC_ARRAY) { - trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); - return ret; - } - - offset = tep_read_number(event->tep, - data + arg->dynarray.field->offset, - arg->dynarray.field->size); - arr_len = (unsigned long long)(offset >> 16); - buf = data + (offset & 0xffff); - - if (arr_len < plen) - plen = arr_len; - - if (plen < 1) - return ret; - - trace_seq_printf(s, "%02x", buf[0] & 0xff); - for (i = 1; i < plen; i++) - trace_seq_printf(s, "%s%02x", delim, buf[i] & 0xff); - - return ret; -} - -static int is_printable_array(char *p, unsigned int len) -{ - unsigned int i; - - for (i = 0; i < len && p[i]; i++) - if (!isprint(p[i]) && !isspace(p[i])) - return 0; - return 1; -} - -void tep_print_field(struct trace_seq *s, void *data, - struct tep_format_field *field) -{ - unsigned long long val; - unsigned int offset, len, i; - struct tep_handle *tep = field->event->tep; - - if (field->flags & TEP_FIELD_IS_ARRAY) { - offset = field->offset; - len = field->size; - if (field->flags & TEP_FIELD_IS_DYNAMIC) { - val = tep_read_number(tep, data + offset, len); - offset = val; - len = offset >> 16; - offset &= 0xffff; - if (field->flags & TEP_FIELD_IS_RELATIVE) - offset += field->offset + field->size; - } - if (field->flags & TEP_FIELD_IS_STRING && - is_printable_array(data + offset, len)) { - trace_seq_printf(s, "%s", (char *)data + offset); - } else { - trace_seq_puts(s, "ARRAY["); - for (i = 0; i < len; i++) { - if (i) - trace_seq_puts(s, ", "); - trace_seq_printf(s, "%02x", - *((unsigned char *)data + offset + i)); - } - trace_seq_putc(s, ']'); - field->flags &= ~TEP_FIELD_IS_STRING; - } - } else { - val = tep_read_number(tep, data + field->offset, - field->size); - if (field->flags & TEP_FIELD_IS_POINTER) { - trace_seq_printf(s, "0x%llx", val); - } else if (field->flags & TEP_FIELD_IS_SIGNED) { - switch (field->size) { - case 4: - /* - * If field is long then print it in hex. - * A long usually stores pointers. - */ - if (field->flags & TEP_FIELD_IS_LONG) - trace_seq_printf(s, "0x%x", (int)val); - else - trace_seq_printf(s, "%d", (int)val); - break; - case 2: - trace_seq_printf(s, "%2d", (short)val); - break; - case 1: - trace_seq_printf(s, "%1d", (char)val); - break; - default: - trace_seq_printf(s, "%lld", val); - } - } else { - if (field->flags & TEP_FIELD_IS_LONG) - trace_seq_printf(s, "0x%llx", val); - else - trace_seq_printf(s, "%llu", val); - } - } -} - -void tep_print_fields(struct trace_seq *s, void *data, - int size __maybe_unused, struct tep_event *event) -{ - struct tep_format_field *field; - - field = event->format.fields; - while (field) { - trace_seq_printf(s, " %s=", field->name); - tep_print_field(s, data, field); - field = field->next; - } -} - -static int print_function(struct trace_seq *s, const char *format, - void *data, int size, struct tep_event *event, - struct tep_print_arg *arg) -{ - struct func_map *func; - unsigned long long val; - - val = eval_num_arg(data, size, event, arg); - func = find_func(event->tep, val); - if (func) { - trace_seq_puts(s, func->func); - if (*format == 'F' || *format == 'S') - trace_seq_printf(s, "+0x%llx", val - func->addr); - } else { - if (event->tep->long_size == 4) - trace_seq_printf(s, "0x%lx", (long)val); - else - trace_seq_printf(s, "0x%llx", (long long)val); - } - - return 0; -} - -static int print_arg_pointer(struct trace_seq *s, const char *format, int plen, - void *data, int size, - struct tep_event *event, struct tep_print_arg *arg) -{ - unsigned long long val; - int ret = 1; - - if (arg->type == TEP_PRINT_BSTRING) { - trace_seq_puts(s, arg->string.string); - return 0; - } - while (*format) { - if (*format == 'p') { - format++; - break; - } - format++; - } - - switch (*format) { - case 'F': - case 'f': - case 'S': - case 's': - ret += print_function(s, format, data, size, event, arg); - break; - case 'M': - case 'm': - ret += print_mac_arg(s, format, data, size, event, arg); - break; - case 'I': - case 'i': - ret += print_ip_arg(s, format, data, size, event, arg); - break; - case 'U': - ret += print_uuid_arg(s, format, data, size, event, arg); - break; - case 'h': - ret += print_raw_buff_arg(s, format, data, size, event, arg, plen); - break; - default: - ret = 0; - val = eval_num_arg(data, size, event, arg); - trace_seq_printf(s, "%p", (void *)(intptr_t)val); - break; - } - - return ret; - -} - -static int print_arg_number(struct trace_seq *s, const char *format, int plen, - void *data, int size, int ls, - struct tep_event *event, struct tep_print_arg *arg) -{ - unsigned long long val; - - val = eval_num_arg(data, size, event, arg); - - switch (ls) { - case -2: - if (plen >= 0) - trace_seq_printf(s, format, plen, (char)val); - else - trace_seq_printf(s, format, (char)val); - break; - case -1: - if (plen >= 0) - trace_seq_printf(s, format, plen, (short)val); - else - trace_seq_printf(s, format, (short)val); - break; - case 0: - if (plen >= 0) - trace_seq_printf(s, format, plen, (int)val); - else - trace_seq_printf(s, format, (int)val); - break; - case 1: - if (plen >= 0) - trace_seq_printf(s, format, plen, (long)val); - else - trace_seq_printf(s, format, (long)val); - break; - case 2: - if (plen >= 0) - trace_seq_printf(s, format, plen, (long long)val); - else - trace_seq_printf(s, format, (long long)val); - break; - default: - do_warning_event(event, "bad count (%d)", ls); - event->flags |= TEP_EVENT_FL_FAILED; - } - return 0; -} - - -static void print_arg_string(struct trace_seq *s, const char *format, int plen, - void *data, int size, - struct tep_event *event, struct tep_print_arg *arg) -{ - struct trace_seq p; - - /* Use helper trace_seq */ - trace_seq_init(&p); - print_str_arg(&p, data, size, event, - format, plen, arg); - trace_seq_terminate(&p); - trace_seq_puts(s, p.buffer); - trace_seq_destroy(&p); -} - -static int parse_arg_format_pointer(const char *format) -{ - int ret = 0; - int index; - int loop; - - switch (*format) { - case 'F': - case 'S': - case 'f': - case 's': - ret++; - break; - case 'M': - case 'm': - /* [mM]R , [mM]F */ - switch (format[1]) { - case 'R': - case 'F': - ret++; - break; - } - ret++; - break; - case 'I': - case 'i': - index = 2; - loop = 1; - switch (format[1]) { - case 'S': - /*[S][pfs]*/ - while (loop) { - switch (format[index]) { - case 'p': - case 'f': - case 's': - ret++; - index++; - break; - default: - loop = 0; - break; - } - } - /* fall through */ - case '4': - /* [4S][hnbl] */ - switch (format[index]) { - case 'h': - case 'n': - case 'l': - case 'b': - ret++; - index++; - break; - } - if (format[1] == '4') { - ret++; - break; - } - /* fall through */ - case '6': - /* [6S]c */ - if (format[index] == 'c') - ret++; - ret++; - break; - } - ret++; - break; - case 'U': - switch (format[1]) { - case 'L': - case 'l': - case 'B': - case 'b': - ret++; - break; - } - ret++; - break; - case 'h': - switch (format[1]) { - case 'C': - case 'D': - case 'N': - ret++; - break; - } - ret++; - break; - default: - break; - } - - return ret; -} - -static void free_parse_args(struct tep_print_parse *arg) -{ - struct tep_print_parse *del; - - while (arg) { - del = arg; - arg = del->next; - free(del->format); - free(del); - } -} - -static int parse_arg_add(struct tep_print_parse **parse, char *format, - enum tep_print_parse_type type, - struct tep_print_arg *arg, - struct tep_print_arg *len_as_arg, - int ls) -{ - struct tep_print_parse *parg = NULL; - - parg = calloc(1, sizeof(*parg)); - if (!parg) - goto error; - parg->format = strdup(format); - if (!parg->format) - goto error; - parg->type = type; - parg->arg = arg; - parg->len_as_arg = len_as_arg; - parg->ls = ls; - *parse = parg; - return 0; -error: - if (parg) { - free(parg->format); - free(parg); - } - return -1; -} - -static int parse_arg_format(struct tep_print_parse **parse, - struct tep_event *event, - const char *format, struct tep_print_arg **arg) -{ - struct tep_print_arg *len_arg = NULL; - char print_format[32]; - const char *start = format; - int ret = 0; - int ls = 0; - int res; - int len; - - format++; - ret++; - for (; *format; format++) { - switch (*format) { - case '#': - /* FIXME: need to handle properly */ - break; - case 'h': - ls--; - break; - case 'l': - ls++; - break; - case 'L': - ls = 2; - break; - case '.': - case 'z': - case 'Z': - case '0' ... '9': - case '-': - break; - case '*': - /* The argument is the length. */ - if (!*arg) { - do_warning_event(event, "no argument match"); - event->flags |= TEP_EVENT_FL_FAILED; - goto out_failed; - } - if (len_arg) { - do_warning_event(event, "argument already matched"); - event->flags |= TEP_EVENT_FL_FAILED; - goto out_failed; - } - len_arg = *arg; - *arg = (*arg)->next; - break; - case 'p': - if (!*arg) { - do_warning_event(event, "no argument match"); - event->flags |= TEP_EVENT_FL_FAILED; - goto out_failed; - } - res = parse_arg_format_pointer(format + 1); - if (res > 0) { - format += res; - ret += res; - } - len = ((unsigned long)format + 1) - - (unsigned long)start; - /* should never happen */ - if (len > 31) { - do_warning_event(event, "bad format!"); - event->flags |= TEP_EVENT_FL_FAILED; - len = 31; - } - memcpy(print_format, start, len); - print_format[len] = 0; - - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_POINTER, *arg, len_arg, ls); - *arg = (*arg)->next; - ret++; - return ret; - case 'd': - case 'u': - case 'i': - case 'x': - case 'X': - case 'o': - if (!*arg) { - do_warning_event(event, "no argument match"); - event->flags |= TEP_EVENT_FL_FAILED; - goto out_failed; - } - - len = ((unsigned long)format + 1) - - (unsigned long)start; - - /* should never happen */ - if (len > 30) { - do_warning_event(event, "bad format!"); - event->flags |= TEP_EVENT_FL_FAILED; - len = 31; - } - memcpy(print_format, start, len); - print_format[len] = 0; - - if (event->tep->long_size == 8 && ls == 1 && - sizeof(long) != 8) { - char *p; - - /* make %l into %ll */ - if (ls == 1 && (p = strchr(print_format, 'l'))) - memmove(p+1, p, strlen(p)+1); - ls = 2; - } - if (ls < -2 || ls > 2) { - do_warning_event(event, "bad count (%d)", ls); - event->flags |= TEP_EVENT_FL_FAILED; - } - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_DIGIT, *arg, len_arg, ls); - *arg = (*arg)->next; - ret++; - return ret; - case 's': - if (!*arg) { - do_warning_event(event, "no matching argument"); - event->flags |= TEP_EVENT_FL_FAILED; - goto out_failed; - } - - len = ((unsigned long)format + 1) - - (unsigned long)start; - - /* should never happen */ - if (len > 31) { - do_warning_event(event, "bad format!"); - event->flags |= TEP_EVENT_FL_FAILED; - len = 31; - } - - memcpy(print_format, start, len); - print_format[len] = 0; - - parse_arg_add(parse, print_format, - PRINT_FMT_ARG_STRING, *arg, len_arg, 0); - *arg = (*arg)->next; - ret++; - return ret; - default: - snprintf(print_format, 32, ">%c<", *format); - parse_arg_add(parse, print_format, - PRINT_FMT_STRING, NULL, NULL, 0); - ret++; - return ret; - } - ret++; - } - -out_failed: - return ret; - -} - -static int parse_arg_string(struct tep_print_parse **parse, const char *format) -{ - struct trace_seq s; - int ret = 0; - - trace_seq_init(&s); - for (; *format; format++) { - if (*format == '\\') { - format++; - ret++; - switch (*format) { - case 'n': - trace_seq_putc(&s, '\n'); - break; - case 't': - trace_seq_putc(&s, '\t'); - break; - case 'r': - trace_seq_putc(&s, '\r'); - break; - case '\\': - trace_seq_putc(&s, '\\'); - break; - default: - trace_seq_putc(&s, *format); - break; - } - } else if (*format == '%') { - if (*(format + 1) == '%') { - trace_seq_putc(&s, '%'); - format++; - ret++; - } else - break; - } else - trace_seq_putc(&s, *format); - - ret++; - } - trace_seq_terminate(&s); - parse_arg_add(parse, s.buffer, PRINT_FMT_STRING, NULL, NULL, 0); - trace_seq_destroy(&s); - - return ret; -} - -static struct tep_print_parse * -parse_args(struct tep_event *event, const char *format, struct tep_print_arg *arg) -{ - struct tep_print_parse *parse_ret = NULL; - struct tep_print_parse **parse = NULL; - int ret; - int len; - - len = strlen(format); - while (*format) { - if (!parse_ret) - parse = &parse_ret; - if (*format == '%' && *(format + 1) != '%') - ret = parse_arg_format(parse, event, format, &arg); - else - ret = parse_arg_string(parse, format); - if (*parse) - parse = &((*parse)->next); - - len -= ret; - if (len > 0) - format += ret; - else - break; - } - return parse_ret; -} - -static void print_event_cache(struct tep_print_parse *parse, struct trace_seq *s, - void *data, int size, struct tep_event *event) -{ - int len_arg; - - while (parse) { - if (parse->len_as_arg) - len_arg = eval_num_arg(data, size, event, parse->len_as_arg); - switch (parse->type) { - case PRINT_FMT_ARG_DIGIT: - print_arg_number(s, parse->format, - parse->len_as_arg ? len_arg : -1, data, - size, parse->ls, event, parse->arg); - break; - case PRINT_FMT_ARG_POINTER: - print_arg_pointer(s, parse->format, - parse->len_as_arg ? len_arg : 1, - data, size, event, parse->arg); - break; - case PRINT_FMT_ARG_STRING: - print_arg_string(s, parse->format, - parse->len_as_arg ? len_arg : -1, - data, size, event, parse->arg); - break; - case PRINT_FMT_STRING: - default: - trace_seq_printf(s, "%s", parse->format); - break; - } - parse = parse->next; - } -} - -static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event *event) -{ - struct tep_print_parse *parse = event->print_fmt.print_cache; - struct tep_print_arg *args = NULL; - char *bprint_fmt = NULL; - - if (event->flags & TEP_EVENT_FL_FAILED) { - trace_seq_printf(s, "[FAILED TO PARSE]"); - tep_print_fields(s, data, size, event); - return; - } - - if (event->flags & TEP_EVENT_FL_ISBPRINT) { - bprint_fmt = get_bprint_format(data, size, event); - args = make_bprint_args(bprint_fmt, data, size, event); - parse = parse_args(event, bprint_fmt, args); - } - - print_event_cache(parse, s, data, size, event); - - if (event->flags & TEP_EVENT_FL_ISBPRINT) { - free_parse_args(parse); - free_args(args); - free(bprint_fmt); - } -} - -/* - * This parses out the Latency format (interrupts disabled, - * need rescheduling, in hard/soft interrupt, preempt count - * and lock depth) and places it into the trace_seq. - */ -static void data_latency_format(struct tep_handle *tep, struct trace_seq *s, - char *format, struct tep_record *record) -{ - static int check_lock_depth = 1; - static int check_migrate_disable = 1; - static int lock_depth_exists; - static int migrate_disable_exists; - unsigned int lat_flags; - struct trace_seq sq; - unsigned int pc; - int lock_depth = 0; - int migrate_disable = 0; - int hardirq; - int softirq; - void *data = record->data; - - trace_seq_init(&sq); - lat_flags = parse_common_flags(tep, data); - pc = parse_common_pc(tep, data); - /* lock_depth may not always exist */ - if (lock_depth_exists) - lock_depth = parse_common_lock_depth(tep, data); - else if (check_lock_depth) { - lock_depth = parse_common_lock_depth(tep, data); - if (lock_depth < 0) - check_lock_depth = 0; - else - lock_depth_exists = 1; - } - - /* migrate_disable may not always exist */ - if (migrate_disable_exists) - migrate_disable = parse_common_migrate_disable(tep, data); - else if (check_migrate_disable) { - migrate_disable = parse_common_migrate_disable(tep, data); - if (migrate_disable < 0) - check_migrate_disable = 0; - else - migrate_disable_exists = 1; - } - - hardirq = lat_flags & TRACE_FLAG_HARDIRQ; - softirq = lat_flags & TRACE_FLAG_SOFTIRQ; - - trace_seq_printf(&sq, "%c%c%c", - (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : - (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? - 'X' : '.', - (lat_flags & TRACE_FLAG_NEED_RESCHED) ? - 'N' : '.', - (hardirq && softirq) ? 'H' : - hardirq ? 'h' : softirq ? 's' : '.'); - - if (pc) - trace_seq_printf(&sq, "%x", pc); - else - trace_seq_printf(&sq, "."); - - if (migrate_disable_exists) { - if (migrate_disable < 0) - trace_seq_printf(&sq, "."); - else - trace_seq_printf(&sq, "%d", migrate_disable); - } - - if (lock_depth_exists) { - if (lock_depth < 0) - trace_seq_printf(&sq, "."); - else - trace_seq_printf(&sq, "%d", lock_depth); - } - - if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) { - s->state = TRACE_SEQ__MEM_ALLOC_FAILED; - return; - } - - trace_seq_terminate(&sq); - trace_seq_puts(s, sq.buffer); - trace_seq_destroy(&sq); - trace_seq_terminate(s); -} - -/** - * tep_data_type - parse out the given event type - * @tep: a handle to the trace event parser context - * @rec: the record to read from - * - * This returns the event id from the @rec. - */ -int tep_data_type(struct tep_handle *tep, struct tep_record *rec) -{ - return trace_parse_common_type(tep, rec->data); -} - -/** - * tep_data_pid - parse the PID from record - * @tep: a handle to the trace event parser context - * @rec: the record to parse - * - * This returns the PID from a record. - */ -int tep_data_pid(struct tep_handle *tep, struct tep_record *rec) -{ - return parse_common_pid(tep, rec->data); -} - -/** - * tep_data_preempt_count - parse the preempt count from the record - * @tep: a handle to the trace event parser context - * @rec: the record to parse - * - * This returns the preempt count from a record. - */ -int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec) -{ - return parse_common_pc(tep, rec->data); -} - -/** - * tep_data_flags - parse the latency flags from the record - * @tep: a handle to the trace event parser context - * @rec: the record to parse - * - * This returns the latency flags from a record. - * - * Use trace_flag_type enum for the flags (see event-parse.h). - */ -int tep_data_flags(struct tep_handle *tep, struct tep_record *rec) -{ - return parse_common_flags(tep, rec->data); -} - -/** - * tep_data_comm_from_pid - return the command line from PID - * @tep: a handle to the trace event parser context - * @pid: the PID of the task to search for - * - * This returns a pointer to the command line that has the given - * @pid. - */ -const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid) -{ - const char *comm; - - comm = find_cmdline(tep, pid); - return comm; -} - -static struct tep_cmdline * -pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next) -{ - struct cmdline_list *cmdlist = (struct cmdline_list *)next; - - if (cmdlist) - cmdlist = cmdlist->next; - else - cmdlist = tep->cmdlist; - - while (cmdlist && strcmp(cmdlist->comm, comm) != 0) - cmdlist = cmdlist->next; - - return (struct tep_cmdline *)cmdlist; -} - -/** - * tep_data_pid_from_comm - return the pid from a given comm - * @tep: a handle to the trace event parser context - * @comm: the cmdline to find the pid from - * @next: the cmdline structure to find the next comm - * - * This returns the cmdline structure that holds a pid for a given - * comm, or NULL if none found. As there may be more than one pid for - * a given comm, the result of this call can be passed back into - * a recurring call in the @next parameter, and then it will find the - * next pid. - * Also, it does a linear search, so it may be slow. - */ -struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm, - struct tep_cmdline *next) -{ - struct tep_cmdline *cmdline; - - /* - * If the cmdlines have not been converted yet, then use - * the list. - */ - if (!tep->cmdlines) - return pid_from_cmdlist(tep, comm, next); - - if (next) { - /* - * The next pointer could have been still from - * a previous call before cmdlines were created - */ - if (next < tep->cmdlines || - next >= tep->cmdlines + tep->cmdline_count) - next = NULL; - else - cmdline = next++; - } - - if (!next) - cmdline = tep->cmdlines; - - while (cmdline < tep->cmdlines + tep->cmdline_count) { - if (strcmp(cmdline->comm, comm) == 0) - return cmdline; - cmdline++; - } - return NULL; -} - -/** - * tep_cmdline_pid - return the pid associated to a given cmdline - * @tep: a handle to the trace event parser context - * @cmdline: The cmdline structure to get the pid from - * - * Returns the pid for a give cmdline. If @cmdline is NULL, then - * -1 is returned. - */ -int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline) -{ - struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline; - - if (!cmdline) - return -1; - - /* - * If cmdlines have not been created yet, or cmdline is - * not part of the array, then treat it as a cmdlist instead. - */ - if (!tep->cmdlines || - cmdline < tep->cmdlines || - cmdline >= tep->cmdlines + tep->cmdline_count) - return cmdlist->pid; - - return cmdline->pid; -} - -/* - * This parses the raw @data using the given @event information and - * writes the print format into the trace_seq. - */ -static void print_event_info(struct trace_seq *s, char *format, bool raw, - struct tep_event *event, struct tep_record *record) -{ - int print_pretty = 1; - - if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) - tep_print_fields(s, record->data, record->size, event); - else { - - if (event->handler && !(event->flags & TEP_EVENT_FL_NOHANDLE)) - print_pretty = event->handler(s, record, event, - event->context); - - if (print_pretty) - pretty_print(s, record->data, record->size, event); - } - - trace_seq_terminate(s); -} - -/** - * tep_find_event_by_record - return the event from a given record - * @tep: a handle to the trace event parser context - * @record: The record to get the event from - * - * Returns the associated event for a given record, or NULL if non is - * is found. - */ -struct tep_event * -tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record) -{ - int type; - - if (record->size < 0) { - do_warning("ug! negative record size %d", record->size); - return NULL; - } - - type = trace_parse_common_type(tep, record->data); - - return tep_find_event(tep, type); -} - -/* - * Writes the timestamp of the record into @s. Time divisor and precision can be - * specified as part of printf @format string. Example: - * "%3.1000d" - divide the time by 1000 and print the first 3 digits - * before the dot. Thus, the timestamp "123456000" will be printed as - * "123.456" - */ -static void print_event_time(struct tep_handle *tep, struct trace_seq *s, - char *format, struct tep_event *event, - struct tep_record *record) -{ - unsigned long long time; - char *divstr; - int prec = 0, pr; - int div = 0; - int p10 = 1; - - if (isdigit(*(format + 1))) - prec = atoi(format + 1); - divstr = strchr(format, '.'); - if (divstr && isdigit(*(divstr + 1))) - div = atoi(divstr + 1); - time = record->ts; - if (div) { - time += div / 2; - time /= div; - } - pr = prec; - while (pr--) - p10 *= 10; - - if (p10 > 1 && p10 < time) - trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10); - else - trace_seq_printf(s, "%12llu", time); -} - -struct print_event_type { - enum { - EVENT_TYPE_INT = 1, - EVENT_TYPE_STRING, - EVENT_TYPE_UNKNOWN, - } type; - char format[32]; -}; - -static void print_string(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, struct tep_event *event, - const char *arg, struct print_event_type *type) -{ - const char *comm; - int pid; - - if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) { - data_latency_format(tep, s, type->format, record); - } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) { - pid = parse_common_pid(tep, record->data); - comm = find_cmdline(tep, pid); - trace_seq_printf(s, type->format, comm); - } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) { - print_event_info(s, type->format, true, event, record); - } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) { - print_event_info(s, type->format, false, event, record); - } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) { - trace_seq_printf(s, type->format, event->name); - } else { - trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg); - } - -} - -static void print_int(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, struct tep_event *event, - int arg, struct print_event_type *type) -{ - int param; - - switch (arg) { - case TEP_PRINT_CPU: - param = record->cpu; - break; - case TEP_PRINT_PID: - param = parse_common_pid(tep, record->data); - break; - case TEP_PRINT_TIME: - return print_event_time(tep, s, type->format, event, record); - default: - return; - } - trace_seq_printf(s, type->format, param); -} - -static int tep_print_event_param_type(char *format, - struct print_event_type *type) -{ - char *str = format + 1; - int i = 1; - - type->type = EVENT_TYPE_UNKNOWN; - while (*str) { - switch (*str) { - case 'd': - case 'u': - case 'i': - case 'x': - case 'X': - case 'o': - type->type = EVENT_TYPE_INT; - break; - case 's': - type->type = EVENT_TYPE_STRING; - break; - } - str++; - i++; - if (type->type != EVENT_TYPE_UNKNOWN) - break; - } - memset(type->format, 0, 32); - memcpy(type->format, format, i < 32 ? i : 31); - return i; -} - -/** - * tep_print_event - Write various event information - * @tep: a handle to the trace event parser context - * @s: the trace_seq to write to - * @record: The record to get the event from - * @format: a printf format string. Supported event fileds: - * TEP_PRINT_PID, "%d" - event PID - * TEP_PRINT_CPU, "%d" - event CPU - * TEP_PRINT_COMM, "%s" - event command string - * TEP_PRINT_NAME, "%s" - event name - * TEP_PRINT_LATENCY, "%s" - event latency - * TEP_PRINT_TIME, %d - event time stamp. A divisor and precision - * can be specified as part of this format string: - * "%precision.divisord". Example: - * "%3.1000d" - divide the time by 1000 and print the first - * 3 digits before the dot. Thus, the time stamp - * "123456000" will be printed as "123.456" - * TEP_PRINT_INFO, "%s" - event information. If any width is specified in - * the format string, the event information will be printed - * in raw format. - * Writes the specified event information into @s. - */ -void tep_print_event(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, const char *fmt, ...) -{ - struct print_event_type type; - char *format = strdup(fmt); - char *current = format; - char *str = format; - int offset; - va_list args; - struct tep_event *event; - - if (!format) - return; - - event = tep_find_event_by_record(tep, record); - va_start(args, fmt); - while (*current) { - current = strchr(str, '%'); - if (!current) { - trace_seq_puts(s, str); - break; - } - memset(&type, 0, sizeof(type)); - offset = tep_print_event_param_type(current, &type); - *current = '\0'; - trace_seq_puts(s, str); - current += offset; - switch (type.type) { - case EVENT_TYPE_STRING: - print_string(tep, s, record, event, - va_arg(args, char*), &type); - break; - case EVENT_TYPE_INT: - print_int(tep, s, record, event, - va_arg(args, int), &type); - break; - case EVENT_TYPE_UNKNOWN: - default: - trace_seq_printf(s, "[UNKNOWN TYPE]"); - break; - } - str = current; - - } - va_end(args); - free(format); -} - -static int events_id_cmp(const void *a, const void *b) -{ - struct tep_event * const * ea = a; - struct tep_event * const * eb = b; - - if ((*ea)->id < (*eb)->id) - return -1; - - if ((*ea)->id > (*eb)->id) - return 1; - - return 0; -} - -static int events_name_cmp(const void *a, const void *b) -{ - struct tep_event * const * ea = a; - struct tep_event * const * eb = b; - int res; - - res = strcmp((*ea)->name, (*eb)->name); - if (res) - return res; - - res = strcmp((*ea)->system, (*eb)->system); - if (res) - return res; - - return events_id_cmp(a, b); -} - -static int events_system_cmp(const void *a, const void *b) -{ - struct tep_event * const * ea = a; - struct tep_event * const * eb = b; - int res; - - res = strcmp((*ea)->system, (*eb)->system); - if (res) - return res; - - res = strcmp((*ea)->name, (*eb)->name); - if (res) - return res; - - return events_id_cmp(a, b); -} - -static struct tep_event **list_events_copy(struct tep_handle *tep) -{ - struct tep_event **events; - - if (!tep) - return NULL; - - events = malloc(sizeof(*events) * (tep->nr_events + 1)); - if (!events) - return NULL; - - memcpy(events, tep->events, sizeof(*events) * tep->nr_events); - events[tep->nr_events] = NULL; - return events; -} - -static void list_events_sort(struct tep_event **events, int nr_events, - enum tep_event_sort_type sort_type) -{ - int (*sort)(const void *a, const void *b); - - switch (sort_type) { - case TEP_EVENT_SORT_ID: - sort = events_id_cmp; - break; - case TEP_EVENT_SORT_NAME: - sort = events_name_cmp; - break; - case TEP_EVENT_SORT_SYSTEM: - sort = events_system_cmp; - break; - default: - sort = NULL; - } - - if (sort) - qsort(events, nr_events, sizeof(*events), sort); -} - -/** - * tep_list_events - Get events, sorted by given criteria. - * @tep: a handle to the tep context - * @sort_type: desired sort order of the events in the array - * - * Returns an array of pointers to all events, sorted by the given - * @sort_type criteria. The last element of the array is NULL. The returned - * memory must not be freed, it is managed by the library. - * The function is not thread safe. - */ -struct tep_event **tep_list_events(struct tep_handle *tep, - enum tep_event_sort_type sort_type) -{ - struct tep_event **events; - - if (!tep) - return NULL; - - events = tep->sort_events; - if (events && tep->last_type == sort_type) - return events; - - if (!events) { - events = list_events_copy(tep); - if (!events) - return NULL; - - tep->sort_events = events; - - /* the internal events are sorted by id */ - if (sort_type == TEP_EVENT_SORT_ID) { - tep->last_type = sort_type; - return events; - } - } - - list_events_sort(events, tep->nr_events, sort_type); - tep->last_type = sort_type; - - return events; -} - - -/** - * tep_list_events_copy - Thread safe version of tep_list_events() - * @tep: a handle to the tep context - * @sort_type: desired sort order of the events in the array - * - * Returns an array of pointers to all events, sorted by the given - * @sort_type criteria. The last element of the array is NULL. The returned - * array is newly allocated inside the function and must be freed by the caller - */ -struct tep_event **tep_list_events_copy(struct tep_handle *tep, - enum tep_event_sort_type sort_type) -{ - struct tep_event **events; - - if (!tep) - return NULL; - - events = list_events_copy(tep); - if (!events) - return NULL; - - /* the internal events are sorted by id */ - if (sort_type == TEP_EVENT_SORT_ID) - return events; - - list_events_sort(events, tep->nr_events, sort_type); - - return events; -} - -static struct tep_format_field ** -get_event_fields(const char *type, const char *name, - int count, struct tep_format_field *list) -{ - struct tep_format_field **fields; - struct tep_format_field *field; - int i = 0; - - fields = malloc(sizeof(*fields) * (count + 1)); - if (!fields) - return NULL; - - for (field = list; field; field = field->next) { - fields[i++] = field; - if (i == count + 1) { - do_warning("event %s has more %s fields than specified", - name, type); - i--; - break; - } - } - - if (i != count) - do_warning("event %s has less %s fields than specified", - name, type); - - fields[i] = NULL; - - return fields; -} - -/** - * tep_event_common_fields - return a list of common fields for an event - * @event: the event to return the common fields of. - * - * Returns an allocated array of fields. The last item in the array is NULL. - * The array must be freed with free(). - */ -struct tep_format_field **tep_event_common_fields(struct tep_event *event) -{ - return get_event_fields("common", event->name, - event->format.nr_common, - event->format.common_fields); -} - -/** - * tep_event_fields - return a list of event specific fields for an event - * @event: the event to return the fields of. - * - * Returns an allocated array of fields. The last item in the array is NULL. - * The array must be freed with free(). - */ -struct tep_format_field **tep_event_fields(struct tep_event *event) -{ - return get_event_fields("event", event->name, - event->format.nr_fields, - event->format.fields); -} - -static void print_fields(struct trace_seq *s, struct tep_print_flag_sym *field) -{ - trace_seq_printf(s, "{ %s, %s }", field->value, field->str); - if (field->next) { - trace_seq_puts(s, ", "); - print_fields(s, field->next); - } -} - -/* for debugging */ -static void print_args(struct tep_print_arg *args) -{ - int print_paren = 1; - struct trace_seq s; - - switch (args->type) { - case TEP_PRINT_NULL: - printf("null"); - break; - case TEP_PRINT_ATOM: - printf("%s", args->atom.atom); - break; - case TEP_PRINT_FIELD: - printf("REC->%s", args->field.name); - break; - case TEP_PRINT_FLAGS: - printf("__print_flags("); - print_args(args->flags.field); - printf(", %s, ", args->flags.delim); - trace_seq_init(&s); - print_fields(&s, args->flags.flags); - trace_seq_do_printf(&s); - trace_seq_destroy(&s); - printf(")"); - break; - case TEP_PRINT_SYMBOL: - printf("__print_symbolic("); - print_args(args->symbol.field); - printf(", "); - trace_seq_init(&s); - print_fields(&s, args->symbol.symbols); - trace_seq_do_printf(&s); - trace_seq_destroy(&s); - printf(")"); - break; - case TEP_PRINT_HEX: - printf("__print_hex("); - print_args(args->hex.field); - printf(", "); - print_args(args->hex.size); - printf(")"); - break; - case TEP_PRINT_HEX_STR: - printf("__print_hex_str("); - print_args(args->hex.field); - printf(", "); - print_args(args->hex.size); - printf(")"); - break; - case TEP_PRINT_INT_ARRAY: - printf("__print_array("); - print_args(args->int_array.field); - printf(", "); - print_args(args->int_array.count); - printf(", "); - print_args(args->int_array.el_size); - printf(")"); - break; - case TEP_PRINT_STRING: - case TEP_PRINT_BSTRING: - printf("__get_str(%s)", args->string.string); - break; - case TEP_PRINT_BITMASK: - printf("__get_bitmask(%s)", args->bitmask.bitmask); - break; - case TEP_PRINT_TYPE: - printf("(%s)", args->typecast.type); - print_args(args->typecast.item); - break; - case TEP_PRINT_OP: - if (strcmp(args->op.op, ":") == 0) - print_paren = 0; - if (print_paren) - printf("("); - print_args(args->op.left); - printf(" %s ", args->op.op); - print_args(args->op.right); - if (print_paren) - printf(")"); - break; - default: - /* we should warn... */ - return; - } - if (args->next) { - printf("\n"); - print_args(args->next); - } -} - -static void parse_header_field(const char *field, - int *offset, int *size, int mandatory) -{ - unsigned long long save_input_buf_ptr; - unsigned long long save_input_buf_siz; - char *token; - int type; - - save_input_buf_ptr = input_buf_ptr; - save_input_buf_siz = input_buf_siz; - - if (read_expected(TEP_EVENT_ITEM, "field") < 0) - return; - if (read_expected(TEP_EVENT_OP, ":") < 0) - return; - - /* type */ - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - free_token(token); - - /* - * If this is not a mandatory field, then test it first. - */ - if (mandatory) { - if (read_expected(TEP_EVENT_ITEM, field) < 0) - return; - } else { - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - if (strcmp(token, field) != 0) - goto discard; - free_token(token); - } - - if (read_expected(TEP_EVENT_OP, ";") < 0) - return; - if (read_expected(TEP_EVENT_ITEM, "offset") < 0) - return; - if (read_expected(TEP_EVENT_OP, ":") < 0) - return; - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - *offset = atoi(token); - free_token(token); - if (read_expected(TEP_EVENT_OP, ";") < 0) - return; - if (read_expected(TEP_EVENT_ITEM, "size") < 0) - return; - if (read_expected(TEP_EVENT_OP, ":") < 0) - return; - if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) - goto fail; - *size = atoi(token); - free_token(token); - if (read_expected(TEP_EVENT_OP, ";") < 0) - return; - type = read_token(&token); - if (type != TEP_EVENT_NEWLINE) { - /* newer versions of the kernel have a "signed" type */ - if (type != TEP_EVENT_ITEM) - goto fail; - - if (strcmp(token, "signed") != 0) - goto fail; - - free_token(token); - - if (read_expected(TEP_EVENT_OP, ":") < 0) - return; - - if (read_expect_type(TEP_EVENT_ITEM, &token)) - goto fail; - - free_token(token); - if (read_expected(TEP_EVENT_OP, ";") < 0) - return; - - if (read_expect_type(TEP_EVENT_NEWLINE, &token)) - goto fail; - } - fail: - free_token(token); - return; - - discard: - input_buf_ptr = save_input_buf_ptr; - input_buf_siz = save_input_buf_siz; - *offset = 0; - *size = 0; - free_token(token); -} - -/** - * tep_parse_header_page - parse the data stored in the header page - * @tep: a handle to the trace event parser context - * @buf: the buffer storing the header page format string - * @size: the size of @buf - * @long_size: the long size to use if there is no header - * - * This parses the header page format for information on the - * ring buffer used. The @buf should be copied from - * - * /sys/kernel/debug/tracing/events/header_page - */ -int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, - int long_size) -{ - int ignore; - - if (!size) { - /* - * Old kernels did not have header page info. - * Sorry but we just use what we find here in user space. - */ - tep->header_page_ts_size = sizeof(long long); - tep->header_page_size_size = long_size; - tep->header_page_data_offset = sizeof(long long) + long_size; - tep->old_format = 1; - return -1; - } - init_input_buf(buf, size); - - parse_header_field("timestamp", &tep->header_page_ts_offset, - &tep->header_page_ts_size, 1); - parse_header_field("commit", &tep->header_page_size_offset, - &tep->header_page_size_size, 1); - parse_header_field("overwrite", &tep->header_page_overwrite, - &ignore, 0); - parse_header_field("data", &tep->header_page_data_offset, - &tep->header_page_data_size, 1); - - return 0; -} - -static int event_matches(struct tep_event *event, - int id, const char *sys_name, - const char *event_name) -{ - if (id >= 0 && id != event->id) - return 0; - - if (event_name && (strcmp(event_name, event->name) != 0)) - return 0; - - if (sys_name && (strcmp(sys_name, event->system) != 0)) - return 0; - - return 1; -} - -static void free_handler(struct event_handler *handle) -{ - free((void *)handle->sys_name); - free((void *)handle->event_name); - free(handle); -} - -static int find_event_handle(struct tep_handle *tep, struct tep_event *event) -{ - struct event_handler *handle, **next; - - for (next = &tep->handlers; *next; - next = &(*next)->next) { - handle = *next; - if (event_matches(event, handle->id, - handle->sys_name, - handle->event_name)) - break; - } - - if (!(*next)) - return 0; - - pr_stat("overriding event (%d) %s:%s with new print handler", - event->id, event->system, event->name); - - event->handler = handle->func; - event->context = handle->context; - - *next = handle->next; - free_handler(handle); - - return 1; -} - -/** - * parse_format - parse the event format - * @buf: the buffer storing the event format string - * @size: the size of @buf - * @sys: the system the event belongs to - * - * This parses the event format and creates an event structure - * to quickly parse raw data for a given event. - * - * These files currently come from: - * - * /sys/kernel/debug/tracing/events/.../.../format - */ -static enum tep_errno parse_format(struct tep_event **eventp, - struct tep_handle *tep, const char *buf, - unsigned long size, const char *sys) -{ - struct tep_event *event; - int ret; - - init_input_buf(buf, size); - - *eventp = event = alloc_event(); - if (!event) - return TEP_ERRNO__MEM_ALLOC_FAILED; - - event->name = event_read_name(); - if (!event->name) { - /* Bad event? */ - ret = TEP_ERRNO__MEM_ALLOC_FAILED; - goto event_alloc_failed; - } - - if (strcmp(sys, "ftrace") == 0) { - event->flags |= TEP_EVENT_FL_ISFTRACE; - - if (strcmp(event->name, "bprint") == 0) - event->flags |= TEP_EVENT_FL_ISBPRINT; - } - - event->id = event_read_id(); - if (event->id < 0) { - ret = TEP_ERRNO__READ_ID_FAILED; - /* - * This isn't an allocation error actually. - * But as the ID is critical, just bail out. - */ - goto event_alloc_failed; - } - - event->system = strdup(sys); - if (!event->system) { - ret = TEP_ERRNO__MEM_ALLOC_FAILED; - goto event_alloc_failed; - } - - /* Add tep to event so that it can be referenced */ - event->tep = tep; - - ret = event_read_format(event); - if (ret < 0) { - ret = TEP_ERRNO__READ_FORMAT_FAILED; - goto event_parse_failed; - } - - /* - * If the event has an override, don't print warnings if the event - * print format fails to parse. - */ - if (tep && find_event_handle(tep, event)) - show_warning = 0; - - ret = event_read_print(event); - show_warning = 1; - - if (ret < 0) { - ret = TEP_ERRNO__READ_PRINT_FAILED; - goto event_parse_failed; - } - - if (!ret && (event->flags & TEP_EVENT_FL_ISFTRACE)) { - struct tep_format_field *field; - struct tep_print_arg *arg, **list; - - /* old ftrace had no args */ - list = &event->print_fmt.args; - for (field = event->format.fields; field; field = field->next) { - arg = alloc_arg(); - if (!arg) { - event->flags |= TEP_EVENT_FL_FAILED; - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; - } - arg->type = TEP_PRINT_FIELD; - arg->field.name = strdup(field->name); - if (!arg->field.name) { - event->flags |= TEP_EVENT_FL_FAILED; - free_arg(arg); - return TEP_ERRNO__OLD_FTRACE_ARG_FAILED; - } - arg->field.field = field; - *list = arg; - list = &arg->next; - } - } - - if (!(event->flags & TEP_EVENT_FL_ISBPRINT)) - event->print_fmt.print_cache = parse_args(event, - event->print_fmt.format, - event->print_fmt.args); - - return 0; - - event_parse_failed: - event->flags |= TEP_EVENT_FL_FAILED; - return ret; - - event_alloc_failed: - free(event->system); - free(event->name); - free(event); - *eventp = NULL; - return ret; -} - -static enum tep_errno -__parse_event(struct tep_handle *tep, - struct tep_event **eventp, - const char *buf, unsigned long size, - const char *sys) -{ - int ret = parse_format(eventp, tep, buf, size, sys); - struct tep_event *event = *eventp; - - if (event == NULL) - return ret; - - if (tep && add_event(tep, event)) { - ret = TEP_ERRNO__MEM_ALLOC_FAILED; - goto event_add_failed; - } - -#define PRINT_ARGS 0 - if (PRINT_ARGS && event->print_fmt.args) - print_args(event->print_fmt.args); - - return 0; - -event_add_failed: - free_tep_event(event); - return ret; -} - -/** - * tep_parse_format - parse the event format - * @tep: a handle to the trace event parser context - * @eventp: returned format - * @buf: the buffer storing the event format string - * @size: the size of @buf - * @sys: the system the event belongs to - * - * This parses the event format and creates an event structure - * to quickly parse raw data for a given event. - * - * These files currently come from: - * - * /sys/kernel/debug/tracing/events/.../.../format - */ -enum tep_errno tep_parse_format(struct tep_handle *tep, - struct tep_event **eventp, - const char *buf, - unsigned long size, const char *sys) -{ - return __parse_event(tep, eventp, buf, size, sys); -} - -/** - * tep_parse_event - parse the event format - * @tep: a handle to the trace event parser context - * @buf: the buffer storing the event format string - * @size: the size of @buf - * @sys: the system the event belongs to - * - * This parses the event format and creates an event structure - * to quickly parse raw data for a given event. - * - * These files currently come from: - * - * /sys/kernel/debug/tracing/events/.../.../format - */ -enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf, - unsigned long size, const char *sys) -{ - struct tep_event *event = NULL; - return __parse_event(tep, &event, buf, size, sys); -} - -int get_field_val(struct trace_seq *s, struct tep_format_field *field, - const char *name, struct tep_record *record, - unsigned long long *val, int err) -{ - if (!field) { - if (err) - trace_seq_printf(s, "", name); - return -1; - } - - if (tep_read_number_field(field, record->data, val)) { - if (err) - trace_seq_printf(s, " %s=INVALID", name); - return -1; - } - - return 0; -} - -/** - * tep_get_field_raw - return the raw pointer into the data field - * @s: The seq to print to on error - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @len: place to store the field length. - * @err: print default error if failed. - * - * Returns a pointer into record->data of the field and places - * the length of the field in @len. - * - * On failure, it returns NULL. - */ -void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - int *len, int err) -{ - struct tep_format_field *field; - void *data = record->data; - unsigned offset; - int dummy; - - if (!event) - return NULL; - - field = tep_find_field(event, name); - - if (!field) { - if (err) - trace_seq_printf(s, "", name); - return NULL; - } - - /* Allow @len to be NULL */ - if (!len) - len = &dummy; - - offset = field->offset; - if (field->flags & TEP_FIELD_IS_DYNAMIC) { - offset = tep_read_number(event->tep, - data + offset, field->size); - *len = offset >> 16; - offset &= 0xffff; - if (field->flags & TEP_FIELD_IS_RELATIVE) - offset += field->offset + field->size; - } else - *len = field->size; - - return data + offset; -} - -/** - * tep_get_field_val - find a field and return its value - * @s: The seq to print to on error - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @val: place to store the value of the field. - * @err: print default error if failed. - * - * Returns 0 on success -1 on field not found. - */ -int tep_get_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err) -{ - struct tep_format_field *field; - - if (!event) - return -1; - - field = tep_find_field(event, name); - - return get_field_val(s, field, name, record, val, err); -} - -/** - * tep_get_common_field_val - find a common field and return its value - * @s: The seq to print to on error - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @val: place to store the value of the field. - * @err: print default error if failed. - * - * Returns 0 on success -1 on field not found. - */ -int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err) -{ - struct tep_format_field *field; - - if (!event) - return -1; - - field = tep_find_common_field(event, name); - - return get_field_val(s, field, name, record, val, err); -} - -/** - * tep_get_any_field_val - find a any field and return its value - * @s: The seq to print to on error - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @val: place to store the value of the field. - * @err: print default error if failed. - * - * Returns 0 on success -1 on field not found. - */ -int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err) -{ - struct tep_format_field *field; - - if (!event) - return -1; - - field = tep_find_any_field(event, name); - - return get_field_val(s, field, name, record, val, err); -} - -/** - * tep_print_num_field - print a field and a format - * @s: The seq to print to - * @fmt: The printf format to print the field with. - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @err: print default error if failed. - * - * Returns positive value on success, negative in case of an error, - * or 0 if buffer is full. - */ -int tep_print_num_field(struct trace_seq *s, const char *fmt, - struct tep_event *event, const char *name, - struct tep_record *record, int err) -{ - struct tep_format_field *field = tep_find_field(event, name); - unsigned long long val; - - if (!field) - goto failed; - - if (tep_read_number_field(field, record->data, &val)) - goto failed; - - return trace_seq_printf(s, fmt, val); - - failed: - if (err) - trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); - return -1; -} - -/** - * tep_print_func_field - print a field and a format for function pointers - * @s: The seq to print to - * @fmt: The printf format to print the field with. - * @event: the event that the field is for - * @name: The name of the field - * @record: The record with the field name. - * @err: print default error if failed. - * - * Returns positive value on success, negative in case of an error, - * or 0 if buffer is full. - */ -int tep_print_func_field(struct trace_seq *s, const char *fmt, - struct tep_event *event, const char *name, - struct tep_record *record, int err) -{ - struct tep_format_field *field = tep_find_field(event, name); - struct tep_handle *tep = event->tep; - unsigned long long val; - struct func_map *func; - char tmp[128]; - - if (!field) - goto failed; - - if (tep_read_number_field(field, record->data, &val)) - goto failed; - - func = find_func(tep, val); - - if (func) - snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val); - else - sprintf(tmp, "0x%08llx", val); - - return trace_seq_printf(s, fmt, tmp); - - failed: - if (err) - trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); - return -1; -} - -static void free_func_handle(struct tep_function_handler *func) -{ - struct func_params *params; - - free(func->name); - - while (func->params) { - params = func->params; - func->params = params->next; - free(params); - } - - free(func); -} - -/** - * tep_register_print_function - register a helper function - * @tep: a handle to the trace event parser context - * @func: the function to process the helper function - * @ret_type: the return type of the helper function - * @name: the name of the helper function - * @parameters: A list of enum tep_func_arg_type - * - * Some events may have helper functions in the print format arguments. - * This allows a plugin to dynamically create a way to process one - * of these functions. - * - * The @parameters is a variable list of tep_func_arg_type enums that - * must end with TEP_FUNC_ARG_VOID. - */ -int tep_register_print_function(struct tep_handle *tep, - tep_func_handler func, - enum tep_func_arg_type ret_type, - char *name, ...) -{ - struct tep_function_handler *func_handle; - struct func_params **next_param; - struct func_params *param; - enum tep_func_arg_type type; - va_list ap; - int ret; - - func_handle = find_func_handler(tep, name); - if (func_handle) { - /* - * This is most like caused by the users own - * plugins updating the function. This overrides the - * system defaults. - */ - pr_stat("override of function helper '%s'", name); - remove_func_handler(tep, name); - } - - func_handle = calloc(1, sizeof(*func_handle)); - if (!func_handle) { - do_warning("Failed to allocate function handler"); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - func_handle->ret_type = ret_type; - func_handle->name = strdup(name); - func_handle->func = func; - if (!func_handle->name) { - do_warning("Failed to allocate function name"); - free(func_handle); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - next_param = &(func_handle->params); - va_start(ap, name); - for (;;) { - type = va_arg(ap, enum tep_func_arg_type); - if (type == TEP_FUNC_ARG_VOID) - break; - - if (type >= TEP_FUNC_ARG_MAX_TYPES) { - do_warning("Invalid argument type %d", type); - ret = TEP_ERRNO__INVALID_ARG_TYPE; - goto out_free; - } - - param = malloc(sizeof(*param)); - if (!param) { - do_warning("Failed to allocate function param"); - ret = TEP_ERRNO__MEM_ALLOC_FAILED; - goto out_free; - } - param->type = type; - param->next = NULL; - - *next_param = param; - next_param = &(param->next); - - func_handle->nr_args++; - } - va_end(ap); - - func_handle->next = tep->func_handlers; - tep->func_handlers = func_handle; - - return 0; - out_free: - va_end(ap); - free_func_handle(func_handle); - return ret; -} - -/** - * tep_unregister_print_function - unregister a helper function - * @tep: a handle to the trace event parser context - * @func: the function to process the helper function - * @name: the name of the helper function - * - * This function removes existing print handler for function @name. - * - * Returns 0 if the handler was removed successully, -1 otherwise. - */ -int tep_unregister_print_function(struct tep_handle *tep, - tep_func_handler func, char *name) -{ - struct tep_function_handler *func_handle; - - func_handle = find_func_handler(tep, name); - if (func_handle && func_handle->func == func) { - remove_func_handler(tep, name); - return 0; - } - return -1; -} - -static struct tep_event *search_event(struct tep_handle *tep, int id, - const char *sys_name, - const char *event_name) -{ - struct tep_event *event; - - if (id >= 0) { - /* search by id */ - event = tep_find_event(tep, id); - if (!event) - return NULL; - if (event_name && (strcmp(event_name, event->name) != 0)) - return NULL; - if (sys_name && (strcmp(sys_name, event->system) != 0)) - return NULL; - } else { - event = tep_find_event_by_name(tep, sys_name, event_name); - if (!event) - return NULL; - } - return event; -} - -/** - * tep_register_event_handler - register a way to parse an event - * @tep: a handle to the trace event parser context - * @id: the id of the event to register - * @sys_name: the system name the event belongs to - * @event_name: the name of the event - * @func: the function to call to parse the event information - * @context: the data to be passed to @func - * - * This function allows a developer to override the parsing of - * a given event. If for some reason the default print format - * is not sufficient, this function will register a function - * for an event to be used to parse the data instead. - * - * If @id is >= 0, then it is used to find the event. - * else @sys_name and @event_name are used. - * - * Returns: - * TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler is overwritten - * TEP_REGISTER_SUCCESS if a new handler is registered successfully - * negative TEP_ERRNO_... in case of an error - * - */ -int tep_register_event_handler(struct tep_handle *tep, int id, - const char *sys_name, const char *event_name, - tep_event_handler_func func, void *context) -{ - struct tep_event *event; - struct event_handler *handle; - - event = search_event(tep, id, sys_name, event_name); - if (event == NULL) - goto not_found; - - pr_stat("overriding event (%d) %s:%s with new print handler", - event->id, event->system, event->name); - - event->handler = func; - event->context = context; - return TEP_REGISTER_SUCCESS_OVERWRITE; - - not_found: - /* Save for later use. */ - handle = calloc(1, sizeof(*handle)); - if (!handle) { - do_warning("Failed to allocate event handler"); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - handle->id = id; - if (event_name) - handle->event_name = strdup(event_name); - if (sys_name) - handle->sys_name = strdup(sys_name); - - if ((event_name && !handle->event_name) || - (sys_name && !handle->sys_name)) { - do_warning("Failed to allocate event/sys name"); - free((void *)handle->event_name); - free((void *)handle->sys_name); - free(handle); - return TEP_ERRNO__MEM_ALLOC_FAILED; - } - - handle->func = func; - handle->next = tep->handlers; - tep->handlers = handle; - handle->context = context; - - return TEP_REGISTER_SUCCESS; -} - -static int handle_matches(struct event_handler *handler, int id, - const char *sys_name, const char *event_name, - tep_event_handler_func func, void *context) -{ - if (id >= 0 && id != handler->id) - return 0; - - if (event_name && (strcmp(event_name, handler->event_name) != 0)) - return 0; - - if (sys_name && (strcmp(sys_name, handler->sys_name) != 0)) - return 0; - - if (func != handler->func || context != handler->context) - return 0; - - return 1; -} - -/** - * tep_unregister_event_handler - unregister an existing event handler - * @tep: a handle to the trace event parser context - * @id: the id of the event to unregister - * @sys_name: the system name the handler belongs to - * @event_name: the name of the event handler - * @func: the function to call to parse the event information - * @context: the data to be passed to @func - * - * This function removes existing event handler (parser). - * - * If @id is >= 0, then it is used to find the event. - * else @sys_name and @event_name are used. - * - * Returns 0 if handler was removed successfully, -1 if event was not found. - */ -int tep_unregister_event_handler(struct tep_handle *tep, int id, - const char *sys_name, const char *event_name, - tep_event_handler_func func, void *context) -{ - struct tep_event *event; - struct event_handler *handle; - struct event_handler **next; - - event = search_event(tep, id, sys_name, event_name); - if (event == NULL) - goto not_found; - - if (event->handler == func && event->context == context) { - pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.", - event->id, event->system, event->name); - - event->handler = NULL; - event->context = NULL; - return 0; - } - -not_found: - for (next = &tep->handlers; *next; next = &(*next)->next) { - handle = *next; - if (handle_matches(handle, id, sys_name, event_name, - func, context)) - break; - } - - if (!(*next)) - return -1; - - *next = handle->next; - free_handler(handle); - - return 0; -} - -/** - * tep_alloc - create a tep handle - */ -struct tep_handle *tep_alloc(void) -{ - struct tep_handle *tep = calloc(1, sizeof(*tep)); - - if (tep) { - tep->ref_count = 1; - tep->host_bigendian = tep_is_bigendian(); - } - - return tep; -} - -void tep_ref(struct tep_handle *tep) -{ - tep->ref_count++; -} - -int tep_get_ref(struct tep_handle *tep) -{ - if (tep) - return tep->ref_count; - return 0; -} - -__hidden void free_tep_format_field(struct tep_format_field *field) -{ - free(field->type); - if (field->alias != field->name) - free(field->alias); - free(field->name); - free(field); -} - -static void free_format_fields(struct tep_format_field *field) -{ - struct tep_format_field *next; - - while (field) { - next = field->next; - free_tep_format_field(field); - field = next; - } -} - -static void free_formats(struct tep_format *format) -{ - free_format_fields(format->common_fields); - free_format_fields(format->fields); -} - -__hidden void free_tep_event(struct tep_event *event) -{ - free(event->name); - free(event->system); - - free_formats(&event->format); - - free(event->print_fmt.format); - free_args(event->print_fmt.args); - free_parse_args(event->print_fmt.print_cache); - free(event); -} - -/** - * tep_free - free a tep handle - * @tep: the tep handle to free - */ -void tep_free(struct tep_handle *tep) -{ - struct cmdline_list *cmdlist, *cmdnext; - struct func_list *funclist, *funcnext; - struct printk_list *printklist, *printknext; - struct tep_function_handler *func_handler; - struct event_handler *handle; - int i; - - if (!tep) - return; - - cmdlist = tep->cmdlist; - funclist = tep->funclist; - printklist = tep->printklist; - - tep->ref_count--; - if (tep->ref_count) - return; - - if (tep->cmdlines) { - for (i = 0; i < tep->cmdline_count; i++) - free(tep->cmdlines[i].comm); - free(tep->cmdlines); - } - - while (cmdlist) { - cmdnext = cmdlist->next; - free(cmdlist->comm); - free(cmdlist); - cmdlist = cmdnext; - } - - if (tep->func_map) { - for (i = 0; i < (int)tep->func_count; i++) { - free(tep->func_map[i].func); - free(tep->func_map[i].mod); - } - free(tep->func_map); - } - - while (funclist) { - funcnext = funclist->next; - free(funclist->func); - free(funclist->mod); - free(funclist); - funclist = funcnext; - } - - while (tep->func_handlers) { - func_handler = tep->func_handlers; - tep->func_handlers = func_handler->next; - free_func_handle(func_handler); - } - - if (tep->printk_map) { - for (i = 0; i < (int)tep->printk_count; i++) - free(tep->printk_map[i].printk); - free(tep->printk_map); - } - - while (printklist) { - printknext = printklist->next; - free(printklist->printk); - free(printklist); - printklist = printknext; - } - - for (i = 0; i < tep->nr_events; i++) - free_tep_event(tep->events[i]); - - while (tep->handlers) { - handle = tep->handlers; - tep->handlers = handle->next; - free_handler(handle); - } - - free(tep->events); - free(tep->sort_events); - free(tep->func_resolver); - free_tep_plugin_paths(tep); - - free(tep); -} - -void tep_unref(struct tep_handle *tep) -{ - tep_free(tep); -} diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h deleted file mode 100644 index 41d4f9f6a8436..0000000000000 --- a/tools/lib/traceevent/event-parse.h +++ /dev/null @@ -1,750 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1 */ -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - */ -#ifndef _PARSE_EVENTS_H -#define _PARSE_EVENTS_H - -#include -#include -#include -#include -#include - -#include "trace-seq.h" - -#ifndef __maybe_unused -#define __maybe_unused __attribute__((unused)) -#endif - -#ifndef DEBUG_RECORD -#define DEBUG_RECORD 0 -#endif - -struct tep_record { - unsigned long long ts; - unsigned long long offset; - long long missed_events; /* buffer dropped events before */ - int record_size; /* size of binary record */ - int size; /* size of data */ - void *data; - int cpu; - int ref_count; - int locked; /* Do not free, even if ref_count is zero */ - void *priv; -#if DEBUG_RECORD - struct tep_record *prev; - struct tep_record *next; - long alloc_addr; -#endif -}; - -/* ----------------------- tep ----------------------- */ - -struct tep_handle; -struct tep_event; - -typedef int (*tep_event_handler_func)(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, - void *context); - -typedef int (*tep_plugin_load_func)(struct tep_handle *tep); -typedef int (*tep_plugin_unload_func)(struct tep_handle *tep); - -struct tep_plugin_option { - struct tep_plugin_option *next; - void *handle; - char *file; - char *name; - char *plugin_alias; - char *description; - const char *value; - void *priv; - int set; -}; - -/* - * Plugin hooks that can be called: - * - * TEP_PLUGIN_LOADER: (required) - * The function name to initialized the plugin. - * - * int TEP_PLUGIN_LOADER(struct tep_handle *tep) - * - * TEP_PLUGIN_UNLOADER: (optional) - * The function called just before unloading - * - * int TEP_PLUGIN_UNLOADER(struct tep_handle *tep) - * - * TEP_PLUGIN_OPTIONS: (optional) - * Plugin options that can be set before loading - * - * struct tep_plugin_option TEP_PLUGIN_OPTIONS[] = { - * { - * .name = "option-name", - * .plugin_alias = "override-file-name", (optional) - * .description = "description of option to show users", - * }, - * { - * .name = NULL, - * }, - * }; - * - * Array must end with .name = NULL; - * - * - * .plugin_alias is used to give a shorter name to access - * the vairable. Useful if a plugin handles more than one event. - * - * If .value is not set, then it is considered a boolean and only - * .set will be processed. If .value is defined, then it is considered - * a string option and .set will be ignored. - * - * TEP_PLUGIN_ALIAS: (optional) - * The name to use for finding options (uses filename if not defined) - */ -#define TEP_PLUGIN_LOADER tep_plugin_loader -#define TEP_PLUGIN_UNLOADER tep_plugin_unloader -#define TEP_PLUGIN_OPTIONS tep_plugin_options -#define TEP_PLUGIN_ALIAS tep_plugin_alias -#define _MAKE_STR(x) #x -#define MAKE_STR(x) _MAKE_STR(x) -#define TEP_PLUGIN_LOADER_NAME MAKE_STR(TEP_PLUGIN_LOADER) -#define TEP_PLUGIN_UNLOADER_NAME MAKE_STR(TEP_PLUGIN_UNLOADER) -#define TEP_PLUGIN_OPTIONS_NAME MAKE_STR(TEP_PLUGIN_OPTIONS) -#define TEP_PLUGIN_ALIAS_NAME MAKE_STR(TEP_PLUGIN_ALIAS) - -enum tep_format_flags { - TEP_FIELD_IS_ARRAY = 1, - TEP_FIELD_IS_POINTER = 2, - TEP_FIELD_IS_SIGNED = 4, - TEP_FIELD_IS_STRING = 8, - TEP_FIELD_IS_DYNAMIC = 16, - TEP_FIELD_IS_LONG = 32, - TEP_FIELD_IS_FLAG = 64, - TEP_FIELD_IS_SYMBOLIC = 128, - TEP_FIELD_IS_RELATIVE = 256, -}; - -struct tep_format_field { - struct tep_format_field *next; - struct tep_event *event; - char *type; - char *name; - char *alias; - int offset; - int size; - unsigned int arraylen; - unsigned int elementsize; - unsigned long flags; -}; - -struct tep_format { - int nr_common; - int nr_fields; - struct tep_format_field *common_fields; - struct tep_format_field *fields; -}; - -struct tep_print_arg_atom { - char *atom; -}; - -struct tep_print_arg_string { - char *string; - struct tep_format_field *field; -}; - -struct tep_print_arg_bitmask { - char *bitmask; - struct tep_format_field *field; -}; - -struct tep_print_arg_field { - char *name; - struct tep_format_field *field; -}; - -struct tep_print_flag_sym { - struct tep_print_flag_sym *next; - char *value; - char *str; -}; - -struct tep_print_arg_typecast { - char *type; - struct tep_print_arg *item; -}; - -struct tep_print_arg_flags { - struct tep_print_arg *field; - char *delim; - struct tep_print_flag_sym *flags; -}; - -struct tep_print_arg_symbol { - struct tep_print_arg *field; - struct tep_print_flag_sym *symbols; -}; - -struct tep_print_arg_hex { - struct tep_print_arg *field; - struct tep_print_arg *size; -}; - -struct tep_print_arg_int_array { - struct tep_print_arg *field; - struct tep_print_arg *count; - struct tep_print_arg *el_size; -}; - -struct tep_print_arg_dynarray { - struct tep_format_field *field; - struct tep_print_arg *index; -}; - -struct tep_print_arg; - -struct tep_print_arg_op { - char *op; - int prio; - struct tep_print_arg *left; - struct tep_print_arg *right; -}; - -struct tep_function_handler; - -struct tep_print_arg_func { - struct tep_function_handler *func; - struct tep_print_arg *args; -}; - -enum tep_print_arg_type { - TEP_PRINT_NULL, - TEP_PRINT_ATOM, - TEP_PRINT_FIELD, - TEP_PRINT_FLAGS, - TEP_PRINT_SYMBOL, - TEP_PRINT_HEX, - TEP_PRINT_INT_ARRAY, - TEP_PRINT_TYPE, - TEP_PRINT_STRING, - TEP_PRINT_BSTRING, - TEP_PRINT_DYNAMIC_ARRAY, - TEP_PRINT_OP, - TEP_PRINT_FUNC, - TEP_PRINT_BITMASK, - TEP_PRINT_DYNAMIC_ARRAY_LEN, - TEP_PRINT_HEX_STR, -}; - -struct tep_print_arg { - struct tep_print_arg *next; - enum tep_print_arg_type type; - union { - struct tep_print_arg_atom atom; - struct tep_print_arg_field field; - struct tep_print_arg_typecast typecast; - struct tep_print_arg_flags flags; - struct tep_print_arg_symbol symbol; - struct tep_print_arg_hex hex; - struct tep_print_arg_int_array int_array; - struct tep_print_arg_func func; - struct tep_print_arg_string string; - struct tep_print_arg_bitmask bitmask; - struct tep_print_arg_op op; - struct tep_print_arg_dynarray dynarray; - }; -}; - -struct tep_print_parse; - -struct tep_print_fmt { - char *format; - struct tep_print_arg *args; - struct tep_print_parse *print_cache; -}; - -struct tep_event { - struct tep_handle *tep; - char *name; - int id; - int flags; - struct tep_format format; - struct tep_print_fmt print_fmt; - char *system; - tep_event_handler_func handler; - void *context; -}; - -enum { - TEP_EVENT_FL_ISFTRACE = 0x01, - TEP_EVENT_FL_ISPRINT = 0x02, - TEP_EVENT_FL_ISBPRINT = 0x04, - TEP_EVENT_FL_ISFUNCENT = 0x10, - TEP_EVENT_FL_ISFUNCRET = 0x20, - TEP_EVENT_FL_NOHANDLE = 0x40, - TEP_EVENT_FL_PRINTRAW = 0x80, - - TEP_EVENT_FL_FAILED = 0x80000000 -}; - -enum tep_event_sort_type { - TEP_EVENT_SORT_ID, - TEP_EVENT_SORT_NAME, - TEP_EVENT_SORT_SYSTEM, -}; - -enum tep_event_type { - TEP_EVENT_ERROR, - TEP_EVENT_NONE, - TEP_EVENT_SPACE, - TEP_EVENT_NEWLINE, - TEP_EVENT_OP, - TEP_EVENT_DELIM, - TEP_EVENT_ITEM, - TEP_EVENT_DQUOTE, - TEP_EVENT_SQUOTE, -}; - -typedef unsigned long long (*tep_func_handler)(struct trace_seq *s, - unsigned long long *args); - -enum tep_func_arg_type { - TEP_FUNC_ARG_VOID, - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_LONG, - TEP_FUNC_ARG_STRING, - TEP_FUNC_ARG_PTR, - TEP_FUNC_ARG_MAX_TYPES -}; - -enum tep_flag { - TEP_NSEC_OUTPUT = 1, /* output in NSECS */ - TEP_DISABLE_SYS_PLUGINS = 1 << 1, - TEP_DISABLE_PLUGINS = 1 << 2, -}; - -#define TEP_ERRORS \ - _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \ - _PE(PARSE_EVENT_FAILED, "failed to parse event"), \ - _PE(READ_ID_FAILED, "failed to read event id"), \ - _PE(READ_FORMAT_FAILED, "failed to read event format"), \ - _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ - _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ - _PE(INVALID_ARG_TYPE, "invalid argument type"), \ - _PE(INVALID_EXP_TYPE, "invalid expression type"), \ - _PE(INVALID_OP_TYPE, "invalid operator type"), \ - _PE(INVALID_EVENT_NAME, "invalid event name"), \ - _PE(EVENT_NOT_FOUND, "no event found"), \ - _PE(SYNTAX_ERROR, "syntax error"), \ - _PE(ILLEGAL_RVALUE, "illegal rvalue"), \ - _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \ - _PE(INVALID_REGEX, "regex did not compute"), \ - _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \ - _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \ - _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \ - _PE(REPARENT_FAILED, "failed to reparent filter OP"), \ - _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \ - _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \ - _PE(ILLEGAL_TOKEN, "illegal token"), \ - _PE(INVALID_PAREN, "open parenthesis cannot come here"), \ - _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \ - _PE(UNKNOWN_TOKEN, "unknown token"), \ - _PE(FILTER_NOT_FOUND, "no filter found"), \ - _PE(NOT_A_NUMBER, "must have number field"), \ - _PE(NO_FILTER, "no filters exists"), \ - _PE(FILTER_MISS, "record does not match to filter") - -#undef _PE -#define _PE(__code, __str) TEP_ERRNO__ ## __code -enum tep_errno { - TEP_ERRNO__SUCCESS = 0, - TEP_ERRNO__FILTER_MATCH = TEP_ERRNO__SUCCESS, - - /* - * Choose an arbitrary negative big number not to clash with standard - * errno since SUS requires the errno has distinct positive values. - * See 'Issue 6' in the link below. - * - * https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html - */ - __TEP_ERRNO__START = -100000, - - TEP_ERRORS, - - __TEP_ERRNO__END, -}; -#undef _PE - -struct tep_plugin_list; - -#define INVALID_PLUGIN_LIST_OPTION ((char **)((unsigned long)-1)) - -enum tep_plugin_load_priority { - TEP_PLUGIN_FIRST, - TEP_PLUGIN_LAST, -}; - -int tep_add_plugin_path(struct tep_handle *tep, char *path, - enum tep_plugin_load_priority prio); -struct tep_plugin_list *tep_load_plugins(struct tep_handle *tep); -void tep_unload_plugins(struct tep_plugin_list *plugin_list, - struct tep_handle *tep); -void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix, - void (*load_plugin)(struct tep_handle *tep, - const char *path, - const char *name, - void *data), - void *data); -char **tep_plugin_list_options(void); -void tep_plugin_free_options_list(char **list); -int tep_plugin_add_options(const char *name, - struct tep_plugin_option *options); -int tep_plugin_add_option(const char *name, const char *val); -void tep_plugin_remove_options(struct tep_plugin_option *options); -void tep_plugin_print_options(struct trace_seq *s); -void tep_print_plugins(struct trace_seq *s, - const char *prefix, const char *suffix, - const struct tep_plugin_list *list); - -/* tep_handle */ -typedef char *(tep_func_resolver_t)(void *priv, - unsigned long long *addrp, char **modp); -void tep_set_flag(struct tep_handle *tep, int flag); -void tep_clear_flag(struct tep_handle *tep, enum tep_flag flag); -bool tep_test_flag(struct tep_handle *tep, enum tep_flag flags); - -static inline int tep_is_bigendian(void) -{ - unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 }; - unsigned int val; - - memcpy(&val, str, 4); - return val == 0x01020304; -} - -/* taken from kernel/trace/trace.h */ -enum trace_flag_type { - TRACE_FLAG_IRQS_OFF = 0x01, - TRACE_FLAG_IRQS_NOSUPPORT = 0x02, - TRACE_FLAG_NEED_RESCHED = 0x04, - TRACE_FLAG_HARDIRQ = 0x08, - TRACE_FLAG_SOFTIRQ = 0x10, -}; - -int tep_set_function_resolver(struct tep_handle *tep, - tep_func_resolver_t *func, void *priv); -void tep_reset_function_resolver(struct tep_handle *tep); -int tep_register_comm(struct tep_handle *tep, const char *comm, int pid); -int tep_override_comm(struct tep_handle *tep, const char *comm, int pid); -int tep_register_function(struct tep_handle *tep, char *name, - unsigned long long addr, char *mod); -int tep_register_print_string(struct tep_handle *tep, const char *fmt, - unsigned long long addr); -bool tep_is_pid_registered(struct tep_handle *tep, int pid); - -struct tep_event *tep_get_event(struct tep_handle *tep, int index); - -#define TEP_PRINT_INFO "INFO" -#define TEP_PRINT_INFO_RAW "INFO_RAW" -#define TEP_PRINT_COMM "COMM" -#define TEP_PRINT_LATENCY "LATENCY" -#define TEP_PRINT_NAME "NAME" -#define TEP_PRINT_PID 1U -#define TEP_PRINT_TIME 2U -#define TEP_PRINT_CPU 3U - -void tep_print_event(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, const char *fmt, ...) - __attribute__ ((format (printf, 4, 5))); - -int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, - int long_size); - -enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf, - unsigned long size, const char *sys); -enum tep_errno tep_parse_format(struct tep_handle *tep, - struct tep_event **eventp, - const char *buf, - unsigned long size, const char *sys); - -void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - int *len, int err); - -int tep_get_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err); -int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err); -int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event, - const char *name, struct tep_record *record, - unsigned long long *val, int err); - -int tep_print_num_field(struct trace_seq *s, const char *fmt, - struct tep_event *event, const char *name, - struct tep_record *record, int err); - -int tep_print_func_field(struct trace_seq *s, const char *fmt, - struct tep_event *event, const char *name, - struct tep_record *record, int err); - -enum tep_reg_handler { - TEP_REGISTER_SUCCESS = 0, - TEP_REGISTER_SUCCESS_OVERWRITE, -}; - -int tep_register_event_handler(struct tep_handle *tep, int id, - const char *sys_name, const char *event_name, - tep_event_handler_func func, void *context); -int tep_unregister_event_handler(struct tep_handle *tep, int id, - const char *sys_name, const char *event_name, - tep_event_handler_func func, void *context); -int tep_register_print_function(struct tep_handle *tep, - tep_func_handler func, - enum tep_func_arg_type ret_type, - char *name, ...); -int tep_unregister_print_function(struct tep_handle *tep, - tep_func_handler func, char *name); - -struct tep_format_field *tep_find_common_field(struct tep_event *event, const char *name); -struct tep_format_field *tep_find_field(struct tep_event *event, const char *name); -struct tep_format_field *tep_find_any_field(struct tep_event *event, const char *name); - -const char *tep_find_function(struct tep_handle *tep, unsigned long long addr); -unsigned long long -tep_find_function_address(struct tep_handle *tep, unsigned long long addr); -unsigned long long tep_read_number(struct tep_handle *tep, const void *ptr, int size); -int tep_read_number_field(struct tep_format_field *field, const void *data, - unsigned long long *value); - -struct tep_event *tep_get_first_event(struct tep_handle *tep); -int tep_get_events_count(struct tep_handle *tep); -struct tep_event *tep_find_event(struct tep_handle *tep, int id); - -struct tep_event * -tep_find_event_by_name(struct tep_handle *tep, const char *sys, const char *name); -struct tep_event * -tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record); - -int tep_data_type(struct tep_handle *tep, struct tep_record *rec); -int tep_data_pid(struct tep_handle *tep, struct tep_record *rec); -int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec); -int tep_data_flags(struct tep_handle *tep, struct tep_record *rec); -const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid); -struct tep_cmdline; -struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm, - struct tep_cmdline *next); -int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline); - -void tep_print_field(struct trace_seq *s, void *data, - struct tep_format_field *field); -void tep_print_fields(struct trace_seq *s, void *data, - int size __maybe_unused, struct tep_event *event); -int tep_strerror(struct tep_handle *tep, enum tep_errno errnum, - char *buf, size_t buflen); - -struct tep_event **tep_list_events(struct tep_handle *tep, enum tep_event_sort_type); -struct tep_event **tep_list_events_copy(struct tep_handle *tep, - enum tep_event_sort_type); -struct tep_format_field **tep_event_common_fields(struct tep_event *event); -struct tep_format_field **tep_event_fields(struct tep_event *event); - -enum tep_endian { - TEP_LITTLE_ENDIAN = 0, - TEP_BIG_ENDIAN -}; -int tep_get_cpus(struct tep_handle *tep); -void tep_set_cpus(struct tep_handle *tep, int cpus); -int tep_get_long_size(struct tep_handle *tep); -void tep_set_long_size(struct tep_handle *tep, int long_size); -int tep_get_page_size(struct tep_handle *tep); -void tep_set_page_size(struct tep_handle *tep, int _page_size); -bool tep_is_file_bigendian(struct tep_handle *tep); -void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); -bool tep_is_local_bigendian(struct tep_handle *tep); -void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian); -int tep_get_header_page_size(struct tep_handle *tep); -int tep_get_header_timestamp_size(struct tep_handle *tep); -bool tep_is_old_format(struct tep_handle *tep); -void tep_set_test_filters(struct tep_handle *tep, int test_filters); - -struct tep_handle *tep_alloc(void); -void tep_free(struct tep_handle *tep); -void tep_ref(struct tep_handle *tep); -void tep_unref(struct tep_handle *tep); -int tep_get_ref(struct tep_handle *tep); - -/* for debugging */ -void tep_print_funcs(struct tep_handle *tep); -void tep_print_printk(struct tep_handle *tep); - -/* ----------------------- filtering ----------------------- */ - -enum tep_filter_boolean_type { - TEP_FILTER_FALSE, - TEP_FILTER_TRUE, -}; - -enum tep_filter_op_type { - TEP_FILTER_OP_AND = 1, - TEP_FILTER_OP_OR, - TEP_FILTER_OP_NOT, -}; - -enum tep_filter_cmp_type { - TEP_FILTER_CMP_NONE, - TEP_FILTER_CMP_EQ, - TEP_FILTER_CMP_NE, - TEP_FILTER_CMP_GT, - TEP_FILTER_CMP_LT, - TEP_FILTER_CMP_GE, - TEP_FILTER_CMP_LE, - TEP_FILTER_CMP_MATCH, - TEP_FILTER_CMP_NOT_MATCH, - TEP_FILTER_CMP_REGEX, - TEP_FILTER_CMP_NOT_REGEX, -}; - -enum tep_filter_exp_type { - TEP_FILTER_EXP_NONE, - TEP_FILTER_EXP_ADD, - TEP_FILTER_EXP_SUB, - TEP_FILTER_EXP_MUL, - TEP_FILTER_EXP_DIV, - TEP_FILTER_EXP_MOD, - TEP_FILTER_EXP_RSHIFT, - TEP_FILTER_EXP_LSHIFT, - TEP_FILTER_EXP_AND, - TEP_FILTER_EXP_OR, - TEP_FILTER_EXP_XOR, - TEP_FILTER_EXP_NOT, -}; - -enum tep_filter_arg_type { - TEP_FILTER_ARG_NONE, - TEP_FILTER_ARG_BOOLEAN, - TEP_FILTER_ARG_VALUE, - TEP_FILTER_ARG_FIELD, - TEP_FILTER_ARG_EXP, - TEP_FILTER_ARG_OP, - TEP_FILTER_ARG_NUM, - TEP_FILTER_ARG_STR, -}; - -enum tep_filter_value_type { - TEP_FILTER_NUMBER, - TEP_FILTER_STRING, - TEP_FILTER_CHAR -}; - -struct tep_filter_arg; - -struct tep_filter_arg_boolean { - enum tep_filter_boolean_type value; -}; - -struct tep_filter_arg_field { - struct tep_format_field *field; -}; - -struct tep_filter_arg_value { - enum tep_filter_value_type type; - union { - char *str; - unsigned long long val; - }; -}; - -struct tep_filter_arg_op { - enum tep_filter_op_type type; - struct tep_filter_arg *left; - struct tep_filter_arg *right; -}; - -struct tep_filter_arg_exp { - enum tep_filter_exp_type type; - struct tep_filter_arg *left; - struct tep_filter_arg *right; -}; - -struct tep_filter_arg_num { - enum tep_filter_cmp_type type; - struct tep_filter_arg *left; - struct tep_filter_arg *right; -}; - -struct tep_filter_arg_str { - enum tep_filter_cmp_type type; - struct tep_format_field *field; - char *val; - char *buffer; - regex_t reg; -}; - -struct tep_filter_arg { - enum tep_filter_arg_type type; - union { - struct tep_filter_arg_boolean boolean; - struct tep_filter_arg_field field; - struct tep_filter_arg_value value; - struct tep_filter_arg_op op; - struct tep_filter_arg_exp exp; - struct tep_filter_arg_num num; - struct tep_filter_arg_str str; - }; -}; - -struct tep_filter_type { - int event_id; - struct tep_event *event; - struct tep_filter_arg *filter; -}; - -#define TEP_FILTER_ERROR_BUFSZ 1024 - -struct tep_event_filter { - struct tep_handle *tep; - int filters; - struct tep_filter_type *event_filters; - char error_buffer[TEP_FILTER_ERROR_BUFSZ]; -}; - -struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep); - -/* for backward compatibility */ -#define FILTER_NONE TEP_ERRNO__NO_FILTER -#define FILTER_NOEXIST TEP_ERRNO__FILTER_NOT_FOUND -#define FILTER_MISS TEP_ERRNO__FILTER_MISS -#define FILTER_MATCH TEP_ERRNO__FILTER_MATCH - -enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter, - const char *filter_str); - -enum tep_errno tep_filter_match(struct tep_event_filter *filter, - struct tep_record *record); - -int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err, - char *buf, size_t buflen); - -int tep_event_filtered(struct tep_event_filter *filter, - int event_id); - -void tep_filter_reset(struct tep_event_filter *filter); - -void tep_filter_free(struct tep_event_filter *filter); - -char *tep_filter_make_string(struct tep_event_filter *filter, int event_id); - -int tep_filter_remove_event(struct tep_event_filter *filter, - int event_id); - -int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source); - -int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2); - -#endif /* _PARSE_EVENTS_H */ diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c deleted file mode 100644 index e7f93d5fe4fd0..0000000000000 --- a/tools/lib/traceevent/event-plugin.c +++ /dev/null @@ -1,711 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "event-parse.h" -#include "event-parse-local.h" -#include "event-utils.h" -#include "trace-seq.h" - -#define LOCAL_PLUGIN_DIR ".local/lib/traceevent/plugins/" - -static struct registered_plugin_options { - struct registered_plugin_options *next; - struct tep_plugin_option *options; -} *registered_options; - -static struct trace_plugin_options { - struct trace_plugin_options *next; - char *plugin; - char *option; - char *value; -} *trace_plugin_options; - -struct tep_plugin_list { - struct tep_plugin_list *next; - char *name; - void *handle; -}; - -struct tep_plugins_dir { - struct tep_plugins_dir *next; - char *path; - enum tep_plugin_load_priority prio; -}; - -static void lower_case(char *str) -{ - if (!str) - return; - for (; *str; str++) - *str = tolower(*str); -} - -static int update_option_value(struct tep_plugin_option *op, const char *val) -{ - char *op_val; - - if (!val) { - /* toggle, only if option is boolean */ - if (op->value) - /* Warn? */ - return 0; - op->set ^= 1; - return 0; - } - - /* - * If the option has a value then it takes a string - * otherwise the option is a boolean. - */ - if (op->value) { - op->value = val; - return 0; - } - - /* Option is boolean, must be either "1", "0", "true" or "false" */ - - op_val = strdup(val); - if (!op_val) - return -1; - lower_case(op_val); - - if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0) - op->set = 1; - else if (strcmp(val, "0") == 0 || strcmp(val, "false") == 0) - op->set = 0; - free(op_val); - - return 0; -} - -/** - * tep_plugin_list_options - get list of plugin options - * - * Returns an array of char strings that list the currently registered - * plugin options in the format of :