Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NTB: switchtec_ntb: Introduce initial NTB driver

Seeing the Switchtec NTB hardware shares the same endpoint as the
management endpoint we utilize the class_interface API to register
an NTB driver for every Switchtec device in the system that has the
NTB class code.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Stephen Bates <sbates@raithlin.com>
Reviewed-by: Kurt Schwemmer <kurt.schwemmer@microsemi.com>
Acked-by: Allen Hubbe <Allen.Hubbe@dell.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>

authored by

Logan Gunthorpe and committed by
Jon Mason
33dea5aa fa5ab66e

+101
+1
MAINTAINERS
··· 10348 10348 F: drivers/pci/switch/switchtec* 10349 10349 F: include/uapi/linux/switchtec_ioctl.h 10350 10350 F: include/linux/switchtec.h 10351 + F: drivers/ntb/hw/mscc/ 10351 10352 10352 10353 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support) 10353 10354 M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+1
drivers/ntb/hw/Kconfig
··· 1 1 source "drivers/ntb/hw/amd/Kconfig" 2 2 source "drivers/ntb/hw/idt/Kconfig" 3 3 source "drivers/ntb/hw/intel/Kconfig" 4 + source "drivers/ntb/hw/mscc/Kconfig"
+1
drivers/ntb/hw/Makefile
··· 1 1 obj-$(CONFIG_NTB_AMD) += amd/ 2 2 obj-$(CONFIG_NTB_IDT) += idt/ 3 3 obj-$(CONFIG_NTB_INTEL) += intel/ 4 + obj-$(CONFIG_NTB_SWITCHTEC) += mscc/
+9
drivers/ntb/hw/mscc/Kconfig
··· 1 + config NTB_SWITCHTEC 2 + tristate "MicroSemi Switchtec Non-Transparent Bridge Support" 3 + select PCI_SW_SWITCHTEC 4 + help 5 + Enables NTB support for Switchtec PCI switches. This also 6 + selects the Switchtec management driver as they share the same 7 + hardware interface. 8 + 9 + If unsure, say N.
+1
drivers/ntb/hw/mscc/Makefile
··· 1 + obj-$(CONFIG_NTB_SWITCHTEC) += ntb_hw_switchtec.o
+81
drivers/ntb/hw/mscc/ntb_hw_switchtec.c
··· 1 + /* 2 + * Microsemi Switchtec(tm) PCIe Management Driver 3 + * Copyright (c) 2017, Microsemi Corporation 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + */ 15 + 16 + #include <linux/switchtec.h> 17 + #include <linux/module.h> 18 + 19 + MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver"); 20 + MODULE_VERSION("0.1"); 21 + MODULE_LICENSE("GPL"); 22 + MODULE_AUTHOR("Microsemi Corporation"); 23 + 24 + struct switchtec_ntb { 25 + struct switchtec_dev *stdev; 26 + }; 27 + 28 + static int switchtec_ntb_add(struct device *dev, 29 + struct class_interface *class_intf) 30 + { 31 + struct switchtec_dev *stdev = to_stdev(dev); 32 + struct switchtec_ntb *sndev; 33 + 34 + stdev->sndev = NULL; 35 + 36 + if (stdev->pdev->class != MICROSEMI_NTB_CLASSCODE) 37 + return -ENODEV; 38 + 39 + sndev = kzalloc_node(sizeof(*sndev), GFP_KERNEL, dev_to_node(dev)); 40 + if (!sndev) 41 + return -ENOMEM; 42 + 43 + sndev->stdev = stdev; 44 + 45 + stdev->sndev = sndev; 46 + dev_info(dev, "NTB device registered"); 47 + 48 + return 0; 49 + } 50 + 51 + void switchtec_ntb_remove(struct device *dev, 52 + struct class_interface *class_intf) 53 + { 54 + struct switchtec_dev *stdev = to_stdev(dev); 55 + struct switchtec_ntb *sndev = stdev->sndev; 56 + 57 + if (!sndev) 58 + return; 59 + 60 + stdev->sndev = NULL; 61 + kfree(sndev); 62 + dev_info(dev, "ntb device unregistered"); 63 + } 64 + 65 + static struct class_interface switchtec_interface = { 66 + .add_dev = switchtec_ntb_add, 67 + .remove_dev = switchtec_ntb_remove, 68 + }; 69 + 70 + static int __init switchtec_ntb_init(void) 71 + { 72 + switchtec_interface.class = switchtec_class; 73 + return class_interface_register(&switchtec_interface); 74 + } 75 + module_init(switchtec_ntb_init); 76 + 77 + static void __exit switchtec_ntb_exit(void) 78 + { 79 + class_interface_unregister(&switchtec_interface); 80 + } 81 + module_exit(switchtec_ntb_exit);
+3
drivers/pci/switch/switchtec.c
··· 1275 1275 struct switchtec_dev *stdev; 1276 1276 int rc; 1277 1277 1278 + if (pdev->class == MICROSEMI_NTB_CLASSCODE) 1279 + request_module_nowait("ntb_hw_switchtec"); 1280 + 1278 1281 stdev = stdev_create(pdev); 1279 1282 if (IS_ERR(stdev)) 1280 1283 return PTR_ERR(stdev);
+4
include/linux/switchtec.h
··· 320 320 u32 reserved4[174]; 321 321 } __packed; 322 322 323 + struct switchtec_ntb; 324 + 323 325 struct switchtec_dev { 324 326 struct pci_dev *pdev; 325 327 struct device dev; ··· 359 357 struct work_struct link_event_work; 360 358 void (*link_notifier)(struct switchtec_dev *stdev); 361 359 u8 link_event_count[SWITCHTEC_MAX_PFF_CSR]; 360 + 361 + struct switchtec_ntb *sndev; 362 362 }; 363 363 364 364 static inline struct switchtec_dev *to_stdev(struct device *dev)