diff --git a/.config b/.config index 220a2407..d8a853f6 100644 --- a/.config +++ b/.config @@ -1620,6 +1620,7 @@ CONFIG_SRAM=y CONFIG_SRAM_EXEC=y CONFIG_VEXPRESS_SYSCFG=y CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_MISC_OCM=y # CONFIG_C2PORT is not set # diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3726eacd..92095a24 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -513,6 +513,9 @@ config MISC_RTSX tristate default MISC_RTSX_PCI || MISC_RTSX_USB +config MISC_OCM + tristate MISC_OCM + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index af22bbc3..2470b1ae 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o obj-$(CONFIG_OCXL) += ocxl/ obj-$(CONFIG_MISC_RTSX) += cardreader/ +obj-$(CONFIG_MISC_OCM) += ocm.o diff --git a/drivers/misc/ocm.c b/drivers/misc/ocm.c new file mode 100644 index 00000000..b0678892 --- /dev/null +++ b/drivers/misc/ocm.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static uint8_t *zynq_ocm; +static size_t zynq_ocm_len; + +/* +** This function will be called when we open the Misc device file +*/ +static int zynq_ocm_open(struct inode *inode, struct file *file) +{ + pr_info("zynq_ocm device open\n"); + return 0; +} + +/* +** This function will be called when we close the Misc Device file +*/ +static int zynq_ocm_close(struct inode *inodep, struct file *filp) +{ + pr_info("zynq_ocm device close\n"); + return 0; +} + +/* +** This function will be called when we write the Misc Device file +*/ +static ssize_t zynq_ocm_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + pr_info("zynq_ocm device write\n"); + + /* We are not doing anything with this data now */ + + return -ENODEV; +} + +/* +** This function will be called when we read the Misc Device file +*/ +static ssize_t zynq_ocm_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + + if (*f_pos>=zynq_ocm_len) return 0; + + if ((*f_pos+count)>zynq_ocm_len) { + count=zynq_ocm_len-*f_pos; + } + + if (copy_to_user(buf, zynq_ocm+(*f_pos), count)) + return -EFAULT; + + (*f_pos) += count; + + return count; +} + +//File operation structure +static const struct file_operations fops = { + .owner = THIS_MODULE, + .write = zynq_ocm_write, + .read = zynq_ocm_read, + .open = zynq_ocm_open, + .release = zynq_ocm_close, + .llseek = no_llseek, +}; + +//Misc device structure +struct miscdevice zynq_ocm_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "zynq_ocm", + .fops = &fops, +}; + + +static const struct of_device_id zynq_ocm_of_match[] = { + { .compatible = "xlnx,zynq-ocm-1.0" }, + { /* end of table */ } +}; +MODULE_DEVICE_TABLE(of, zynq_ocm_of_match); + + +static int zynq_ocm_probe(struct platform_device *pdev) +{ + struct resource *res; + const struct of_device_id *match; + uint8_t *ptr; + + match = of_match_node(zynq_ocm_of_match, pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "of_match_node() failed\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + zynq_ocm_len=res->end - res->start; + zynq_ocm_len++; + pr_info("zynq_ocm resource indicates length of 0x%x\n",zynq_ocm_len); + + ptr = devm_ioremap_resource(&pdev->dev, res); + pr_info("zynq_ocm devm_ioremap_resource() gives %px\n",ptr); + + if (IS_ERR(ptr)) + return PTR_ERR(ptr); + + zynq_ocm=ptr; + + return 0; +} + +/** + * zynq_gpio_remove - Driver removal function + * @pdev: platform device instance + * + * Return: 0 always + */ +static int zynq_ocm_remove(struct platform_device *pdev) +{ + //struct zynq_gpio *gpio = platform_get_drvdata(pdev); + + zynq_ocm=NULL; + return 0; +} + +static struct platform_driver zynq_ocm_driver = { + .driver = { + .name = "zynq_ocm", + .of_match_table = zynq_ocm_of_match, + }, + .probe = zynq_ocm_probe, + .remove = zynq_ocm_remove, +}; + + +static int __init zynq_ocm_init(void) +{ + int error; + + error=platform_driver_register(&zynq_ocm_driver); + if (error) { + pr_err("platform_driver_register failed!!!\n"); + return error; + } + + error = misc_register(&zynq_ocm_device); + if (error) { + platform_driver_unregister(&zynq_ocm_driver); + pr_err("misc_register failed!!!\n"); + return error; + } + + pr_info("misc_register init done!!!\n"); + +#if 0 + zynq_ocm = ioremap(0xfffc0000,0x40000); + pr_info("zynq_ocm mapped at %px\n",zynq_ocm); +#endif + + return 0; +} + +static void __exit zynq_ocm_exit(void) +{ + misc_deregister(&zynq_ocm_device); + platform_driver_unregister(&zynq_ocm_driver); + + pr_info("misc_register exit done!!!\n"); + +#if 0 + if (zynq_ocm) iounmap(zynq_ocm); +#endif +} + +module_init(zynq_ocm_init) +module_exit(zynq_ocm_exit) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("meh"); +MODULE_DESCRIPTION("zynq_ocm driver"); +MODULE_VERSION("1.29"); + + +