[CAUTION: External Email]
On Thu, Feb 27, 2020 at 7:01 AM Sandeep Singh <Sandeep.Singh@xxxxxxx> wrote:
From: Sandeep Singh <sandeep.singh@xxxxxxx>You asked for review, here you are.
AMD SFH uses HID over PCIe bus.SFH fw is part of MP2
processor (MP2 which is an ARMÂ Cortex-M4 core based
co-processor to x86) and it runs on MP2 where in driver resides
on X86. This part of module will communicate with MP2 FW and
provide that data into DRAM
TL,DR; it requires a bit of work.
...
+ depends on (X86_64 || COMPILE_TEST) && PCIFor better maintenance
depends on X86_64 || COMPILE_TEST
depends on PCI
...
+# SPDX-License-Identifier: GPL-2.0Perhaps simple blank line instead?
+#
+# Makefile - AMD SFH HID drivers
+# Copyright (c) 2020-2021, Advanced Micro Devices, Inc.
+#
+#
+ccflags-y += -I$(srctree)/$(src)/Why?
...
+#include <linux/interrupt.h>Keep in order?
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+ blank line?
Missed bits.h, types.h.
+#include "amd_mp2_pcie.h"...
+ write64((u64)info.phy_address, privdata->mmio + AMD_C2P_MSG2);Why explicit cast?
...
+ /*fill up command register */Space is missed.
...
+ if (!sensor_id)I can say -EINVAL as per its definition, but why do you need this at all?
+ return -ENOMEM;
...
+static int amd_mp2_pci_init(struct amd_mp2_dev *privdata, struct pci_dev *pdev)Better to assign when you are sure (to some extend in both of them):
+{
+ int rc;
+ int bar_index = 2;
+ resource_size_t size, base;
+ pci_set_drvdata(pdev, privdata);
a) it's needed
b) driver is going to be probed correctly
...
+ rc = pcim_iomap_regions(pdev, 1 >> 2, DRIVER_NAME);What 1 >> 2 means? Shouldn't be simple BIT(2)?
How was this been tested?
+ if (rc)...
+ goto err_pci_regions;
+ base = pci_resource_start(pdev, bar_index);Read printk-formats.rst.
+ size = pci_resource_len(pdev, bar_index);
+ dev_dbg(ndev_dev(privdata), "Base addr:%llx size:%llx\n",
+ (unsigned long long)base, (unsigned long long)size);
Now, when you get familiar with it, find proper specifier and drop
these ugly castings.
But wait, why do you need this? `dmesg` will show it anyway during
boot / hotplug event time.
...
+ privdata->mmio = ioremap(base, size);Why?!
+ if (!privdata->mmio) {
+ rc = -EIO;
+ goto err_dma_mask;
+ }
...
+err_dma_mask:Are you using devres or not? Please, be consistent.
+ pci_clear_master(pdev);
+err_pci_regions:
+ pci_disable_device(pdev);
+err_pci_enable:I think it's some like 5 to 10 years that we don't need this.
+ pci_set_drvdata(pdev, NULL);
+ return rc;...
+}
+ pci_iounmap(pdev, privdata->mmio);Ditto as above two comments.
+
+ pci_clear_master(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
...
+ dev_info(&pdev->dev, "MP2 device found [%04x:%04x] (rev %x)\n",Oh, if you use explicit casting for printf(), 99.9% you are doing
+ (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
something wrong (in kernel space).
On top of that, why this noise is here?
...
+ privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL);No need for this blank line.
+
+ if (!privdata) {...
+ }
+ rc = amd_mp2_pci_init(privdata, pdev);Why its content can't be simple here? I.o.w. why this function is needed?
+ if (rc)
+ goto err_pci_init;
+ return 0;
...
+err_pci_init:Completely useless code.
+ return rc;
+err_dev:
+ return rc;
+}...
+static const struct pci_device_id amd_mp2_pci_tbl[] = {0 is not needed, but it's up to you.
+ {PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2)},
+ {0}
+};...
+static int __init amd_mp2_pci_driver_init(void)module_pci_driver()
+{
+ return pci_register_driver(&amd_mp2_pci_driver);
+}
+module_init(amd_mp2_pci_driver_init);
+
+static void __exit amd_mp2_pci_driver_exit(void)
+{
+ pci_unregister_driver(&amd_mp2_pci_driver);
+}
+module_exit(amd_mp2_pci_driver_exit);
We have it for years.
...
+#include <linux/pci.h>I don't see users of it, but missed headers
types.h
...
+#define PCI_DEVICE_ID_AMD_MP2 0x15E4Why it's not in C file?
...
+#define AMD_P2C_MSG0 0x10680 /*Do not use*/Missed spaces.
+#define AMD_P2C_MSG1 0x10684
+#define AMD_P2C_MSG2 0x10688
+#define AMD_P2C_MSG3 0x1068C /*MP2 debug info*/
+#define AMD_P2C_MSG_INTEN 0x10690 /*MP2 int gen register*/
+#define AMD_P2C_MSG_INTSTS 0x10694 /*Interrupt sts*/
...
+#define write64 amdsfh_write64NIH of lo_hi_writeq().
+static inline void amdsfh_write64(u64 val, void __iomem *mmio)
+{
+ writel(val, mmio);
+ writel(val >> 32, mmio + sizeof(u32));
+}
+#define read64 amdsfh_read64NIH of lo_hi_readq().
+static inline u64 amdsfh_read64(void __iomem *mmio)
+{
+ u64 low, high;
+
+ low = readl(mmio);
+ high = readl(mmio + sizeof(u32));
+ return low | (high << 32);
+}
...
+struct sfh_command_register {Are you sure? This type is flexible. And by name of the struct I think
+ union sfh_cmd_base cmd_base;
+ union sfh_command_parameter cmd_param;
+ phys_addr_t phy_addr;
it operates with hardware, so, fix it accordingly.
+};...
+enum response_type {GENMASK()
+ non_operationevent,
+ command_success,
+ command_failed,
+ sfi_dataready_event,
+ invalid_response = 0xff,
+};UPPER CASE?
+enum status_type {Ditto.
+ cmd_success,
+ invalid_data_payload,
+ invalid_data_length,
+ invalid_sensor_id,
+ invalid_dram_addr,
+ invalid_command,
+ sensor_enabled,
+ sensor_disabled,
+ status_end,
+};
+
+enum command_id {
+ non_operation = 0,
+ enable_sensor = 1,
+ disable_sensor = 2,
+ dump_sensorinfo = 3,
+ numberof_sensordiscovered = 4,
+ who_am_i_regchipid = 5,
+ set_dcd_data = 6,
+ get_dcd_data = 7,
+ stop_all_sensors = 8,
+ invalid_cmd = 0xf,
+};
...
+enum sensor_idx {Do you need names for enums like this?
+ ACCEL_IDX = 0,...
+ GYRO_IDX = 1,
+ MAG_IDX = 2,
+ AMBIENT_LIGHT_IDX = 19,
+ NUM_ALL_SENSOR_CONSUMERS
+};
+struct amd_mp2_dev {Header for __iomem?
+ struct pci_dev *pdev;
+ void __iomem *mmio;
+ struct delayed_work work;Header for this?
+ void *ctx;...
+ void *cl_data;
+};
+struct amd_mp2_sensor_info {Same comment as per above use of phys_addr_t type.
+ u8 sensor_idx;
+ u32 period;
+ phys_addr_t phy_address;
+};...
+#define ndev_pdev(ndev) ((ndev)->pdev)Why? What's the benefit?
+#define ndev_name(ndev) pci_name(ndev_pdev(ndev))
+#define ndev_dev(ndev) (&ndev_pdev(ndev)->dev)
--
With Best Regards,
Andy Shevchenko