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

Merge branch 'ptp-ocxp-Oroli-ART-CARD'

Vadim Fedorenko says:

====================
ptp: ocp: add support for Orolia ART-CARD

Orolia company created alternative open source TimeCard. The hardware of
the card provides similar to OCP's card functions, that's why the support
is added to current driver.

The first patch in the series changes the way to store information about
serial ports and is more like preparation.

The patches 2 to 4 introduces actual hardware support.

The last patch removes fallback from devlink flashing interface to protect
against flashing wrong image. This became actual now as we have 2 different
boards supported and wrong image can ruin hardware easily.

v2:
Address comments from Jonathan Lemon

v3:
Fix issue reported by kernel test robot <lkp@intel.com>

v4:
Fix clang build issue

v5:
Fix warnings and per-patch build errors

v6:
Fix more style issues
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+515 -48
+515 -48
drivers/ptp/ptp_ocp.c
··· 13 13 #include <linux/clk-provider.h> 14 14 #include <linux/platform_device.h> 15 15 #include <linux/platform_data/i2c-xiic.h> 16 + #include <linux/platform_data/i2c-ocores.h> 16 17 #include <linux/ptp_clock_kernel.h> 17 18 #include <linux/spi/spi.h> 18 19 #include <linux/spi/xilinx_spi.h> 20 + #include <linux/spi/altera.h> 19 21 #include <net/devlink.h> 20 22 #include <linux/i2c.h> 21 23 #include <linux/mtd/mtd.h> ··· 29 27 30 28 #define PCI_VENDOR_ID_CELESTICA 0x18d4 31 29 #define PCI_DEVICE_ID_CELESTICA_TIMECARD 0x1008 30 + 31 + #define PCI_VENDOR_ID_OROLIA 0x1ad7 32 + #define PCI_DEVICE_ID_OROLIA_ARTCARD 0xa000 32 33 33 34 static struct class timecard_class = { 34 35 .owner = THIS_MODULE, ··· 208 203 u32 ctrl; 209 204 u32 status; 210 205 }; 206 + 207 + struct board_config_reg { 208 + u32 mro50_serial_activate; 209 + }; 210 + 211 211 #define FREQ_STATUS_VALID BIT(31) 212 212 #define FREQ_STATUS_ERROR BIT(30) 213 213 #define FREQ_STATUS_OVERRUN BIT(29) ··· 288 278 bool running; 289 279 }; 290 280 281 + struct ptp_ocp_serial_port { 282 + int line; 283 + int baud; 284 + }; 285 + 291 286 #define OCP_BOARD_ID_LEN 13 292 287 #define OCP_SERIAL_LEN 6 293 288 ··· 304 289 struct tod_reg __iomem *tod; 305 290 struct pps_reg __iomem *pps_to_ext; 306 291 struct pps_reg __iomem *pps_to_clk; 292 + struct board_config_reg __iomem *board_config; 307 293 struct gpio_reg __iomem *pps_select; 308 294 struct gpio_reg __iomem *sma_map1; 309 295 struct gpio_reg __iomem *sma_map2; ··· 321 305 struct ptp_ocp_ext_src *ts2; 322 306 struct ptp_ocp_ext_src *ts3; 323 307 struct ptp_ocp_ext_src *ts4; 308 + struct ocp_art_gpio_reg __iomem *art_sma; 324 309 struct img_reg __iomem *image; 325 310 struct ptp_clock *ptp; 326 311 struct ptp_clock_info ptp_info; ··· 335 318 time64_t gnss_lost; 336 319 int id; 337 320 int n_irqs; 338 - int gnss_port; 339 - int gnss2_port; 340 - int mac_port; /* miniature atomic clock */ 341 - int nmea_port; 321 + struct ptp_ocp_serial_port gnss_port; 322 + struct ptp_ocp_serial_port gnss2_port; 323 + struct ptp_ocp_serial_port mac_port; /* miniature atomic clock */ 324 + struct ptp_ocp_serial_port nmea_port; 342 325 bool fw_loader; 343 326 u8 fw_tag; 344 327 u16 fw_version; ··· 382 365 static int ptp_ocp_signal_enable(void *priv, u32 req, bool enable); 383 366 static int ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr); 384 367 368 + static int ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r); 369 + 385 370 static const struct ocp_attr_group fb_timecard_groups[]; 371 + 372 + static const struct ocp_attr_group art_timecard_groups[]; 386 373 387 374 struct ptp_ocp_eeprom_map { 388 375 u16 off; ··· 407 386 static struct ptp_ocp_eeprom_map fb_eeprom_map[] = { 408 387 { EEPROM_ENTRY(0x43, board_id) }, 409 388 { EEPROM_ENTRY(0x00, serial), .tag = "mac" }, 389 + { } 390 + }; 391 + 392 + static struct ptp_ocp_eeprom_map art_eeprom_map[] = { 393 + { EEPROM_ENTRY(0x200 + 0x43, board_id) }, 394 + { EEPROM_ENTRY(0x200 + 0x63, serial) }, 410 395 { } 411 396 }; 412 397 ··· 457 430 * 14: Signal Generator 4 458 431 * 15: TS3 459 432 * 16: TS4 433 + -- 434 + * 8: Orolia TS1 435 + * 10: Orolia TS2 436 + * 11: Orolia TS0 (GNSS) 437 + * 12: Orolia PPS 438 + * 14: Orolia TS3 439 + * 15: Orolia TS4 460 440 */ 461 441 462 442 static struct ocp_resource ocp_fb_resource[] = { ··· 630 596 { 631 597 OCP_SERIAL_RESOURCE(gnss_port), 632 598 .offset = 0x00160000 + 0x1000, .irq_vec = 3, 599 + .extra = &(struct ptp_ocp_serial_port) { 600 + .baud = 115200, 601 + }, 633 602 }, 634 603 { 635 604 OCP_SERIAL_RESOURCE(gnss2_port), 636 605 .offset = 0x00170000 + 0x1000, .irq_vec = 4, 606 + .extra = &(struct ptp_ocp_serial_port) { 607 + .baud = 115200, 608 + }, 637 609 }, 638 610 { 639 611 OCP_SERIAL_RESOURCE(mac_port), 640 612 .offset = 0x00180000 + 0x1000, .irq_vec = 5, 613 + .extra = &(struct ptp_ocp_serial_port) { 614 + .baud = 57600, 615 + }, 641 616 }, 642 617 { 643 618 OCP_SERIAL_RESOURCE(nmea_port), ··· 690 647 { } 691 648 }; 692 649 650 + #define OCP_ART_CONFIG_SIZE 144 651 + #define OCP_ART_TEMP_TABLE_SIZE 368 652 + 653 + struct ocp_art_gpio_reg { 654 + struct { 655 + u32 gpio; 656 + u32 __pad[3]; 657 + } map[4]; 658 + }; 659 + 660 + static struct ocp_resource ocp_art_resource[] = { 661 + { 662 + OCP_MEM_RESOURCE(reg), 663 + .offset = 0x01000000, .size = 0x10000, 664 + }, 665 + { 666 + OCP_SERIAL_RESOURCE(gnss_port), 667 + .offset = 0x00160000 + 0x1000, .irq_vec = 3, 668 + .extra = &(struct ptp_ocp_serial_port) { 669 + .baud = 115200, 670 + }, 671 + }, 672 + { 673 + OCP_MEM_RESOURCE(art_sma), 674 + .offset = 0x003C0000, .size = 0x1000, 675 + }, 676 + /* Timestamp associated with GNSS1 receiver PPS */ 677 + { 678 + OCP_EXT_RESOURCE(ts0), 679 + .offset = 0x360000, .size = 0x20, .irq_vec = 12, 680 + .extra = &(struct ptp_ocp_ext_info) { 681 + .index = 0, 682 + .irq_fcn = ptp_ocp_ts_irq, 683 + .enable = ptp_ocp_ts_enable, 684 + }, 685 + }, 686 + { 687 + OCP_EXT_RESOURCE(ts1), 688 + .offset = 0x380000, .size = 0x20, .irq_vec = 8, 689 + .extra = &(struct ptp_ocp_ext_info) { 690 + .index = 1, 691 + .irq_fcn = ptp_ocp_ts_irq, 692 + .enable = ptp_ocp_ts_enable, 693 + }, 694 + }, 695 + { 696 + OCP_EXT_RESOURCE(ts2), 697 + .offset = 0x390000, .size = 0x20, .irq_vec = 10, 698 + .extra = &(struct ptp_ocp_ext_info) { 699 + .index = 2, 700 + .irq_fcn = ptp_ocp_ts_irq, 701 + .enable = ptp_ocp_ts_enable, 702 + }, 703 + }, 704 + { 705 + OCP_EXT_RESOURCE(ts3), 706 + .offset = 0x3A0000, .size = 0x20, .irq_vec = 14, 707 + .extra = &(struct ptp_ocp_ext_info) { 708 + .index = 3, 709 + .irq_fcn = ptp_ocp_ts_irq, 710 + .enable = ptp_ocp_ts_enable, 711 + }, 712 + }, 713 + { 714 + OCP_EXT_RESOURCE(ts4), 715 + .offset = 0x3B0000, .size = 0x20, .irq_vec = 15, 716 + .extra = &(struct ptp_ocp_ext_info) { 717 + .index = 4, 718 + .irq_fcn = ptp_ocp_ts_irq, 719 + .enable = ptp_ocp_ts_enable, 720 + }, 721 + }, 722 + /* Timestamp associated with Internal PPS of the card */ 723 + { 724 + OCP_EXT_RESOURCE(pps), 725 + .offset = 0x00330000, .size = 0x20, .irq_vec = 11, 726 + .extra = &(struct ptp_ocp_ext_info) { 727 + .index = 5, 728 + .irq_fcn = ptp_ocp_ts_irq, 729 + .enable = ptp_ocp_ts_enable, 730 + }, 731 + }, 732 + { 733 + OCP_SPI_RESOURCE(spi_flash), 734 + .offset = 0x00310000, .size = 0x10000, .irq_vec = 9, 735 + .extra = &(struct ptp_ocp_flash_info) { 736 + .name = "spi_altera", .pci_offset = 0, 737 + .data_size = sizeof(struct altera_spi_platform_data), 738 + .data = &(struct altera_spi_platform_data) { 739 + .num_chipselect = 1, 740 + .num_devices = 1, 741 + .devices = &(struct spi_board_info) { 742 + .modalias = "spi-nor", 743 + }, 744 + }, 745 + }, 746 + }, 747 + { 748 + OCP_I2C_RESOURCE(i2c_ctrl), 749 + .offset = 0x350000, .size = 0x100, .irq_vec = 4, 750 + .extra = &(struct ptp_ocp_i2c_info) { 751 + .name = "ocores-i2c", 752 + .fixed_rate = 400000, 753 + .data_size = sizeof(struct ocores_i2c_platform_data), 754 + .data = &(struct ocores_i2c_platform_data) { 755 + .clock_khz = 125000, 756 + .bus_khz = 400, 757 + .num_devices = 1, 758 + .devices = &(struct i2c_board_info) { 759 + I2C_BOARD_INFO("24c08", 0x50), 760 + }, 761 + }, 762 + }, 763 + }, 764 + { 765 + OCP_SERIAL_RESOURCE(mac_port), 766 + .offset = 0x00190000, .irq_vec = 7, 767 + .extra = &(struct ptp_ocp_serial_port) { 768 + .baud = 9600, 769 + }, 770 + }, 771 + { 772 + OCP_MEM_RESOURCE(board_config), 773 + .offset = 0x210000, .size = 0x1000, 774 + }, 775 + { 776 + .setup = ptp_ocp_art_board_init, 777 + }, 778 + { } 779 + }; 780 + 693 781 static const struct pci_device_id ptp_ocp_pcidev_id[] = { 694 782 { PCI_DEVICE_DATA(FACEBOOK, TIMECARD, &ocp_fb_resource) }, 695 783 { PCI_DEVICE_DATA(CELESTICA, TIMECARD, &ocp_fb_resource) }, 784 + { PCI_DEVICE_DATA(OROLIA, ARTCARD, &ocp_art_resource) }, 696 785 { } 697 786 }; 698 787 MODULE_DEVICE_TABLE(pci, ptp_ocp_pcidev_id); ··· 886 711 { .name = "GEN4", .value = 0x0200 }, 887 712 { .name = "GND", .value = 0x2000 }, 888 713 { .name = "VCC", .value = 0x4000 }, 714 + { } 715 + }; 716 + 717 + static const struct ocp_selector ptp_ocp_art_sma_in[] = { 718 + { .name = "PPS1", .value = 0x0001 }, 719 + { .name = "10Mhz", .value = 0x0008 }, 720 + { } 721 + }; 722 + 723 + static const struct ocp_selector ptp_ocp_art_sma_out[] = { 724 + { .name = "PHC", .value = 0x0002 }, 725 + { .name = "GNSS", .value = 0x0004 }, 726 + { .name = "10Mhz", .value = 0x0010 }, 889 727 { } 890 728 }; 891 729 ··· 1530 1342 hdr = (const struct ptp_ocp_firmware_header *)fw->data; 1531 1343 if (memcmp(hdr->magic, OCP_FIRMWARE_MAGIC_HEADER, 4)) { 1532 1344 devlink_flash_update_status_notify(devlink, 1533 - "No firmware header found, flashing raw image", 1345 + "No firmware header found, cancel firmware upgrade", 1534 1346 NULL, 0, 0); 1535 - offset = 0; 1536 - length = fw->size; 1537 - goto out; 1347 + return -EINVAL; 1538 1348 } 1539 1349 1540 1350 if (be16_to_cpu(hdr->pci_vendor_id) != bp->pdev->vendor || ··· 1560 1374 return -EINVAL; 1561 1375 } 1562 1376 1563 - out: 1564 1377 *data = &fw->data[offset]; 1565 1378 *size = length; 1566 1379 ··· 2057 1872 static int 2058 1873 ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r) 2059 1874 { 2060 - int port; 1875 + struct ptp_ocp_serial_port *p = (struct ptp_ocp_serial_port *)r->extra; 1876 + struct ptp_ocp_serial_port port = {}; 2061 1877 2062 - port = ptp_ocp_serial_line(bp, r); 2063 - if (port < 0) 2064 - return port; 1878 + port.line = ptp_ocp_serial_line(bp, r); 1879 + if (port.line < 0) 1880 + return port.line; 1881 + 1882 + if (p) 1883 + port.baud = p->baud; 2065 1884 2066 1885 bp_assign_entry(bp, r, port); 2067 1886 ··· 2444 2255 } 2445 2256 } 2446 2257 return err; 2258 + } 2259 + 2260 + static void 2261 + ptp_ocp_art_sma_init(struct ptp_ocp *bp) 2262 + { 2263 + u32 reg; 2264 + int i; 2265 + 2266 + /* defaults */ 2267 + bp->sma[0].mode = SMA_MODE_IN; 2268 + bp->sma[1].mode = SMA_MODE_IN; 2269 + bp->sma[2].mode = SMA_MODE_OUT; 2270 + bp->sma[3].mode = SMA_MODE_OUT; 2271 + 2272 + bp->sma[0].default_fcn = 0x08; /* IN: 10Mhz */ 2273 + bp->sma[1].default_fcn = 0x01; /* IN: PPS1 */ 2274 + bp->sma[2].default_fcn = 0x10; /* OUT: 10Mhz */ 2275 + bp->sma[3].default_fcn = 0x02; /* OUT: PHC */ 2276 + 2277 + /* If no SMA map, the pin functions and directions are fixed. */ 2278 + if (!bp->art_sma) { 2279 + for (i = 0; i < 4; i++) { 2280 + bp->sma[i].fixed_fcn = true; 2281 + bp->sma[i].fixed_dir = true; 2282 + } 2283 + return; 2284 + } 2285 + 2286 + for (i = 0; i < 4; i++) { 2287 + reg = ioread32(&bp->art_sma->map[i].gpio); 2288 + 2289 + switch (reg & 0xff) { 2290 + case 0: 2291 + bp->sma[i].fixed_fcn = true; 2292 + bp->sma[i].fixed_dir = true; 2293 + break; 2294 + case 1: 2295 + case 8: 2296 + bp->sma[i].mode = SMA_MODE_IN; 2297 + break; 2298 + default: 2299 + bp->sma[i].mode = SMA_MODE_OUT; 2300 + break; 2301 + } 2302 + } 2303 + } 2304 + 2305 + static u32 2306 + ptp_ocp_art_sma_get(struct ptp_ocp *bp, int sma_nr) 2307 + { 2308 + if (bp->sma[sma_nr - 1].fixed_fcn) 2309 + return bp->sma[sma_nr - 1].default_fcn; 2310 + 2311 + return ioread32(&bp->art_sma->map[sma_nr - 1].gpio) & 0xff; 2312 + } 2313 + 2314 + /* note: store 0 is considered invalid. */ 2315 + static int 2316 + ptp_ocp_art_sma_set(struct ptp_ocp *bp, int sma_nr, u32 val) 2317 + { 2318 + unsigned long flags; 2319 + u32 __iomem *gpio; 2320 + int err = 0; 2321 + u32 reg; 2322 + 2323 + val &= SMA_SELECT_MASK; 2324 + if (hweight32(val) > 1) 2325 + return -EINVAL; 2326 + 2327 + gpio = &bp->art_sma->map[sma_nr - 1].gpio; 2328 + 2329 + spin_lock_irqsave(&bp->lock, flags); 2330 + reg = ioread32(gpio); 2331 + if (((reg >> 16) & val) == 0) { 2332 + err = -EOPNOTSUPP; 2333 + } else { 2334 + reg = (reg & 0xff00) | (val & 0xff); 2335 + iowrite32(reg, gpio); 2336 + } 2337 + spin_unlock_irqrestore(&bp->lock, flags); 2338 + 2339 + return err; 2340 + } 2341 + 2342 + static const struct ocp_sma_op ocp_art_sma_op = { 2343 + .tbl = { ptp_ocp_art_sma_in, ptp_ocp_art_sma_out }, 2344 + .init = ptp_ocp_art_sma_init, 2345 + .get = ptp_ocp_art_sma_get, 2346 + .set_inputs = ptp_ocp_art_sma_set, 2347 + .set_output = ptp_ocp_art_sma_set, 2348 + }; 2349 + 2350 + /* ART specific board initializers; last "resource" registered. */ 2351 + static int 2352 + ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r) 2353 + { 2354 + int err; 2355 + 2356 + bp->flash_start = 0x1000000; 2357 + bp->eeprom_map = art_eeprom_map; 2358 + bp->fw_cap = OCP_CAP_BASIC; 2359 + bp->fw_version = ioread32(&bp->reg->version); 2360 + bp->fw_tag = 2; 2361 + bp->sma_op = &ocp_art_sma_op; 2362 + 2363 + /* Enable MAC serial port during initialisation */ 2364 + iowrite32(1, &bp->board_config->mro50_serial_activate); 2365 + 2366 + ptp_ocp_sma_init(bp); 2367 + 2368 + err = ptp_ocp_attr_group_add(bp, art_timecard_groups); 2369 + if (err) 2370 + return err; 2371 + 2372 + return ptp_ocp_init_clock(bp); 2447 2373 } 2448 2374 2449 2375 static ssize_t ··· 3334 3030 DEVICE_FREQ_GROUP(freq3, 2); 3335 3031 DEVICE_FREQ_GROUP(freq4, 3); 3336 3032 3033 + static ssize_t 3034 + disciplining_config_read(struct file *filp, struct kobject *kobj, 3035 + struct bin_attribute *bin_attr, char *buf, 3036 + loff_t off, size_t count) 3037 + { 3038 + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); 3039 + size_t size = OCP_ART_CONFIG_SIZE; 3040 + struct nvmem_device *nvmem; 3041 + ssize_t err; 3042 + 3043 + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); 3044 + if (IS_ERR(nvmem)) 3045 + return PTR_ERR(nvmem); 3046 + 3047 + if (off > size) { 3048 + err = 0; 3049 + goto out; 3050 + } 3051 + 3052 + if (off + count > size) 3053 + count = size - off; 3054 + 3055 + // the configuration is in the very beginning of the EEPROM 3056 + err = nvmem_device_read(nvmem, off, count, buf); 3057 + if (err != count) { 3058 + err = -EFAULT; 3059 + goto out; 3060 + } 3061 + 3062 + out: 3063 + ptp_ocp_nvmem_device_put(&nvmem); 3064 + 3065 + return err; 3066 + } 3067 + 3068 + static ssize_t 3069 + disciplining_config_write(struct file *filp, struct kobject *kobj, 3070 + struct bin_attribute *bin_attr, char *buf, 3071 + loff_t off, size_t count) 3072 + { 3073 + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); 3074 + struct nvmem_device *nvmem; 3075 + ssize_t err; 3076 + 3077 + /* Allow write of the whole area only */ 3078 + if (off || count != OCP_ART_CONFIG_SIZE) 3079 + return -EFAULT; 3080 + 3081 + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); 3082 + if (IS_ERR(nvmem)) 3083 + return PTR_ERR(nvmem); 3084 + 3085 + err = nvmem_device_write(nvmem, 0x00, count, buf); 3086 + if (err != count) 3087 + err = -EFAULT; 3088 + 3089 + ptp_ocp_nvmem_device_put(&nvmem); 3090 + 3091 + return err; 3092 + } 3093 + static BIN_ATTR_RW(disciplining_config, OCP_ART_CONFIG_SIZE); 3094 + 3095 + static ssize_t 3096 + temperature_table_read(struct file *filp, struct kobject *kobj, 3097 + struct bin_attribute *bin_attr, char *buf, 3098 + loff_t off, size_t count) 3099 + { 3100 + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); 3101 + size_t size = OCP_ART_TEMP_TABLE_SIZE; 3102 + struct nvmem_device *nvmem; 3103 + ssize_t err; 3104 + 3105 + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); 3106 + if (IS_ERR(nvmem)) 3107 + return PTR_ERR(nvmem); 3108 + 3109 + if (off > size) { 3110 + err = 0; 3111 + goto out; 3112 + } 3113 + 3114 + if (off + count > size) 3115 + count = size - off; 3116 + 3117 + // the configuration is in the very beginning of the EEPROM 3118 + err = nvmem_device_read(nvmem, 0x90 + off, count, buf); 3119 + if (err != count) { 3120 + err = -EFAULT; 3121 + goto out; 3122 + } 3123 + 3124 + out: 3125 + ptp_ocp_nvmem_device_put(&nvmem); 3126 + 3127 + return err; 3128 + } 3129 + 3130 + static ssize_t 3131 + temperature_table_write(struct file *filp, struct kobject *kobj, 3132 + struct bin_attribute *bin_attr, char *buf, 3133 + loff_t off, size_t count) 3134 + { 3135 + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); 3136 + struct nvmem_device *nvmem; 3137 + ssize_t err; 3138 + 3139 + /* Allow write of the whole area only */ 3140 + if (off || count != OCP_ART_TEMP_TABLE_SIZE) 3141 + return -EFAULT; 3142 + 3143 + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); 3144 + if (IS_ERR(nvmem)) 3145 + return PTR_ERR(nvmem); 3146 + 3147 + err = nvmem_device_write(nvmem, 0x90, count, buf); 3148 + if (err != count) 3149 + err = -EFAULT; 3150 + 3151 + ptp_ocp_nvmem_device_put(&nvmem); 3152 + 3153 + return err; 3154 + } 3155 + static BIN_ATTR_RW(temperature_table, OCP_ART_TEMP_TABLE_SIZE); 3156 + 3337 3157 static struct attribute *fb_timecard_attrs[] = { 3338 3158 &dev_attr_serialnum.attr, 3339 3159 &dev_attr_gnss_sync.attr, ··· 3477 3049 &dev_attr_tod_correction.attr, 3478 3050 NULL, 3479 3051 }; 3052 + 3480 3053 static const struct attribute_group fb_timecard_group = { 3481 3054 .attrs = fb_timecard_attrs, 3482 3055 }; 3056 + 3483 3057 static const struct ocp_attr_group fb_timecard_groups[] = { 3484 3058 { .cap = OCP_CAP_BASIC, .group = &fb_timecard_group }, 3485 3059 { .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group }, ··· 3492 3062 { .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq1_group }, 3493 3063 { .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq2_group }, 3494 3064 { .cap = OCP_CAP_FREQ, .group = &fb_timecard_freq3_group }, 3065 + { }, 3066 + }; 3067 + 3068 + static struct attribute *art_timecard_attrs[] = { 3069 + &dev_attr_serialnum.attr, 3070 + &dev_attr_clock_source.attr, 3071 + &dev_attr_available_clock_sources.attr, 3072 + &dev_attr_utc_tai_offset.attr, 3073 + &dev_attr_ts_window_adjust.attr, 3074 + &dev_attr_sma1.attr, 3075 + &dev_attr_sma2.attr, 3076 + &dev_attr_sma3.attr, 3077 + &dev_attr_sma4.attr, 3078 + &dev_attr_available_sma_inputs.attr, 3079 + &dev_attr_available_sma_outputs.attr, 3080 + NULL, 3081 + }; 3082 + 3083 + static struct bin_attribute *bin_art_timecard_attrs[] = { 3084 + &bin_attr_disciplining_config, 3085 + &bin_attr_temperature_table, 3086 + NULL, 3087 + }; 3088 + 3089 + static const struct attribute_group art_timecard_group = { 3090 + .attrs = art_timecard_attrs, 3091 + .bin_attrs = bin_art_timecard_attrs, 3092 + }; 3093 + 3094 + static const struct ocp_attr_group art_timecard_groups[] = { 3095 + { .cap = OCP_CAP_BASIC, .group = &art_timecard_group }, 3495 3096 { }, 3496 3097 }; 3497 3098 ··· 3638 3177 bp = dev_get_drvdata(dev); 3639 3178 3640 3179 seq_printf(s, "%7s: /dev/ptp%d\n", "PTP", ptp_clock_index(bp->ptp)); 3641 - if (bp->gnss_port != -1) 3642 - seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS1", bp->gnss_port); 3643 - if (bp->gnss2_port != -1) 3644 - seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS2", bp->gnss2_port); 3645 - if (bp->mac_port != -1) 3646 - seq_printf(s, "%7s: /dev/ttyS%d\n", "MAC", bp->mac_port); 3647 - if (bp->nmea_port != -1) 3648 - seq_printf(s, "%7s: /dev/ttyS%d\n", "NMEA", bp->nmea_port); 3180 + if (bp->gnss_port.line != -1) 3181 + seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS1", 3182 + bp->gnss_port.line); 3183 + if (bp->gnss2_port.line != -1) 3184 + seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS2", 3185 + bp->gnss2_port.line); 3186 + if (bp->mac_port.line != -1) 3187 + seq_printf(s, "%7s: /dev/ttyS%d\n", "MAC", bp->mac_port.line); 3188 + if (bp->nmea_port.line != -1) 3189 + seq_printf(s, "%7s: /dev/ttyS%d\n", "NMEA", bp->nmea_port.line); 3649 3190 3650 3191 memset(sma_val, 0xff, sizeof(sma_val)); 3651 3192 if (bp->sma_map1) { ··· 3971 3508 3972 3509 bp->ptp_info = ptp_ocp_clock_info; 3973 3510 spin_lock_init(&bp->lock); 3974 - bp->gnss_port = -1; 3975 - bp->gnss2_port = -1; 3976 - bp->mac_port = -1; 3977 - bp->nmea_port = -1; 3511 + bp->gnss_port.line = -1; 3512 + bp->gnss2_port.line = -1; 3513 + bp->mac_port.line = -1; 3514 + bp->nmea_port.line = -1; 3978 3515 bp->pdev = pdev; 3979 3516 3980 3517 device_initialize(&bp->dev); ··· 4032 3569 struct pps_device *pps; 4033 3570 char buf[32]; 4034 3571 4035 - if (bp->gnss_port != -1) { 4036 - sprintf(buf, "ttyS%d", bp->gnss_port); 3572 + if (bp->gnss_port.line != -1) { 3573 + sprintf(buf, "ttyS%d", bp->gnss_port.line); 4037 3574 ptp_ocp_link_child(bp, buf, "ttyGNSS"); 4038 3575 } 4039 - if (bp->gnss2_port != -1) { 4040 - sprintf(buf, "ttyS%d", bp->gnss2_port); 3576 + if (bp->gnss2_port.line != -1) { 3577 + sprintf(buf, "ttyS%d", bp->gnss2_port.line); 4041 3578 ptp_ocp_link_child(bp, buf, "ttyGNSS2"); 4042 3579 } 4043 - if (bp->mac_port != -1) { 4044 - sprintf(buf, "ttyS%d", bp->mac_port); 3580 + if (bp->mac_port.line != -1) { 3581 + sprintf(buf, "ttyS%d", bp->mac_port.line); 4045 3582 ptp_ocp_link_child(bp, buf, "ttyMAC"); 4046 3583 } 4047 - if (bp->nmea_port != -1) { 4048 - sprintf(buf, "ttyS%d", bp->nmea_port); 3584 + if (bp->nmea_port.line != -1) { 3585 + sprintf(buf, "ttyS%d", bp->nmea_port.line); 4049 3586 ptp_ocp_link_child(bp, buf, "ttyNMEA"); 4050 3587 } 4051 3588 sprintf(buf, "ptp%d", ptp_clock_index(bp->ptp)); ··· 4101 3638 4102 3639 ptp_ocp_phc_info(bp); 4103 3640 4104 - ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200); 4105 - ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port, 115200); 4106 - ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600); 4107 - if (bp->nmea_out && bp->nmea_port != -1) { 4108 - int baud = -1; 3641 + ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port.line, 3642 + bp->gnss_port.baud); 3643 + ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port.line, 3644 + bp->gnss2_port.baud); 3645 + ptp_ocp_serial_info(dev, "MAC", bp->mac_port.line, bp->mac_port.baud); 3646 + if (bp->nmea_out && bp->nmea_port.line != -1) { 3647 + bp->nmea_port.baud = -1; 4109 3648 4110 3649 reg = ioread32(&bp->nmea_out->uart_baud); 4111 3650 if (reg < ARRAY_SIZE(nmea_baud)) 4112 - baud = nmea_baud[reg]; 4113 - ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port, baud); 3651 + bp->nmea_port.baud = nmea_baud[reg]; 3652 + 3653 + ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port.line, 3654 + bp->nmea_port.baud); 4114 3655 } 4115 3656 } 4116 3657 ··· 4155 3688 for (i = 0; i < 4; i++) 4156 3689 if (bp->signal_out[i]) 4157 3690 ptp_ocp_unregister_ext(bp->signal_out[i]); 4158 - if (bp->gnss_port != -1) 4159 - serial8250_unregister_port(bp->gnss_port); 4160 - if (bp->gnss2_port != -1) 4161 - serial8250_unregister_port(bp->gnss2_port); 4162 - if (bp->mac_port != -1) 4163 - serial8250_unregister_port(bp->mac_port); 4164 - if (bp->nmea_port != -1) 4165 - serial8250_unregister_port(bp->nmea_port); 3691 + if (bp->gnss_port.line != -1) 3692 + serial8250_unregister_port(bp->gnss_port.line); 3693 + if (bp->gnss2_port.line != -1) 3694 + serial8250_unregister_port(bp->gnss2_port.line); 3695 + if (bp->mac_port.line != -1) 3696 + serial8250_unregister_port(bp->mac_port.line); 3697 + if (bp->nmea_port.line != -1) 3698 + serial8250_unregister_port(bp->nmea_port.line); 4166 3699 platform_device_unregister(bp->spi_flash); 4167 3700 platform_device_unregister(bp->i2c_ctrl); 4168 3701 if (bp->i2c_clk)