diff options
author | Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com> | 2014-06-04 09:57:50 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-09 17:14:27 -0400 |
commit | c1f732ad767e37bd1d41043cbdefc0874b4d05e5 (patch) | |
tree | e4e80d6cd088b93acdb7d8078bb7d726a37f8ffc | |
parent | fc51768ba24077c8148067036e1555a8a978bb99 (diff) |
GenWQE: Add sysfs interface for bitstream reload
This patch adds an interface on sysfs for userspace to request a card
bitstream reload. It sets the appropriate register and try to perform a
fundamental reset on the PCIe slot for the card to reload the bitstream
from the chosen partition.
Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com>
Acked-by: Frank Haverkamp <haver@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | Documentation/ABI/testing/sysfs-driver-genwqe | 9 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_base.c | 90 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_sysfs.c | 25 | ||||
-rw-r--r-- | include/uapi/linux/genwqe/genwqe_card.h | 1 |
4 files changed, 125 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-genwqe b/Documentation/ABI/testing/sysfs-driver-genwqe index 1870737a1f5e..64ac6d567c4b 100644 --- a/Documentation/ABI/testing/sysfs-driver-genwqe +++ b/Documentation/ABI/testing/sysfs-driver-genwqe | |||
@@ -25,6 +25,15 @@ Date: Oct 2013 | |||
25 | Contact: haver@linux.vnet.ibm.com | 25 | Contact: haver@linux.vnet.ibm.com |
26 | Description: Interface to set the next bitstream to be used. | 26 | Description: Interface to set the next bitstream to be used. |
27 | 27 | ||
28 | What: /sys/class/genwqe/genwqe<n>_card/reload_bitstream | ||
29 | Date: May 2014 | ||
30 | Contact: klebers@linux.vnet.ibm.com | ||
31 | Description: Interface to trigger a PCIe card reset to reload the bitstream. | ||
32 | sudo sh -c 'echo 1 > \ | ||
33 | /sys/class/genwqe/genwqe0_card/reload_bitstream' | ||
34 | If successfully, the card will come back with the bitstream set | ||
35 | on 'next_bitstream'. | ||
36 | |||
28 | What: /sys/class/genwqe/genwqe<n>_card/tempsens | 37 | What: /sys/class/genwqe/genwqe<n>_card/tempsens |
29 | Date: Oct 2013 | 38 | Date: Oct 2013 |
30 | Contact: haver@linux.vnet.ibm.com | 39 | Contact: haver@linux.vnet.ibm.com |
diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 74d51c9bb858..e6cc3e1e7326 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c | |||
@@ -761,6 +761,89 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd) | |||
761 | } | 761 | } |
762 | 762 | ||
763 | /** | 763 | /** |
764 | * genwqe_pci_fundamental_reset() - trigger a PCIe fundamental reset on the slot | ||
765 | * | ||
766 | * Note: pci_set_pcie_reset_state() is not implemented on all archs, so this | ||
767 | * reset method will not work in all cases. | ||
768 | * | ||
769 | * Return: 0 on success or error code from pci_set_pcie_reset_state() | ||
770 | */ | ||
771 | static int genwqe_pci_fundamental_reset(struct pci_dev *pci_dev) | ||
772 | { | ||
773 | int rc; | ||
774 | |||
775 | /* | ||
776 | * lock pci config space access from userspace, | ||
777 | * save state and issue PCIe fundamental reset | ||
778 | */ | ||
779 | pci_cfg_access_lock(pci_dev); | ||
780 | pci_save_state(pci_dev); | ||
781 | rc = pci_set_pcie_reset_state(pci_dev, pcie_warm_reset); | ||
782 | if (!rc) { | ||
783 | /* keep PCIe reset asserted for 250ms */ | ||
784 | msleep(250); | ||
785 | pci_set_pcie_reset_state(pci_dev, pcie_deassert_reset); | ||
786 | /* Wait for 2s to reload flash and train the link */ | ||
787 | msleep(2000); | ||
788 | } | ||
789 | pci_restore_state(pci_dev); | ||
790 | pci_cfg_access_unlock(pci_dev); | ||
791 | return rc; | ||
792 | } | ||
793 | |||
794 | /* | ||
795 | * genwqe_reload_bistream() - reload card bitstream | ||
796 | * | ||
797 | * Set the appropriate register and call fundamental reset to reaload the card | ||
798 | * bitstream. | ||
799 | * | ||
800 | * Return: 0 on success, error code otherwise | ||
801 | */ | ||
802 | static int genwqe_reload_bistream(struct genwqe_dev *cd) | ||
803 | { | ||
804 | struct pci_dev *pci_dev = cd->pci_dev; | ||
805 | int rc; | ||
806 | |||
807 | dev_info(&pci_dev->dev, | ||
808 | "[%s] resetting card for bitstream reload\n", | ||
809 | __func__); | ||
810 | |||
811 | genwqe_stop(cd); | ||
812 | |||
813 | /* | ||
814 | * Cause a CPLD reprogram with the 'next_bitstream' | ||
815 | * partition on PCIe hot or fundamental reset | ||
816 | */ | ||
817 | __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, | ||
818 | (cd->softreset & 0xcull) | 0x70ull); | ||
819 | |||
820 | rc = genwqe_pci_fundamental_reset(pci_dev); | ||
821 | if (rc) { | ||
822 | /* | ||
823 | * A fundamental reset failure can be caused | ||
824 | * by lack of support on the arch, so we just | ||
825 | * log the error and try to start the card | ||
826 | * again. | ||
827 | */ | ||
828 | dev_err(&pci_dev->dev, | ||
829 | "[%s] err: failed to reset card for bitstream reload\n", | ||
830 | __func__); | ||
831 | } | ||
832 | |||
833 | rc = genwqe_start(cd); | ||
834 | if (rc) { | ||
835 | dev_err(&pci_dev->dev, | ||
836 | "[%s] err: cannot start card services! (err=%d)\n", | ||
837 | __func__, rc); | ||
838 | return rc; | ||
839 | } | ||
840 | dev_info(&pci_dev->dev, | ||
841 | "[%s] card reloaded\n", __func__); | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | |||
846 | /** | ||
764 | * genwqe_health_thread() - Health checking thread | 847 | * genwqe_health_thread() - Health checking thread |
765 | * | 848 | * |
766 | * This thread is only started for the PF of the card. | 849 | * This thread is only started for the PF of the card. |
@@ -846,6 +929,13 @@ static int genwqe_health_thread(void *data) | |||
846 | } | 929 | } |
847 | } | 930 | } |
848 | 931 | ||
932 | if (cd->card_state == GENWQE_CARD_RELOAD_BITSTREAM) { | ||
933 | /* Userspace requested card bitstream reload */ | ||
934 | rc = genwqe_reload_bistream(cd); | ||
935 | if (rc) | ||
936 | goto fatal_error; | ||
937 | } | ||
938 | |||
849 | cd->last_gfir = gfir; | 939 | cd->last_gfir = gfir; |
850 | cond_resched(); | 940 | cond_resched(); |
851 | } | 941 | } |
diff --git a/drivers/misc/genwqe/card_sysfs.c b/drivers/misc/genwqe/card_sysfs.c index a72a99266c3c..7232e40a3ad9 100644 --- a/drivers/misc/genwqe/card_sysfs.c +++ b/drivers/misc/genwqe/card_sysfs.c | |||
@@ -223,6 +223,30 @@ static ssize_t next_bitstream_store(struct device *dev, | |||
223 | } | 223 | } |
224 | static DEVICE_ATTR_RW(next_bitstream); | 224 | static DEVICE_ATTR_RW(next_bitstream); |
225 | 225 | ||
226 | static ssize_t reload_bitstream_store(struct device *dev, | ||
227 | struct device_attribute *attr, | ||
228 | const char *buf, size_t count) | ||
229 | { | ||
230 | int reload; | ||
231 | struct genwqe_dev *cd = dev_get_drvdata(dev); | ||
232 | |||
233 | if (kstrtoint(buf, 0, &reload) < 0) | ||
234 | return -EINVAL; | ||
235 | |||
236 | if (reload == 0x1) { | ||
237 | if (cd->card_state == GENWQE_CARD_UNUSED || | ||
238 | cd->card_state == GENWQE_CARD_USED) | ||
239 | cd->card_state = GENWQE_CARD_RELOAD_BITSTREAM; | ||
240 | else | ||
241 | return -EIO; | ||
242 | } else { | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | |||
246 | return count; | ||
247 | } | ||
248 | static DEVICE_ATTR_WO(reload_bitstream); | ||
249 | |||
226 | /* | 250 | /* |
227 | * Create device_attribute structures / params: name, mode, show, store | 251 | * Create device_attribute structures / params: name, mode, show, store |
228 | * additional flag if valid in VF | 252 | * additional flag if valid in VF |
@@ -239,6 +263,7 @@ static struct attribute *genwqe_attributes[] = { | |||
239 | &dev_attr_status.attr, | 263 | &dev_attr_status.attr, |
240 | &dev_attr_freerunning_timer.attr, | 264 | &dev_attr_freerunning_timer.attr, |
241 | &dev_attr_queue_working_time.attr, | 265 | &dev_attr_queue_working_time.attr, |
266 | &dev_attr_reload_bitstream.attr, | ||
242 | NULL, | 267 | NULL, |
243 | }; | 268 | }; |
244 | 269 | ||
diff --git a/include/uapi/linux/genwqe/genwqe_card.h b/include/uapi/linux/genwqe/genwqe_card.h index 795e957bb840..4fc065f29255 100644 --- a/include/uapi/linux/genwqe/genwqe_card.h +++ b/include/uapi/linux/genwqe/genwqe_card.h | |||
@@ -328,6 +328,7 @@ enum genwqe_card_state { | |||
328 | GENWQE_CARD_UNUSED = 0, | 328 | GENWQE_CARD_UNUSED = 0, |
329 | GENWQE_CARD_USED = 1, | 329 | GENWQE_CARD_USED = 1, |
330 | GENWQE_CARD_FATAL_ERROR = 2, | 330 | GENWQE_CARD_FATAL_ERROR = 2, |
331 | GENWQE_CARD_RELOAD_BITSTREAM = 3, | ||
331 | GENWQE_CARD_STATE_MAX, | 332 | GENWQE_CARD_STATE_MAX, |
332 | }; | 333 | }; |
333 | 334 | ||