Commit 6e9600e6 authored by Federico Vaga's avatar Federico Vaga

drv: register UART driver

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 0807aac4
Pipeline #651 failed with stages
......@@ -10,5 +10,10 @@ endif
ccflags-y += -DADDITIONAL_VERSIONS="$(SUBMODULE_VERSIONS)"
ccflags-y += -DVERSION=\"$(VERSION)\"
ccflags-y += -Wall -Werror
ccflags-y += -I$(src)
ccflags-y += -I$(src)/../include
ccflags-y += -I$(WB_UART)/include
obj-m := white-rabbit.o
white-rabbit-y := white-rabbit-core.o
......@@ -15,4 +15,6 @@ all: modules
install: modules_install
modules help coccicheck modules_install clean:
$(MAKE) -C $(LINUX) M=$(shell pwd) VERSION=$(VERSION) $@
$(MAKE) -C $(LINUX) M=$(shell pwd) VERSION=$(VERSION) \
WB_UART=$(WB_UART) \
$@
......@@ -7,24 +7,12 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/platform_data/wb-uart.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/version.h>
#include "white-rabbit.h"
#define WR_SIGNATURE 0x0
#define WR_SIGNATURE_OFFSET 0x0
struct wr_memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
};
struct wr_dev {
struct platform_device *pdev;
void __iomem *base;
struct wr_memory_ops memops;
};
static int wr_endianess(struct wr_dev *wr)
{
......@@ -57,6 +45,53 @@ static int wr_memops_detect(struct wr_dev *wr)
}
}
#define WB_UART_RES_N 2
#define WB_UART_MEM_START 0x0
#define WB_UART_MEM_END 0x0
#define WB_IRQ_UART 0
static int wr_uart_register(struct wr_dev *wr)
{
struct platform_device *pdev;
struct wb_uart_platform_data pdata;
struct resource res[WB_UART_RES_N];
struct resource *wr_res;
int ret;
ret = wr_endianess(wr);
if (ret < 0)
return -1;
wr_res = platform_get_resource(wr->pdev, IORESOURCE_MEM, 0);
res[0].name = "wr-uart-mem";
res[0].flags = IORESOURCE_MEM;
res[0].start = wr_res->start + WB_UART_MEM_START;
res[0].end = wr_res->start + WB_UART_MEM_END;
wr_res = platform_get_resource(wr->pdev, IORESOURCE_IRQ, 0);
res[1].name = "wr-uart-irq";
res[1].flags = IORESOURCE_IRQ;
res[1].start = wr_res->start + WB_IRQ_UART;
res[1].end = 0;
pdata.big_endian = ret;
pdev = platform_device_register_resndata(&wr->pdev->dev,
"wb-uart",
PLATFORM_DEVID_AUTO,
res, ARRAY_SIZE(res),
&pdata, sizeof(pdata));
if (IS_ERR(pdev))
return PTR_ERR(pdev);
wr->uart_pdev = pdev;
return 0;
}
static void wr_uart_unregister(struct wr_dev *wr)
{
if (wr->uart_pdev) {
platform_device_unregister(wr->uart_pdev);
wr->uart_pdev = NULL;
}
}
static int wr_probe(struct platform_device *pdev)
{
struct wr_dev *wr;
......@@ -67,7 +102,7 @@ static int wr_probe(struct platform_device *pdev)
if (!wr)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, WR_MEM);
#if KERNEL_VERSION(3, 9, 0) > LINUX_VERSION_CODE
wr->base = devm_request_and_ioremap(&pdev->dev, res);
if (!wr->base)
......@@ -82,15 +117,25 @@ static int wr_probe(struct platform_device *pdev)
if (err)
goto err_endianess;
return 0;
err = wr_uart_register(wr);
if (err)
goto err_uart;
platform_set_drvdata(pdev, wr);
return 0;
err_uart:
err_endianess:
devm_kfree(&pdev->dev, wr);
return err;
}
static int wr_remove(struct platform_device *pdev)
{
return 0;
struct wr_dev *wr = platform_get_drvdata(pdev);
wr_uart_unregister(wr);
return 0;
}
static const struct platform_device_id wr_id[] = {
......
......@@ -7,8 +7,50 @@
#ifndef __LINUX_WHITE_RABBIT_H
#define __LINUX_WHITE_RABBIT_H
#include <linux/serial_core.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/types.h>
enum wr_versions {
WR_VER = 0,
};
#define WR_SIGNATURE 0x0
#define WR_SIGNATURE_OFFSET 0x0
#define WR_MEM 0
struct wr_memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
};
struct wr_dev {
struct platform_device *pdev;
void __iomem *base;
struct wr_memory_ops memops;
spinlock_t lock;
struct platform_device *uart_pdev;
};
static inline struct wr_dev *to_wr_dev(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
return platform_get_drvdata(pdev);
}
static inline uint32_t wr_ioread(struct wr_dev *wr, void *addr)
{
return wr->memops.read(addr);
}
static inline void wr_iowrite(struct wr_dev *wr,
uint32_t value, void *addr)
{
return wr->memops.write(value, addr);
}
#endif /* __LINUX_WHITE_RABBIT_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment