1d787dcdbSChen-Yu Tsai /*
2d787dcdbSChen-Yu Tsai * Allwinner Reduced Serial Bus Driver
3d787dcdbSChen-Yu Tsai *
4d787dcdbSChen-Yu Tsai * Copyright (c) 2015 Chen-Yu Tsai
5d787dcdbSChen-Yu Tsai *
6d787dcdbSChen-Yu Tsai * Author: Chen-Yu Tsai <wens@csie.org>
7d787dcdbSChen-Yu Tsai *
8d787dcdbSChen-Yu Tsai * This file is licensed under the terms of the GNU General Public
9d787dcdbSChen-Yu Tsai * License version 2. This program is licensed "as is" without any
10d787dcdbSChen-Yu Tsai * warranty of any kind, whether express or implied.
11d787dcdbSChen-Yu Tsai */
12d787dcdbSChen-Yu Tsai #ifndef _SUNXI_RSB_H
13d787dcdbSChen-Yu Tsai #define _SUNXI_RSB_H
14d787dcdbSChen-Yu Tsai
15d787dcdbSChen-Yu Tsai #include <linux/device.h>
16d787dcdbSChen-Yu Tsai #include <linux/regmap.h>
17d787dcdbSChen-Yu Tsai #include <linux/types.h>
18d787dcdbSChen-Yu Tsai
19d787dcdbSChen-Yu Tsai struct sunxi_rsb;
20d787dcdbSChen-Yu Tsai
21d787dcdbSChen-Yu Tsai /**
22d787dcdbSChen-Yu Tsai * struct sunxi_rsb_device - Basic representation of an RSB device
23d787dcdbSChen-Yu Tsai * @dev: Driver model representation of the device.
24d787dcdbSChen-Yu Tsai * @ctrl: RSB controller managing the bus hosting this device.
25d787dcdbSChen-Yu Tsai * @rtaddr: This device's runtime address
26d787dcdbSChen-Yu Tsai * @hwaddr: This device's hardware address
27d787dcdbSChen-Yu Tsai */
28d787dcdbSChen-Yu Tsai struct sunxi_rsb_device {
29d787dcdbSChen-Yu Tsai struct device dev;
30d787dcdbSChen-Yu Tsai struct sunxi_rsb *rsb;
31d787dcdbSChen-Yu Tsai int irq;
32d787dcdbSChen-Yu Tsai u8 rtaddr;
33d787dcdbSChen-Yu Tsai u16 hwaddr;
34d787dcdbSChen-Yu Tsai };
35d787dcdbSChen-Yu Tsai
to_sunxi_rsb_device(struct device * d)36d787dcdbSChen-Yu Tsai static inline struct sunxi_rsb_device *to_sunxi_rsb_device(struct device *d)
37d787dcdbSChen-Yu Tsai {
38d787dcdbSChen-Yu Tsai return container_of(d, struct sunxi_rsb_device, dev);
39d787dcdbSChen-Yu Tsai }
40d787dcdbSChen-Yu Tsai
sunxi_rsb_device_get_drvdata(const struct sunxi_rsb_device * rdev)41d787dcdbSChen-Yu Tsai static inline void *sunxi_rsb_device_get_drvdata(const struct sunxi_rsb_device *rdev)
42d787dcdbSChen-Yu Tsai {
43d787dcdbSChen-Yu Tsai return dev_get_drvdata(&rdev->dev);
44d787dcdbSChen-Yu Tsai }
45d787dcdbSChen-Yu Tsai
sunxi_rsb_device_set_drvdata(struct sunxi_rsb_device * rdev,void * data)46d787dcdbSChen-Yu Tsai static inline void sunxi_rsb_device_set_drvdata(struct sunxi_rsb_device *rdev,
47d787dcdbSChen-Yu Tsai void *data)
48d787dcdbSChen-Yu Tsai {
49d787dcdbSChen-Yu Tsai dev_set_drvdata(&rdev->dev, data);
50d787dcdbSChen-Yu Tsai }
51d787dcdbSChen-Yu Tsai
52d787dcdbSChen-Yu Tsai /**
53d787dcdbSChen-Yu Tsai * struct sunxi_rsb_driver - RSB slave device driver
54d787dcdbSChen-Yu Tsai * @driver: RSB device drivers should initialize name and owner field of
55d787dcdbSChen-Yu Tsai * this structure.
56d787dcdbSChen-Yu Tsai * @probe: binds this driver to a RSB device.
57d787dcdbSChen-Yu Tsai * @remove: unbinds this driver from the RSB device.
58d787dcdbSChen-Yu Tsai */
59d787dcdbSChen-Yu Tsai struct sunxi_rsb_driver {
60d787dcdbSChen-Yu Tsai struct device_driver driver;
61d787dcdbSChen-Yu Tsai int (*probe)(struct sunxi_rsb_device *rdev);
62*3c15e00eSUwe Kleine-König void (*remove)(struct sunxi_rsb_device *rdev);
63d787dcdbSChen-Yu Tsai };
64d787dcdbSChen-Yu Tsai
to_sunxi_rsb_driver(struct device_driver * d)65d787dcdbSChen-Yu Tsai static inline struct sunxi_rsb_driver *to_sunxi_rsb_driver(struct device_driver *d)
66d787dcdbSChen-Yu Tsai {
67d787dcdbSChen-Yu Tsai return container_of(d, struct sunxi_rsb_driver, driver);
68d787dcdbSChen-Yu Tsai }
69d787dcdbSChen-Yu Tsai
70d787dcdbSChen-Yu Tsai int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv);
71d787dcdbSChen-Yu Tsai
72d787dcdbSChen-Yu Tsai /**
73d787dcdbSChen-Yu Tsai * sunxi_rsb_driver_unregister() - unregister an RSB client driver
74d787dcdbSChen-Yu Tsai * @rdrv: the driver to unregister
75d787dcdbSChen-Yu Tsai */
sunxi_rsb_driver_unregister(struct sunxi_rsb_driver * rdrv)76d787dcdbSChen-Yu Tsai static inline void sunxi_rsb_driver_unregister(struct sunxi_rsb_driver *rdrv)
77d787dcdbSChen-Yu Tsai {
78d787dcdbSChen-Yu Tsai if (rdrv)
79d787dcdbSChen-Yu Tsai driver_unregister(&rdrv->driver);
80d787dcdbSChen-Yu Tsai }
81d787dcdbSChen-Yu Tsai
82d787dcdbSChen-Yu Tsai #define module_sunxi_rsb_driver(__sunxi_rsb_driver) \
83d787dcdbSChen-Yu Tsai module_driver(__sunxi_rsb_driver, sunxi_rsb_driver_register, \
84d787dcdbSChen-Yu Tsai sunxi_rsb_driver_unregister)
85d787dcdbSChen-Yu Tsai
86d787dcdbSChen-Yu Tsai struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
87d787dcdbSChen-Yu Tsai const struct regmap_config *config,
88d787dcdbSChen-Yu Tsai struct lock_class_key *lock_key,
89d787dcdbSChen-Yu Tsai const char *lock_name);
90d787dcdbSChen-Yu Tsai
91d787dcdbSChen-Yu Tsai /**
92d787dcdbSChen-Yu Tsai * devm_regmap_init_sunxi_rsb(): Initialise managed register map
93d787dcdbSChen-Yu Tsai *
94d787dcdbSChen-Yu Tsai * @rdev: Device that will be interacted with
95d787dcdbSChen-Yu Tsai * @config: Configuration for register map
96d787dcdbSChen-Yu Tsai *
97d787dcdbSChen-Yu Tsai * The return value will be an ERR_PTR() on error or a valid pointer
98d787dcdbSChen-Yu Tsai * to a struct regmap. The regmap will be automatically freed by the
99d787dcdbSChen-Yu Tsai * device management code.
100d787dcdbSChen-Yu Tsai */
101d787dcdbSChen-Yu Tsai #define devm_regmap_init_sunxi_rsb(rdev, config) \
102d787dcdbSChen-Yu Tsai __regmap_lockdep_wrapper(__devm_regmap_init_sunxi_rsb, #config, \
103d787dcdbSChen-Yu Tsai rdev, config)
104d787dcdbSChen-Yu Tsai
105d787dcdbSChen-Yu Tsai #endif /* _SUNXI_RSB_H */
106