diff options
Diffstat (limited to 'include/linux')
73 files changed, 2509 insertions, 386 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7c925e6211f1..f711be6e8c44 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -20,6 +20,8 @@ * flags used across common struct clk. these flags should only affect the * top-level framework. custom flags for dealing with hardware specifics * belong in struct clk_foo + * + * Please update clk_flags[] in drivers/clk/clk.c when making changes here! */ #define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */ #define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ @@ -412,7 +414,7 @@ extern const struct clk_ops clk_divider_ro_ops; unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, unsigned int val, const struct clk_div_table *table, - unsigned long flags); + unsigned long flags, unsigned long width); long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, unsigned long rate, unsigned long *prate, const struct clk_div_table *table, @@ -744,6 +746,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw); unsigned long __clk_get_flags(struct clk *clk); unsigned long clk_hw_get_flags(const struct clk_hw *hw); bool clk_hw_is_prepared(const struct clk_hw *hw); +bool clk_hw_rate_is_protected(const struct clk_hw *hw); bool clk_hw_is_enabled(const struct clk_hw *hw); bool __clk_is_enabled(struct clk *clk); struct clk *__clk_lookup(const char *name); @@ -806,6 +809,44 @@ extern struct of_device_id __clk_of_table; } \ OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver) +#define CLK_HW_INIT(_name, _parent, _ops, _flags) \ + (&(struct clk_init_data) { \ + .flags = _flags, \ + .name = _name, \ + .parent_names = (const char *[]) { _parent }, \ + .num_parents = 1, \ + .ops = _ops, \ + }) + +#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \ + (&(struct clk_init_data) { \ + .flags = _flags, \ + .name = _name, \ + .parent_names = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .ops = _ops, \ + }) + +#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \ + (&(struct clk_init_data) { \ + .flags = _flags, \ + .name = _name, \ + .parent_names = NULL, \ + .num_parents = 0, \ + .ops = _ops, \ + }) + +#define CLK_FIXED_FACTOR(_struct, _name, _parent, \ + _div, _mult, _flags) \ + struct clk_fixed_factor _struct = { \ + .div = _div, \ + .mult = _mult, \ + .hw.init = CLK_HW_INIT(_name, \ + _parent, \ + &clk_fixed_factor_ops, \ + _flags), \ + } + #ifdef CONFIG_OF int of_clk_add_provider(struct device_node *np, struct clk *(*clk_src_get)(struct of_phandle_args *args, diff --git a/include/linux/clk.h b/include/linux/clk.h index 12c96d94d1fa..4c4ef9f34db3 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -331,6 +331,38 @@ struct clk *devm_clk_get(struct device *dev, const char *id); */ struct clk *devm_get_clk_from_child(struct device *dev, struct device_node *np, const char *con_id); +/** + * clk_rate_exclusive_get - get exclusivity over the rate control of a + * producer + * @clk: clock source + * + * This function allows drivers to get exclusive control over the rate of a + * provider. It prevents any other consumer to execute, even indirectly, + * opereation which could alter the rate of the provider or cause glitches + * + * If exlusivity is claimed more than once on clock, even by the same driver, + * the rate effectively gets locked as exclusivity can't be preempted. + * + * Must not be called from within atomic context. + * + * Returns success (0) or negative errno. + */ +int clk_rate_exclusive_get(struct clk *clk); + +/** + * clk_rate_exclusive_put - release exclusivity over the rate control of a + * producer + * @clk: clock source + * + * This function allows drivers to release the exclusivity it previously got + * from clk_rate_exclusive_get() + * + * The caller must balance the number of clk_rate_exclusive_get() and + * clk_rate_exclusive_put() calls. + * + * Must not be called from within atomic context. + */ +void clk_rate_exclusive_put(struct clk *clk); /** * clk_enable - inform the system when the clock source should be running. @@ -473,6 +505,23 @@ long clk_round_rate(struct clk *clk, unsigned long rate); int clk_set_rate(struct clk *clk, unsigned long rate); /** + * clk_set_rate_exclusive- set the clock rate and claim exclusivity over + * clock source + * @clk: clock source + * @rate: desired clock rate in Hz + * + * This helper function allows drivers to atomically set the rate of a producer + * and claim exclusivity over the rate control of the producer. + * + * It is essentially a combination of clk_set_rate() and + * clk_rate_exclusite_get(). Caller must balance this call with a call to + * clk_rate_exclusive_put() + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_exclusive(struct clk *clk, unsigned long rate); + +/** * clk_has_parent - check if a clock is a possible parent for another * @clk: clock source * @parent: parent clock source @@ -583,6 +632,14 @@ static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} static inline void devm_clk_put(struct device *dev, struct clk *clk) {} + +static inline int clk_rate_exclusive_get(struct clk *clk) +{ + return 0; +} + +static inline void clk_rate_exclusive_put(struct clk *clk) {} + static inline int clk_enable(struct clk *clk) { return 0; @@ -609,6 +666,11 @@ static inline int clk_set_rate(struct clk *clk, unsigned long rate) return 0; } +static inline int clk_set_rate_exclusive(struct clk *clk, unsigned long rate) +{ + return 0; +} + static inline long clk_round_rate(struct clk *clk, unsigned long rate) { return 0; diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index 2eabc862abdb..4890ff033220 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -12,7 +12,7 @@ #ifndef __CLKDEV_H #define __CLKDEV_H -#include <asm/clkdev.h> +#include <linux/slab.h> struct clk; struct clk_hw; @@ -52,9 +52,4 @@ int clk_add_alias(const char *, const char *, const char *, struct device *); int clk_register_clkdev(struct clk *, const char *, const char *); int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *); -#ifdef CONFIG_COMMON_CLK -int __clk_get(struct clk *clk); -void __clk_put(struct clk *clk); -#endif - #endif diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..c2cc57a2f508 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -185,23 +185,21 @@ void __read_once_size(const volatile void *p, void *res, int size) #ifdef CONFIG_KASAN /* - * This function is not 'inline' because __no_sanitize_address confilcts + * We can't declare function 'inline' because __no_sanitize_address confilcts * with inlining. Attempt to inline it may cause a build failure. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 * '__maybe_unused' allows us to avoid defined-but-not-used warnings. */ -static __no_sanitize_address __maybe_unused -void __read_once_size_nocheck(const volatile void *p, void *res, int size) -{ - __READ_ONCE_SIZE; -} +# define __no_kasan_or_inline __no_sanitize_address __maybe_unused #else -static __always_inline +# define __no_kasan_or_inline __always_inline +#endif + +static __no_kasan_or_inline void __read_once_size_nocheck(const volatile void *p, void *res, int size) { __READ_ONCE_SIZE; } -#endif static __always_inline void __write_once_size(volatile void *p, void *res, int size) { @@ -240,6 +238,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s * required ordering. */ #include <asm/barrier.h> +#include <linux/kasan-checks.h> #define __READ_ONCE(x, check) \ ({ \ @@ -259,6 +258,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s */ #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0) +static __no_kasan_or_inline +unsigned long read_word_at_a_time(const void *addr) +{ + kasan_check_read(addr, 1); + return *(unsigned long *)addr; +} + #define WRITE_ONCE(x, val) \ ({ \ union { typeof(x) __val; char __c[1]; } __u = \ diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 2c787c5cad3d..5172ad0daa7c 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -59,6 +59,7 @@ enum cpuhp_state { CPUHP_PCI_XGENE_DEAD, CPUHP_IOMMU_INTEL_DEAD, CPUHP_LUSTRE_CFS_DEAD, + CPUHP_AP_ARM_CACHE_B15_RAC_DEAD, CPUHP_WORKQUEUE_PREP, CPUHP_POWER_NUMA_PREPARE, CPUHP_HRTIMERS_PREPARE, @@ -138,6 +139,7 @@ enum cpuhp_state { CPUHP_AP_ARM64_ISNDEP_STARTING, CPUHP_AP_SMPCFD_DYING, CPUHP_AP_X86_TBOOT_DYING, + CPUHP_AP_ARM_CACHE_B15_RAC_DYING, CPUHP_AP_ONLINE, CPUHP_TEARDOWN_CPU, CPUHP_AP_ONLINE_IDLE, diff --git a/include/linux/device.h b/include/linux/device.h index 46ac622e5c6f..b093405ed525 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * device.h - generic, centralized driver model * @@ -5,8 +6,6 @@ * Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de> * Copyright (c) 2008-2009 Novell Inc. * - * This file is released under the GPLv2 - * * See Documentation/driver-model/ for more information. */ @@ -21,7 +20,6 @@ #include <linux/compiler.h> #include <linux/types.h> #include <linux/mutex.h> -#include <linux/pinctrl/devinfo.h> #include <linux/pm.h> #include <linux/atomic.h> #include <linux/ratelimit.h> @@ -42,6 +40,7 @@ struct fwnode_handle; struct iommu_ops; struct iommu_group; struct iommu_fwspec; +struct dev_pin_info; struct bus_attribute { struct attribute attr; @@ -288,6 +287,7 @@ struct device_driver { const struct attribute_group **groups; const struct dev_pm_ops *pm; + int (*coredump) (struct device *dev); struct driver_private *p; }; @@ -301,7 +301,6 @@ extern struct device_driver *driver_find(const char *name, extern int driver_probe_done(void); extern void wait_for_device_probe(void); - /* sysfs interface for exporting driver attributes */ struct driver_attribute { diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h index 332a5420243c..bc8940ca280d 100644 --- a/include/linux/dma-fence-array.h +++ b/include/linux/dma-fence-array.h @@ -21,6 +21,7 @@ #define __LINUX_DMA_FENCE_ARRAY_H #include <linux/dma-fence.h> +#include <linux/irq_work.h> /** * struct dma_fence_array_cb - callback helper for fence array @@ -47,6 +48,8 @@ struct dma_fence_array { unsigned num_fences; atomic_t num_pending; struct dma_fence **fences; + + struct irq_work work; }; extern const struct dma_fence_ops dma_fence_array_ops; diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index efdabbb64e3c..4c008170fe65 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -242,7 +242,7 @@ static inline struct dma_fence *dma_fence_get_rcu(struct dma_fence *fence) * The caller is required to hold the RCU read lock. */ static inline struct dma_fence * -dma_fence_get_rcu_safe(struct dma_fence * __rcu *fencep) +dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep) { do { struct dma_fence *fence; diff --git a/include/linux/fb.h b/include/linux/fb.h index bc24e48e396d..d1e5bed39140 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -465,6 +465,11 @@ struct fb_info { atomic_t count; int node; int flags; + /* + * -1 by default, set to a FB_ROTATE_* value by the driver, if it knows + * a lcd is not mounted upright and fbcon should rotate to compensate. + */ + int fbcon_rotate_hint; struct mutex lock; /* Lock for open/release/ioctl funcs */ struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */ struct fb_var_screeninfo var; /* Current var */ diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h index aa66c87c120b..3694821a6d2d 100644 --- a/include/linux/fpga/fpga-bridge.h +++ b/include/linux/fpga/fpga-bridge.h @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#include <linux/device.h> -#include <linux/fpga/fpga-mgr.h> #ifndef _LINUX_FPGA_BRIDGE_H #define _LINUX_FPGA_BRIDGE_H +#include <linux/device.h> +#include <linux/fpga/fpga-mgr.h> + struct fpga_bridge; /** @@ -12,11 +13,13 @@ struct fpga_bridge; * @enable_show: returns the FPGA bridge's status * @enable_set: set a FPGA bridge as enabled or disabled * @fpga_bridge_remove: set FPGA into a specific state during driver remove + * @groups: optional attribute groups. */ struct fpga_bridge_ops { int (*enable_show)(struct fpga_bridge *bridge); int (*enable_set)(struct fpga_bridge *bridge, bool enable); void (*fpga_bridge_remove)(struct fpga_bridge *bridge); + const struct attribute_group **groups; }; /** @@ -43,6 +46,8 @@ struct fpga_bridge { struct fpga_bridge *of_fpga_bridge_get(struct device_node *node, struct fpga_image_info *info); +struct fpga_bridge *fpga_bridge_get(struct device *dev, + struct fpga_image_info *info); void fpga_bridge_put(struct fpga_bridge *bridge); int fpga_bridge_enable(struct fpga_bridge *bridge); int fpga_bridge_disable(struct fpga_bridge *bridge); @@ -50,9 +55,12 @@ int fpga_bridge_disable(struct fpga_bridge *bridge); int fpga_bridges_enable(struct list_head *bridge_list); int fpga_bridges_disable(struct list_head *bridge_list); void fpga_bridges_put(struct list_head *bridge_list); -int fpga_bridge_get_to_list(struct device_node *np, +int fpga_bridge_get_to_list(struct device *dev, struct fpga_image_info *info, struct list_head *bridge_list); +int of_fpga_bridge_get_to_list(struct device_node *np, + struct fpga_image_info *info, + struct list_head *bridge_list); int fpga_bridge_register(struct device *dev, const char *name, const struct fpga_bridge_ops *br_ops, void *priv); diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index bfa14bc023fb..3c6de23aabdf 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -1,7 +1,8 @@ /* * FPGA Framework * - * Copyright (C) 2013-2015 Altera Corporation + * Copyright (C) 2013-2016 Altera Corporation + * Copyright (C) 2017 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -15,12 +16,12 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/mutex.h> -#include <linux/platform_device.h> - #ifndef _LINUX_FPGA_MGR_H #define _LINUX_FPGA_MGR_H +#include <linux/mutex.h> +#include <linux/platform_device.h> + struct fpga_manager; struct sg_table; @@ -83,12 +84,26 @@ enum fpga_mgr_states { * @disable_timeout_us: maximum time to disable traffic through bridge (uSec) * @config_complete_timeout_us: maximum time for FPGA to switch to operating * status in the write_complete op. + * @firmware_name: name of FPGA image firmware file + * @sgt: scatter/gather table containing FPGA image + * @buf: contiguous buffer containing FPGA image + * @count: size of buf + * @dev: device that owns this + * @overlay: Device Tree overlay */ struct fpga_image_info { u32 flags; u32 enable_timeout_us; u32 disable_timeout_us; u32 config_complete_timeout_us; + char *firmware_name; + struct sg_table *sgt; + const char *buf; + size_t count; + struct device *dev; +#ifdef CONFIG_OF + struct device_node *overlay; +#endif }; /** @@ -100,6 +115,7 @@ struct fpga_image_info { * @write_sg: write the scatter list of configuration data to the FPGA * @write_complete: set FPGA to operating state after writing is done * @fpga_remove: optional: Set FPGA into a specific state during driver remove + * @groups: optional attribute groups. * * fpga_manager_ops are the low level functions implemented by a specific * fpga manager driver. The optional ones are tested for NULL before being @@ -116,6 +132,7 @@ struct fpga_manager_ops { int (*write_complete)(struct fpga_manager *mgr, struct fpga_image_info *info); void (*fpga_remove)(struct fpga_manager *mgr); + const struct attribute_group **groups; }; /** @@ -138,14 +155,14 @@ struct fpga_manager { #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev) -int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, - const char *buf, size_t count); -int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, - struct sg_table *sgt); +struct fpga_image_info *fpga_image_info_alloc(struct device *dev); + +void fpga_image_info_free(struct fpga_image_info *info); + +int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info); -int fpga_mgr_firmware_load(struct fpga_manager *mgr, - struct fpga_image_info *info, - const char *image_name); +int fpga_mgr_lock(struct fpga_manager *mgr); +void fpga_mgr_unlock(struct fpga_manager *mgr); struct fpga_manager *of_fpga_mgr_get(struct device_node *node); diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h new file mode 100644 index 000000000000..b6520318ab9c --- /dev/null +++ b/include/linux/fpga/fpga-region.h @@ -0,0 +1,40 @@ +#ifndef _FPGA_REGION_H +#define _FPGA_REGION_H + +#include <linux/device.h> +#include <linux/fpga/fpga-mgr.h> +#include <linux/fpga/fpga-bridge.h> + +/** + * struct fpga_region - FPGA Region structure + * @dev: FPGA Region device + * @mutex: enforces exclusive reference to region + * @bridge_list: list of FPGA bridges specified in region + * @mgr: FPGA manager + * @info: FPGA image info + * @priv: private data + * @get_bridges: optional function to get bridges to a list + * @groups: optional attribute groups. + */ +struct fpga_region { + struct device dev; + struct mutex mutex; /* for exclusive reference to region */ + struct list_head bridge_list; + struct fpga_manager *mgr; + struct fpga_image_info *info; + void *priv; + int (*get_bridges)(struct fpga_region *region); + const struct attribute_group **groups; +}; + +#define to_fpga_region(d) container_of(d, struct fpga_region, dev) + +struct fpga_region *fpga_region_class_find( + struct device *start, const void *data, + int (*match)(struct device *, const void *)); + +int fpga_region_program_fpga(struct fpga_region *region); +int fpga_region_register(struct device *dev, struct fpga_region *region); +int fpga_region_unregister(struct fpga_region *region); + +#endif /* _FPGA_REGION_H */ diff --git a/include/linux/hil_mlc.h b/include/linux/hil_mlc.h index 394a8405dd74..774f7d3b8f6a 100644 --- a/include/linux/hil_mlc.h +++ b/include/linux/hil_mlc.h @@ -144,12 +144,12 @@ struct hil_mlc { hil_packet ipacket[16]; hil_packet imatch; int icount; - struct timeval instart; - suseconds_t intimeout; + unsigned long instart; + unsigned long intimeout; int ddi; /* Last operational device id */ int lcv; /* LCV to throttle loops */ - struct timeval lcv_tv; /* Time loop was started */ + time64_t lcv_time; /* Time loop was started */ int di_map[7]; /* Maps below items to live devs */ struct hil_mlc_devinfo di[HIL_MLC_DEVMEM]; diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h index d392975d8887..6f1dee7e67e0 100644 --- a/include/linux/hp_sdc.h +++ b/include/linux/hp_sdc.h @@ -281,7 +281,7 @@ typedef struct { hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */ int rcurr, rqty; /* Current read transact in process */ - struct timeval rtv; /* Time when current read started */ + ktime_t rtime; /* Time when current read started */ int wcurr; /* Current write transact in process */ int dev_err; /* carries status from registration */ diff --git a/include/linux/i7300_idle.h b/include/linux/i7300_idle.h deleted file mode 100644 index 4dbe651f71f5..000000000000 --- a/include/linux/i7300_idle.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef I7300_IDLE_H -#define I7300_IDLE_H - -#include <linux/pci.h> - -/* - * I/O AT controls (PCI bus 0 device 8 function 0) - * DIMM controls (PCI bus 0 device 16 function 1) - */ -#define IOAT_BUS 0 -#define IOAT_DEVFN PCI_DEVFN(8, 0) -#define MEMCTL_BUS 0 -#define MEMCTL_DEVFN PCI_DEVFN(16, 1) - -struct fbd_ioat { - unsigned int vendor; - unsigned int ioat_dev; - unsigned int enabled; -}; - -/* - * The i5000 chip-set has the same hooks as the i7300 - * but it is not enabled by default and must be manually - * manually enabled with "forceload=1" because it is - * only lightly validated. - */ - -static const struct fbd_ioat fbd_ioat_list[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB, 1}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT, 0}, - {0, 0} -}; - -/* table of devices that work with this driver */ -static const struct pci_device_id pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, - { } /* Terminating entry */ -}; - -/* Check for known platforms with I/O-AT */ -static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev, - struct pci_dev **ioat_dev, - int enable_all) -{ - int i; - struct pci_dev *memdev, *dmadev; - - memdev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN); - if (!memdev) - return -ENODEV; - - for (i = 0; pci_tbl[i].vendor != 0; i++) { - if (memdev->vendor == pci_tbl[i].vendor && - memdev->device == pci_tbl[i].device) { - break; - } - } - if (pci_tbl[i].vendor == 0) - return -ENODEV; - - dmadev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN); - if (!dmadev) - return -ENODEV; - - for (i = 0; fbd_ioat_list[i].vendor != 0; i++) { - if (dmadev->vendor == fbd_ioat_list[i].vendor && - dmadev->device == fbd_ioat_list[i].ioat_dev) { - if (!(fbd_ioat_list[i].enabled || enable_all)) - continue; - if (fbd_dev) - *fbd_dev = memdev; - if (ioat_dev) - *ioat_dev = dmadev; - - return 0; - } - } - return -ENODEV; -} - -#endif diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index f12a61be1ede..11579fd4126e 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -578,8 +578,8 @@ const struct iio_chan_spec * iio_device_register() - register a device with the IIO subsystem * @indio_dev: Device structure filled by the device driver **/ -#define iio_device_register(iio_dev) \ - __iio_device_register((iio_dev), THIS_MODULE) +#define iio_device_register(indio_dev) \ + __iio_device_register((indio_dev), THIS_MODULE) int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod); void iio_device_unregister(struct iio_dev *indio_dev); /** diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 1601a2a63a72..5e1cfa75f652 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -28,4 +28,11 @@ struct iio_map { void *consumer_data; }; +#define IIO_MAP(_provider_channel, _consumer_dev_name, _consumer_channel) \ +{ \ + .adc_channel_label = _provider_channel, \ + .consumer_dev_name = _consumer_dev_name, \ + .consumer_channel = _consumer_channel, \ +} + #endif diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index 7d5e44518379..b19b7204ef84 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -43,12 +43,13 @@ struct iio_trigger_ops { /** * struct iio_trigger - industrial I/O trigger device * @ops: [DRIVER] operations structure + * @owner: [INTERN] owner of this driver module * @id: [INTERN] unique id number * @name: [DRIVER] unique name * @dev: [DRIVER] associated device (if relevant) * @list: [INTERN] used in maintenance of global trigger list * @alloc_list: [DRIVER] used for driver specific trigger list - * @use_count: use count for the trigger + * @use_count: [INTERN] use count for the trigger. * @subirq_chip: [INTERN] associate 'virtual' irq chip. * @subirq_base: [INTERN] base number for irqs provided by trigger. * @subirqs: [INTERN] information about the 'child' irqs. diff --git a/include/linux/input/gpio_tilt.h b/include/linux/input/gpio_tilt.h deleted file mode 100644 index f9d932476a80..000000000000 --- a/include/linux/input/gpio_tilt.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _INPUT_GPIO_TILT_H -#define _INPUT_GPIO_TILT_H - -/** - * struct gpio_tilt_axis - Axis used by the tilt switch - * @axis: Constant describing the axis, e.g. ABS_X - * @min: minimum value for abs_param - * @max: maximum value for abs_param - * @fuzz: fuzz value for abs_param - * @flat: flat value for abs_param - */ -struct gpio_tilt_axis { - int axis; - int min; - int max; - int fuzz; - int flat; -}; - -/** - * struct gpio_tilt_state - state description - * @gpios: bitfield of gpio target-states for the value - * @axes: array containing the axes settings for the gpio state - * The array indizes must correspond to the axes defined - * in platform_data - * - * This structure describes a supported axis settings - * and the necessary gpio-state which represent it. - * - * The n-th bit in the bitfield describes the state of the n-th GPIO - * from the gpios-array defined in gpio_regulator_config below. - */ -struct gpio_tilt_state { - int gpios; - int *axes; -}; - -/** - * struct gpio_tilt_platform_data - * @gpios: Array containing the gpios determining the tilt state - * @nr_gpios: Number of gpios - * @axes: Array of gpio_tilt_axis descriptions - * @nr_axes: Number of axes - * @states: Array of gpio_tilt_state entries describing - * the gpio state for specific tilts - * @nr_states: Number of states available - * @debounce_interval: debounce ticks interval in msecs - * @poll_interval: polling interval in msecs - for polling driver only - * @enable: callback to enable the tilt switch - * @disable: callback to disable the tilt switch - * - * This structure contains gpio-tilt-switch configuration - * information that must be passed by platform code to the - * gpio-tilt input driver. - */ -struct gpio_tilt_platform_data { - struct gpio *gpios; - int nr_gpios; - - struct gpio_tilt_axis *axes; - int nr_axes; - - struct gpio_tilt_state *states; - int nr_states; - - int debounce_interval; - - unsigned int poll_interval; - int (*enable)(struct device *dev); - void (*disable)(struct device *dev); -}; - -#endif diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index bd118a6c60cb..d79d1e7486bd 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -9,6 +9,10 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/stddef.h> +#include <linux/mm.h> +#include <linux/module.h> + +#include <asm/sections.h> #define KSYM_NAME_LEN 128 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \ @@ -16,6 +20,56 @@ struct module; +static inline int is_kernel_inittext(unsigned long addr) +{ + if (addr >= (unsigned long)_sinittext + && addr <= (unsigned long)_einittext) + return 1; + return 0; +} + +static inline int is_kernel_text(unsigned long addr) +{ + if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) || + arch_is_kernel_text(addr)) + return 1; + return in_gate_area_no_mm(addr); +} + +static inline int is_kernel(unsigned long addr) +{ + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) + return 1; + return in_gate_area_no_mm(addr); +} + +static inline int is_ksym_addr(unsigned long addr) +{ + if (IS_ENABLED(CONFIG_KALLSYMS_ALL)) + return is_kernel(addr); + + return is_kernel_text(addr) || is_kernel_inittext(addr); +} + +static inline void *dereference_symbol_descriptor(void *ptr) +{ +#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR + struct module *mod; + + ptr = dereference_kernel_function_descriptor(ptr); + if (is_ksym_addr((unsigned long)ptr)) + return ptr; + + preempt_disable(); + mod = __module_address((unsigned long)ptr); + preempt_enable(); + + if (mod) + ptr = dereference_module_function_descriptor(mod, ptr); +#endif + return ptr; +} + #ifdef CONFIG_KALLSYMS /* Lookup the address for a symbol. Returns 0 if not found. */ unsigned long kallsyms_lookup_name(const char *name); @@ -40,9 +94,6 @@ extern int sprint_symbol(char *buffer, unsigned long address); extern int sprint_symbol_no_offset(char *buffer, unsigned long address); extern int sprint_backtrace(char *buffer, unsigned long address); -/* Look up a kernel symbol and print it to the kernel messages. */ -extern void __print_symbol(const char *fmt, unsigned long address); - int lookup_symbol_name(unsigned long addr, char *symname); int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); @@ -112,23 +163,8 @@ static inline int kallsyms_show_value(void) return false; } -/* Stupid that this does nothing, but I didn't create this mess. */ -#define __print_symbol(fmt, addr) #endif /*CONFIG_KALLSYMS*/ -/* This macro allows us to keep printk typechecking */ -static __printf(1, 2) -void __check_printsym_format(const char *fmt, ...) -{ -} - -static inline void print_symbol(const char *fmt, unsigned long addr) -{ - __check_printsym_format(fmt, ""); - __print_symbol(fmt, (unsigned long) - __builtin_extract_return_addr((void *)addr)); -} - static inline void print_ip_sym(unsigned long ip) { printk("[<%p>] %pS\n", (void *) ip, (void *) ip); diff --git a/include/linux/kobject.h b/include/linux/kobject.h index e0a6205caa71..7f6f93c3df9c 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * kobject.h - generic kernel object infrastructure. * @@ -6,8 +7,6 @@ * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com> * Copyright (c) 2006-2008 Novell Inc. * - * This file is released under the GPLv2. - * * Please read Documentation/kobject.txt before using the kobject * interface, ESPECIALLY the parts about reference counts and object * destructors. diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h index df32d2508290..069aa2ebef90 100644 --- a/include/linux/kobject_ns.h +++ b/include/linux/kobject_ns.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Kernel object name space definitions * * Copyright (c) 2002-2003 Patrick Mochel @@ -7,8 +8,6 @@ * * Split from kobject.h by David Howells (dhowells@redhat.com) * - * This file is released under the GPLv2. - * * Please read Documentation/kobject.txt before using the kobject * interface, ESPECIALLY the parts about reference counts and object * destructors. diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h index 27ba06e5d117..90ed4ebfa692 100644 --- a/include/linux/libfdt.h +++ b/include/linux/libfdt.h @@ -3,7 +3,6 @@ #define _INCLUDE_LIBFDT_H_ #include <linux/libfdt_env.h> -#include "../../scripts/dtc/libfdt/fdt.h" #include "../../scripts/dtc/libfdt/libfdt.h" #endif /* _INCLUDE_LIBFDT_H_ */ diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index a83f6498b95e..2b96e630e3b6 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -291,6 +291,9 @@ enum host_event_code { /* EC desires to change state of host-controlled USB mux */ EC_HOST_EVENT_USB_MUX = 28, + /* EC RTC event occurred */ + EC_HOST_EVENT_RTC = 26, + /* * The high bit of the event mask is not used as a host event code. If * it reads back as set, then the entire event mask should be @@ -799,6 +802,8 @@ enum ec_feature_code { EC_FEATURE_USB_MUX = 23, /* Motion Sensor code has an internal software FIFO */ EC_FEATURE_MOTION_SENSE_FIFO = 24, + /* EC has RTC feature that can be controlled by host commands */ + EC_FEATURE_RTC = 27, }; #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) @@ -1709,6 +1714,9 @@ struct ec_response_rtc { #define EC_CMD_RTC_SET_VALUE 0x46 #define EC_CMD_RTC_SET_ALARM 0x47 +/* Pass as param to SET_ALARM to clear the current alarm */ +#define EC_RTC_ALARM_CLEAR 0 + /*****************************************************************************/ /* Port80 log access */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index abb6dc2ebbf8..48fb2b43c35a 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -229,6 +229,12 @@ struct hda_device_id { unsigned long driver_data; }; +struct sdw_device_id { + __u16 mfg_id; + __u16 part_id; + kernel_ulong_t driver_data; +}; + /* * Struct used for matching a device */ @@ -452,6 +458,19 @@ struct spi_device_id { kernel_ulong_t driver_data; /* Data private to the driver */ }; +/* SLIMbus */ + +#define SLIMBUS_NAME_SIZE 32 +#define SLIMBUS_MODULE_PREFIX "slim:" + +struct slim_device_id { + __u16 manf_id, prod_code; + __u16 dev_index, instance; + + /* Data private to the driver */ + kernel_ulong_t driver_data; +}; + #define SPMI_NAME_SIZE 32 #define SPMI_MODULE_PREFIX "spmi:" diff --git a/include/linux/module.h b/include/linux/module.h index 70245f1a3590..8dc7065d904d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -612,6 +612,9 @@ int ref_module(struct module *a, struct module *b); __mod ? __mod->name : "kernel"; \ }) +/* Dereference module function descriptor */ +void *dereference_module_function_descriptor(struct module *mod, void *ptr); + /* For kallsyms to ask for address resolution. namebuf should be at * least KSYM_NAME_LEN long: a pointer to namebuf is returned if * found, otherwise NULL. */ @@ -766,6 +769,13 @@ static inline bool is_module_sig_enforced(void) return false; } +/* Dereference module function descriptor */ +static inline +void *dereference_module_function_descriptor(struct module *mod, void *ptr) +{ + return ptr; +} + #endif /* CONFIG_MODULES */ #ifdef CONFIG_SYSFS diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h index ea96d4c82be7..5fc6bb2fefad 100644 --- a/include/linux/mux/consumer.h +++ b/include/linux/mux/consumer.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mux/consumer.h - definitions for the multiplexer consumer interface * * Copyright (C) 2017 Axentia Technologies AB * * Author: Peter Rosin <peda@axentia.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef _LINUX_MUX_CONSUMER_H diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h index 35c3579c3304..627a2c6bc02d 100644 --- a/include/linux/mux/driver.h +++ b/include/linux/mux/driver.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mux/driver.h - definitions for the multiplexer driver interface * * Copyright (C) 2017 Axentia Technologies AB * * Author: Peter Rosin <peda@axentia.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef _LINUX_MUX_DRIVER_H diff --git a/include/linux/of.h b/include/linux/of.h index 173102dafb07..da1ee95241c1 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ #ifndef _LINUX_OF_H #define _LINUX_OF_H /* @@ -9,11 +10,6 @@ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. * Updates for SPARC64 by David S. Miller * Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include <linux/types.h> #include <linux/bitops.h> diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h index b90d8ec57c1f..fd706cdf255c 100644 --- a/include/linux/of_dma.h +++ b/include/linux/of_dma.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OF helpers for DMA request / controller * * Based on of_gpio.h * * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __LINUX_OF_DMA_H diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 013c5418aeec..b9cd9ebdf9b9 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for working with the Flattened Device Tree data format * * Copyright 2009 Benjamin Herrenschmidt, IBM Corp * benh@kernel.crashing.org - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #ifndef _LINUX_OF_FDT_H @@ -47,6 +44,12 @@ extern void *initial_boot_params; extern char __dtb_start[]; extern char __dtb_end[]; +/* Other Prototypes */ +extern u64 of_flat_dt_translate_address(unsigned long node); +extern void of_fdt_limit_memory(int limit); +#endif /* CONFIG_OF_FLATTREE */ + +#ifdef CONFIG_OF_EARLY_FLATTREE /* For scanning the flat device-tree at boot time */ extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, int depth, void *data), @@ -77,7 +80,6 @@ extern void early_init_dt_add_memory_arch(u64 base, u64 size); extern int early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size); extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, bool no_map); -extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align); extern u64 dt_mem_next_cell(int s, const __be32 **cellp); /* Early flat tree scan hooks */ @@ -97,16 +99,14 @@ extern void unflatten_device_tree(void); extern void unflatten_and_copy_device_tree(void); extern void early_init_devtree(void *); extern void early_get_first_memblock_info(void *, phys_addr_t *); -extern u64 of_flat_dt_translate_address(unsigned long node); -extern void of_fdt_limit_memory(int limit); -#else /* CONFIG_OF_FLATTREE */ +#else /* CONFIG_OF_EARLY_FLATTREE */ static inline int early_init_dt_scan_chosen_stdout(void) { return -ENODEV; } static inline void early_init_fdt_scan_reserved_mem(void) {} static inline void early_init_fdt_reserve_self(void) {} static inline const char *of_flat_dt_get_machine_name(void) { return NULL; } static inline void unflatten_device_tree(void) {} static inline void unflatten_and_copy_device_tree(void) {} -#endif /* CONFIG_OF_FLATTREE */ +#endif /* CONFIG_OF_EARLY_FLATTREE */ #endif /* __ASSEMBLY__ */ #endif /* _LINUX_OF_FDT_H */ diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 18a7f03e1182..163b79ecd01a 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -1,14 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * OF helpers for the GPIO API * * Copyright (c) 2007-2008 MontaVista Software, Inc. * * Author: Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __LINUX_OF_GPIO_H diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h index 3e058f05ab04..01038a6aade0 100644 --- a/include/linux/of_graph.h +++ b/include/linux/of_graph.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OF graph binding parsing helpers * @@ -6,10 +7,6 @@ * * Copyright (C) 2012 Renesas Electronics Corp. * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. */ #ifndef __LINUX_OF_GRAPH_H #define __LINUX_OF_GRAPH_H diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h index 7e09244bb679..d0b183ab65c6 100644 --- a/include/linux/of_pdt.h +++ b/include/linux/of_pdt.h @@ -1,13 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Definitions for building a device tree by calling into the * Open Firmware PROM. * * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #ifndef _LINUX_OF_PDT_H diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index fb908e598348..84a966623e78 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -1,14 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ #ifndef _LINUX_OF_PLATFORM_H #define _LINUX_OF_PLATFORM_H /* * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. * <benh@kernel.crashing.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * */ #include <linux/device.h> diff --git a/include/linux/pci.h b/include/linux/pci.h index 0314e0716c30..ad35aac87971 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1965,6 +1965,7 @@ int pci_vfs_assigned(struct pci_dev *dev); int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); int pci_sriov_get_totalvfs(struct pci_dev *dev); resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno); +void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe); #else static inline int pci_iov_virtfn_bus(struct pci_dev *dev, int id) { @@ -1992,6 +1993,7 @@ static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) { return 0; } static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno) { return 0; } +static inline void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe) { } #endif #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) @@ -2279,6 +2281,42 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev) return false; } +/** + * pci_uevent_ers - emit a uevent during recovery path of pci device + * @pdev: pci device to check + * @err_type: type of error event + * + */ +static inline void pci_uevent_ers(struct pci_dev *pdev, + enum pci_ers_result err_type) +{ + int idx = 0; + char *envp[3]; + + switch (err_type) { + case PCI_ERS_RESULT_NONE: + case PCI_ERS_RESULT_CAN_RECOVER: + envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; + envp[idx++] = "DEVICE_ONLINE=0"; + break; + case PCI_ERS_RESULT_RECOVERED: + envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY"; + envp[idx++] = "DEVICE_ONLINE=1"; + break; + case PCI_ERS_RESULT_DISCONNECT: + envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY"; + envp[idx++] = "DEVICE_ONLINE=0"; + break; + default: + break; + } + + if (idx > 0) { + envp[idx++] = NULL; + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp); + } +} + /* provide the legacy pci_dma_* API */ #include <linux/pci-dma-compat.h> diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h index 05082e407c4a..d01a8638bb45 100644 --- a/include/linux/pinctrl/devinfo.h +++ b/include/linux/pinctrl/devinfo.h @@ -43,6 +43,8 @@ extern int pinctrl_init_done(struct device *dev); #else +struct device; + /* Stubs if we're not using pinctrl */ static inline int pinctrl_bind_pins(struct device *dev) diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 5e45385c5bdc..8f5dbb84547a 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -18,6 +18,7 @@ #include <linux/list.h> #include <linux/seq_file.h> #include <linux/pinctrl/pinctrl-state.h> +#include <linux/pinctrl/devinfo.h> struct device; struct pinctrl_dev; diff --git a/include/linux/i2c/pxa-i2c.h b/include/linux/platform_data/i2c-pxa.h index 53aab243cbd8..5236f216dfae 100644 --- a/include/linux/i2c/pxa-i2c.h +++ b/include/linux/platform_data/i2c-pxa.h @@ -71,15 +71,4 @@ struct i2c_pxa_platform_data { unsigned char master_code; unsigned long rate; }; - -extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); - -#ifdef CONFIG_PXA27x -extern void pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info); -#endif - -#ifdef CONFIG_PXA3xx -extern void pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info); -#endif - #endif diff --git a/include/linux/platform_data/mms114.h b/include/linux/platform_data/mms114.h deleted file mode 100644 index 5722ebfb2738..000000000000 --- a/include/linux/platform_data/mms114.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#ifndef __LINUX_MMS114_H -#define __LINUX_MMS114_H - -struct mms114_platform_data { - unsigned int x_size; - unsigned int y_size; - unsigned int contact_threshold; - unsigned int moving_threshold; - bool x_invert; - bool y_invert; - - void (*cfg_pin)(bool); -}; - -#endif /* __LINUX_MMS114_H */ diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h index 818c5c6e203f..c71a2dd66143 100644 --- a/include/linux/platform_data/si5351.h +++ b/include/linux/platform_data/si5351.h @@ -86,6 +86,7 @@ enum si5351_disable_state { * @multisynth_src: multisynth source clock * @clkout_src: clkout source clock * @pll_master: if true, clkout can also change pll rate + * @pll_reset: if true, clkout can reset its pll * @drive: output drive strength * @rate: initial clkout rate, or default if 0 */ @@ -95,6 +96,7 @@ struct si5351_clkout_config { enum si5351_drive_strength drive; enum si5351_disable_state disable_state; bool pll_master; + bool pll_reset; unsigned long rate; }; diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h new file mode 100644 index 000000000000..1be356330b96 --- /dev/null +++ b/include/linux/platform_data/ti-sysc.h @@ -0,0 +1,86 @@ +#ifndef __TI_SYSC_DATA_H__ +#define __TI_SYSC_DATA_H__ + +enum ti_sysc_module_type { + TI_SYSC_OMAP2, + TI_SYSC_OMAP2_TIMER, + TI_SYSC_OMAP3_SHAM, + TI_SYSC_OMAP3_AES, + TI_SYSC_OMAP4, + TI_SYSC_OMAP4_TIMER, + TI_SYSC_OMAP4_SIMPLE, + TI_SYSC_OMAP34XX_SR, + TI_SYSC_OMAP36XX_SR, + TI_SYSC_OMAP4_SR, + TI_SYSC_OMAP4_MCASP, + TI_SYSC_OMAP4_USB_HOST_FS, +}; + +/** + * struct sysc_regbits - TI OCP_SYSCONFIG register field offsets + * @midle_shift: Offset of the midle bit + * @clkact_shift: Offset of the clockactivity bit + * @sidle_shift: Offset of the sidle bit + * @enwkup_shift: Offset of the enawakeup bit + * @srst_shift: Offset of the softreset bit + * @autoidle_shift: Offset of the autoidle bit + * @dmadisable_shift: Offset of the dmadisable bit + * @emufree_shift; Offset of the emufree bit + * + * Note that 0 is a valid shift, and for ti-sysc.c -ENODEV can be used if a + * feature is not available. + */ +struct sysc_regbits { + s8 midle_shift; + s8 clkact_shift; + s8 sidle_shift; + s8 enwkup_shift; + s8 srst_shift; + s8 autoidle_shift; + s8 dmadisable_shift; + s8 emufree_shift; +}; + +#define SYSC_QUIRK_RESET_STATUS BIT(7) +#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) +#define SYSC_QUIRK_NO_RESET_ON_INIT BIT(5) +#define SYSC_QUIRK_OPT_CLKS_NEEDED BIT(4) +#define SYSC_QUIRK_OPT_CLKS_IN_RESET BIT(3) +#define SYSC_QUIRK_16BIT BIT(2) +#define SYSC_QUIRK_UNCACHED BIT(1) +#define SYSC_QUIRK_USE_CLOCKACT BIT(0) + +#define SYSC_NR_IDLEMODES 4 + +/** + * struct sysc_capabilities - capabilities for an interconnect target module + * + * @sysc_mask: bitmask of supported SYSCONFIG register bits + * @regbits: bitmask of SYSCONFIG register bits + * @mod_quirks: bitmask of module specific quirks + */ +struct sysc_capabilities { + const enum ti_sysc_module_type type; + const u32 sysc_mask; + const struct sysc_regbits *regbits; + const u32 mod_quirks; +}; + +/** + * struct sysc_config - configuration for an interconnect target module + * @sysc_val: configured value for sysc register + * @midlemodes: bitmask of supported master idle modes + * @sidlemodes: bitmask of supported master idle modes + * @srst_udelay: optional delay needed after OCP soft reset + * @quirks: bitmask of enabled quirks + */ +struct sysc_config { + u32 sysc_val; + u32 syss_mask; + u8 midlemodes; + u8 sidlemodes; + u8 srst_udelay; + u32 quirks; +}; + +#endif /* __TI_SYSC_DATA_H__ */ diff --git a/include/linux/property.h b/include/linux/property.h index 1106bc62dd8c..769d372c1edf 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -214,7 +214,7 @@ struct property_entry { */ #define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _val_) \ -{ \ +(struct property_entry) { \ .name = _name_, \ .length = ARRAY_SIZE(_val_) * sizeof(_type_), \ .is_array = true, \ @@ -232,7 +232,7 @@ struct property_entry { PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, _val_) #define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \ -{ \ +(struct property_entry) { \ .name = _name_, \ .length = ARRAY_SIZE(_val_) * sizeof(const char *), \ .is_array = true, \ @@ -241,7 +241,7 @@ struct property_entry { } #define PROPERTY_ENTRY_INTEGER(_name_, _type_, _val_) \ -{ \ +(struct property_entry) { \ .name = _name_, \ .length = sizeof(_type_), \ .is_string = false, \ @@ -258,7 +258,7 @@ struct property_entry { PROPERTY_ENTRY_INTEGER(_name_, u64, _val_) #define PROPERTY_ENTRY_STRING(_name_, _val_) \ -{ \ +(struct property_entry) { \ .name = _name_, \ .length = sizeof(_val_), \ .is_string = true, \ @@ -266,7 +266,7 @@ struct property_entry { } #define PROPERTY_ENTRY_BOOL(_name_) \ -{ \ +(struct property_entry) { \ .name = _name_, \ } diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 1fd27d68926b..b401b962afff 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -13,6 +13,9 @@ #ifndef __QCOM_SCM_H #define __QCOM_SCM_H +#include <linux/types.h> +#include <linux/cpumask.h> + #define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) #define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0 #define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1 diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 20268b7d5001..6a3aeba40e9e 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -24,6 +24,7 @@ struct module; struct device; struct i2c_client; struct irq_domain; +struct slim_device; struct spi_device; struct spmi_device; struct regmap; @@ -511,6 +512,10 @@ struct regmap *__regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); +struct regmap *__regmap_init_slimbus(struct slim_device *slimbus, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); struct regmap *__regmap_init_spi(struct spi_device *dev, const struct regmap_config *config, struct lock_class_key *lock_key, @@ -636,6 +641,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, i2c, config) /** + * regmap_init_slimbus() - Initialise register map + * + * @slimbus: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer to + * a struct regmap. + */ +#define regmap_init_slimbus(slimbus, config) \ + __regmap_lockdep_wrapper(__regmap_init_slimbus, #config, \ + slimbus, config) + +/** * regmap_init_spi() - Initialise register map * * @dev: Device that will be interacted with diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 21fc84d82d41..02166e815afb 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -167,6 +167,29 @@ reservation_object_lock(struct reservation_object *obj, } /** + * reservation_object_lock_interruptible - lock the reservation object + * @obj: the reservation object + * @ctx: the locking context + * + * Locks the reservation object interruptible for exclusive access and + * modification. Note, that the lock is only against other writers, readers + * will run concurrently with a writer under RCU. The seqlock is used to + * notify readers if they overlap with a writer. + * + * As the reservation object may be locked by multiple parties in an + * undefined order, a #ww_acquire_ctx is passed to unwind if a cycle + * is detected. See ww_mutex_lock() and ww_acquire_init(). A reservation + * object may be locked by itself by passing NULL as @ctx. + */ +static inline int +reservation_object_lock_interruptible(struct reservation_object *obj, + struct ww_acquire_ctx *ctx) +{ + return ww_mutex_lock_interruptible(&obj->lock, ctx); +} + + +/** * reservation_object_trylock - trylock the reservation object * @obj: the reservation object * diff --git a/include/linux/reset.h b/include/linux/reset.h index 4c7871ddf3c6..09732c36f351 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -2,8 +2,10 @@ #ifndef _LINUX_RESET_H_ #define _LINUX_RESET_H_ -#include <linux/device.h> +#include <linux/types.h> +struct device; +struct device_node; struct reset_control; #ifdef CONFIG_RESET_CONTROLLER @@ -20,22 +22,16 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id, int index, bool shared, bool optional); void reset_control_put(struct reset_control *rstc); +int __device_reset(struct device *dev, bool optional); struct reset_control *__devm_reset_control_get(struct device *dev, const char *id, int index, bool shared, bool optional); -int __must_check device_reset(struct device *dev); - struct reset_control *devm_reset_control_array_get(struct device *dev, bool shared, bool optional); struct reset_control *of_reset_control_array_get(struct device_node *np, bool shared, bool optional); -static inline int device_reset_optional(struct device *dev) -{ - return device_reset(dev); -} - #else static inline int reset_control_reset(struct reset_control *rstc) @@ -62,15 +58,9 @@ static inline void reset_control_put(struct reset_control *rstc) { } -static inline int __must_check device_reset(struct device *dev) -{ - WARN_ON(1); - return -ENOTSUPP; -} - -static inline int device_reset_optional(struct device *dev) +static inline int __device_reset(struct device *dev, bool optional) { - return -ENOTSUPP; + return optional ? 0 : -ENOTSUPP; } static inline struct reset_control *__of_reset_control_get( @@ -109,6 +99,16 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional) #endif /* CONFIG_RESET_CONTROLLER */ +static inline int __must_check device_reset(struct device *dev) +{ + return __device_reset(dev, false); +} + +static inline int device_reset_optional(struct device *dev) +{ + return __device_reset(dev, true); +} + /** * reset_control_get_exclusive - Lookup and obtain an exclusive reference * to a reset controller. @@ -127,9 +127,6 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional) static inline struct reset_control * __must_check reset_control_get_exclusive(struct device *dev, const char *id) { -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif return __reset_control_get(dev, id, 0, false, false); } @@ -275,9 +272,6 @@ static inline struct reset_control * __must_check devm_reset_control_get_exclusive(struct device *dev, const char *id) { -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif return __devm_reset_control_get(dev, id, 0, false, false); } @@ -350,18 +344,6 @@ devm_reset_control_get_shared_by_index(struct device *dev, int index) * These inline function calls will be removed once all consumers * have been moved over to the new explicit API. */ -static inline struct reset_control *reset_control_get( - struct device *dev, const char *id) -{ - return reset_control_get_exclusive(dev, id); -} - -static inline struct reset_control *reset_control_get_optional( - struct device *dev, const char *id) -{ - return reset_control_get_optional_exclusive(dev, id); -} - static inline struct reset_control *of_reset_control_get( struct device_node *node, const char *id) { diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 41319a2e409b..fc6c90b57be0 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -87,7 +87,6 @@ struct rtc_class_ops { int (*set_offset)(struct device *, long offset); }; -#define RTC_DEVICE_NAME_SIZE 20 typedef struct rtc_task { void (*func)(void *private_data); void *private_data; diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 531031a15cdd..f153b2c7f0cd 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -27,8 +27,10 @@ struct serdev_device; /** * struct serdev_device_ops - Callback operations for a serdev device - * @receive_buf: Function called with data received from device. - * @write_wakeup: Function called when ready to transmit more data. + * @receive_buf: Function called with data received from device; + * returns number of bytes accepted; may sleep. + * @write_wakeup: Function called when ready to transmit more data; must + * not sleep. */ struct serdev_device_ops { int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 37b044e78333..4c310c34ddad 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -387,7 +387,7 @@ struct uart_port *uart_get_console(struct uart_port *ports, int nr, struct console *c); int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr, char **options); -void uart_parse_options(char *options, int *baud, int *parity, int *bits, +void uart_parse_options(const char *options, int *baud, int *parity, int *bits, int *flow); int uart_set_options(struct uart_port *port, struct console *co, int baud, int parity, int bits, int flow); @@ -501,9 +501,5 @@ static inline int uart_handle_break(struct uart_port *port) (cflag) & CRTSCTS || \ !((cflag) & CLOCAL)) -/* - * Common device tree parsing helpers - */ -void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf); - +void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf); #endif /* LINUX_SERIAL_CORE_H */ diff --git a/include/linux/siox.h b/include/linux/siox.h new file mode 100644 index 000000000000..d79624e83134 --- /dev/null +++ b/include/linux/siox.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include <linux/device.h> + +#define to_siox_device(_dev) container_of((_dev), struct siox_device, dev) +struct siox_device { + struct list_head node; /* node in smaster->devices */ + struct siox_master *smaster; + struct device dev; + + const char *type; + size_t inbytes; + size_t outbytes; + u8 statustype; + + u8 status_read_clean; + u8 status_written; + u8 status_written_lastcycle; + bool connected; + + /* statistics */ + unsigned int watchdog_errors; + unsigned int status_errors; + + struct kernfs_node *status_errors_kn; + struct kernfs_node *watchdog_kn; + struct kernfs_node *watchdog_errors_kn; + struct kernfs_node *connected_kn; +}; + +bool siox_device_synced(struct siox_device *sdevice); +bool siox_device_connected(struct siox_device *sdevice); + +struct siox_driver { + int (*probe)(struct siox_device *sdevice); + int (*remove)(struct siox_device *sdevice); + void (*shutdown)(struct siox_device *sdevice); + + /* + * buf is big enough to hold sdev->inbytes - 1 bytes, the status byte + * is in the scope of the framework. + */ + int (*set_data)(struct siox_device *sdevice, u8 status, u8 buf[]); + /* + * buf is big enough to hold sdev->outbytes - 1 bytes, the status byte + * is in the scope of the framework + */ + int (*get_data)(struct siox_device *sdevice, const u8 buf[]); + + struct device_driver driver; +}; + +static inline struct siox_driver *to_siox_driver(struct device_driver *driver) +{ + if (driver) + return container_of(driver, struct siox_driver, driver); + else + return NULL; +} + +int __siox_driver_register(struct siox_driver *sdriver, struct module *owner); + +static inline int siox_driver_register(struct siox_driver *sdriver) +{ + return __siox_driver_register(sdriver, THIS_MODULE); +} + +static inline void siox_driver_unregister(struct siox_driver *sdriver) +{ + return driver_unregister(&sdriver->driver); +} diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h new file mode 100644 index 000000000000..c36cf121d2cd --- /dev/null +++ b/include/linux/slimbus.h @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2017, The Linux Foundation + */ + +#ifndef _LINUX_SLIMBUS_H +#define _LINUX_SLIMBUS_H +#include <linux/device.h> +#include <linux/module.h> +#include <linux/completion.h> +#include <linux/mod_devicetable.h> + +extern struct bus_type slimbus_bus; + +/** + * struct slim_eaddr - Enumeration address for a SLIMbus device + * @manf_id: Manufacturer Id for the device + * @prod_code: Product code + * @dev_index: Device index + * @instance: Instance value + */ +struct slim_eaddr { + u16 manf_id; + u16 prod_code; + u8 dev_index; + u8 instance; +} __packed; + +/** + * enum slim_device_status - slim device status + * @SLIM_DEVICE_STATUS_DOWN: Slim device is absent or not reported yet. + * @SLIM_DEVICE_STATUS_UP: Slim device is announced on the bus. + * @SLIM_DEVICE_STATUS_RESERVED: Reserved for future use. + */ +enum slim_device_status { + SLIM_DEVICE_STATUS_DOWN = 0, + SLIM_DEVICE_STATUS_UP, + SLIM_DEVICE_STATUS_RESERVED, +}; + +struct slim_controller; + +/** + * struct slim_device - Slim device handle. + * @dev: Driver model representation of the device. + * @e_addr: Enumeration address of this device. + * @status: slim device status + * @ctrl: slim controller instance. + * @laddr: 1-byte Logical address of this device. + * @is_laddr_valid: indicates if the laddr is valid or not + * + * This is the client/device handle returned when a SLIMbus + * device is registered with a controller. + * Pointer to this structure is used by client-driver as a handle. + */ +struct slim_device { + struct device dev; + struct slim_eaddr e_addr; + struct slim_controller *ctrl; + enum slim_device_status status; + u8 laddr; + bool is_laddr_valid; +}; + +#define to_slim_device(d) container_of(d, struct slim_device, dev) + +/** + * struct slim_driver - SLIMbus 'generic device' (slave) device driver + * (similar to 'spi_device' on SPI) + * @probe: Binds this driver to a SLIMbus device. + * @remove: Unbinds this driver from the SLIMbus device. + * @shutdown: Standard shutdown callback used during powerdown/halt. + * @device_status: This callback is called when + * - The device reports present and gets a laddr assigned + * - The device reports absent, or the bus goes down. + * @driver: SLIMbus device drivers should initialize name and owner field of + * this structure + * @id_table: List of SLIMbus devices supported by this driver + */ + +struct slim_driver { + int (*probe)(struct slim_device *sl); + void (*remove)(struct slim_device *sl); + void (*shutdown)(struct slim_device *sl); + int (*device_status)(struct slim_device *sl, + enum slim_device_status s); + struct device_driver driver; + const struct slim_device_id *id_table; +}; +#define to_slim_driver(d) container_of(d, struct slim_driver, driver) + +/** + * struct slim_val_inf - Slimbus value or information element + * @start_offset: Specifies starting offset in information/value element map + * @rbuf: buffer to read the values + * @wbuf: buffer to write + * @num_bytes: upto 16. This ensures that the message will fit the slicesize + * per SLIMbus spec + * @comp: completion for asynchronous operations, valid only if TID is + * required for transaction, like REQUEST operations. + * Rest of the transactions are synchronous anyway. + */ +struct slim_val_inf { + u16 start_offset; + u8 num_bytes; + u8 *rbuf; + const u8 *wbuf; + struct completion *comp; +}; + +/* + * use a macro to avoid include chaining to get THIS_MODULE + */ +#define slim_driver_register(drv) \ + __slim_driver_register(drv, THIS_MODULE) +int __slim_driver_register(struct slim_driver *drv, struct module *owner); +void slim_driver_unregister(struct slim_driver *drv); + +/** + * module_slim_driver() - Helper macro for registering a SLIMbus driver + * @__slim_driver: slimbus_driver struct + * + * Helper macro for SLIMbus drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_slim_driver(__slim_driver) \ + module_driver(__slim_driver, slim_driver_register, \ + slim_driver_unregister) + +static inline void *slim_get_devicedata(const struct slim_device *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void slim_set_devicedata(struct slim_device *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +struct slim_device *slim_get_device(struct slim_controller *ctrl, + struct slim_eaddr *e_addr); +int slim_get_logical_addr(struct slim_device *sbdev); + +/* Information Element management messages */ +#define SLIM_MSG_MC_REQUEST_INFORMATION 0x20 +#define SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION 0x21 +#define SLIM_MSG_MC_REPLY_INFORMATION 0x24 +#define SLIM_MSG_MC_CLEAR_INFORMATION 0x28 +#define SLIM_MSG_MC_REPORT_INFORMATION 0x29 + +/* Value Element management messages */ +#define SLIM_MSG_MC_REQUEST_VALUE 0x60 +#define SLIM_MSG_MC_REQUEST_CHANGE_VALUE 0x61 +#define SLIM_MSG_MC_REPLY_VALUE 0x64 +#define SLIM_MSG_MC_CHANGE_VALUE 0x68 + +int slim_xfer_msg(struct slim_device *sbdev, struct slim_val_inf *msg, + u8 mc); +int slim_readb(struct slim_device *sdev, u32 addr); +int slim_writeb(struct slim_device *sdev, u32 addr, u8 value); +int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val); +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val); +#endif /* _LINUX_SLIMBUS_H */ diff --git a/include/linux/soc/brcmstb/brcmstb.h b/include/linux/soc/brcmstb/brcmstb.h index 12e548938bbb..8e884e0dda0a 100644 --- a/include/linux/soc/brcmstb/brcmstb.h +++ b/include/linux/soc/brcmstb/brcmstb.h @@ -13,12 +13,6 @@ static inline u32 BRCM_REV(u32 reg) } /* - * Bus Interface Unit control register setup, must happen early during boot, - * before SMP is brought up, called by machine entry point. - */ -void brcmstb_biuctrl_init(void); - -/* * Helper functions for getting family or product id from the * SoC driver. */ diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h index e8d9f0d52933..b0a507d356ef 100644 --- a/include/linux/soc/mediatek/infracfg.h +++ b/include/linux/soc/mediatek/infracfg.h @@ -28,7 +28,8 @@ #define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \ BIT(7) | BIT(8)) -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask); -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask); - +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, + bool reg_update); +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, + bool reg_update); #endif /* __SOC_MEDIATEK_INFRACFG_H */ diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h new file mode 100644 index 000000000000..f4de33654a60 --- /dev/null +++ b/include/linux/soc/qcom/qmi.h @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2017, Linaro Ltd. + */ +#ifndef __QMI_HELPERS_H__ +#define __QMI_HELPERS_H__ + +#include <linux/completion.h> +#include <linux/idr.h> +#include <linux/list.h> +#include <linux/qrtr.h> +#include <linux/types.h> +#include <linux/workqueue.h> + +struct socket; + +/** + * qmi_header - wireformat header of QMI messages + * @type: type of message + * @txn_id: transaction id + * @msg_id: message id + * @msg_len: length of message payload following header + */ +struct qmi_header { + u8 type; + u16 txn_id; + u16 msg_id; + u16 msg_len; +} __packed; + +#define QMI_REQUEST 0 +#define QMI_RESPONSE 2 +#define QMI_INDICATION 4 + +#define QMI_COMMON_TLV_TYPE 0 + +enum qmi_elem_type { + QMI_EOTI, + QMI_OPT_FLAG, + QMI_DATA_LEN, + QMI_UNSIGNED_1_BYTE, + QMI_UNSIGNED_2_BYTE, + QMI_UNSIGNED_4_BYTE, + QMI_UNSIGNED_8_BYTE, + QMI_SIGNED_2_BYTE_ENUM, + QMI_SIGNED_4_BYTE_ENUM, + QMI_STRUCT, + QMI_STRING, +}; + +enum qmi_array_type { + NO_ARRAY, + STATIC_ARRAY, + VAR_LEN_ARRAY, +}; + +/** + * struct qmi_elem_info - describes how to encode a single QMI element + * @data_type: Data type of this element. + * @elem_len: Array length of this element, if an array. + * @elem_size: Size of a single instance of this data type. + * @array_type: Array type of this element. + * @tlv_type: QMI message specific type to identify which element + * is present in an incoming message. + * @offset: Specifies the offset of the first instance of this + * element in the data structure. + * @ei_array: Null-terminated array of @qmi_elem_info to describe nested + * structures. + */ +struct qmi_elem_info { + enum qmi_elem_type data_type; + u32 elem_len; + u32 elem_size; + enum qmi_array_type array_type; + u8 tlv_type; + u32 offset; + struct qmi_elem_info *ei_array; +}; + +#define QMI_RESULT_SUCCESS_V01 0 +#define QMI_RESULT_FAILURE_V01 1 + +#define QMI_ERR_NONE_V01 0 +#define QMI_ERR_MALFORMED_MSG_V01 1 +#define QMI_ERR_NO_MEMORY_V01 2 +#define QMI_ERR_INTERNAL_V01 3 +#define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5 +#define QMI_ERR_INVALID_ID_V01 41 +#define QMI_ERR_ENCODING_V01 58 +#define QMI_ERR_INCOMPATIBLE_STATE_V01 90 +#define QMI_ERR_NOT_SUPPORTED_V01 94 + +/** + * qmi_response_type_v01 - common response header (decoded) + * @result: result of the transaction + * @error: error value, when @result is QMI_RESULT_FAILURE_V01 + */ +struct qmi_response_type_v01 { + u16 result; + u16 error; +}; + +extern struct qmi_elem_info qmi_response_type_v01_ei[]; + +/** + * struct qmi_service - context to track lookup-results + * @service: service type + * @version: version of the @service + * @instance: instance id of the @service + * @node: node of the service + * @port: port of the service + * @priv: handle for client's use + * @list_node: list_head for house keeping + */ +struct qmi_service { + unsigned int service; + unsigned int version; + unsigned int instance; + + unsigned int node; + unsigned int port; + + void *priv; + struct list_head list_node; +}; + +struct qmi_handle; + +/** + * struct qmi_ops - callbacks for qmi_handle + * @new_server: inform client of a new_server lookup-result, returning + * successfully from this call causes the library to call + * @del_server as the service is removed from the + * lookup-result. @priv of the qmi_service can be used by + * the client + * @del_server: inform client of a del_server lookup-result + * @net_reset: inform client that the name service was restarted and + * that and any state needs to be released + * @msg_handler: invoked for incoming messages, allows a client to + * override the usual QMI message handler + * @bye: inform a client that all clients from a node are gone + * @del_client: inform a client that a particular client is gone + */ +struct qmi_ops { + int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc); + void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc); + void (*net_reset)(struct qmi_handle *qmi); + void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, + const void *data, size_t count); + void (*bye)(struct qmi_handle *qmi, unsigned int node); + void (*del_client)(struct qmi_handle *qmi, + unsigned int node, unsigned int port); +}; + +/** + * struct qmi_txn - transaction context + * @qmi: QMI handle this transaction is associated with + * @id: transaction id + * @lock: for synchronization between handler and waiter of messages + * @completion: completion object as the transaction receives a response + * @result: result code for the completed transaction + * @ei: description of the QMI encoded response (optional) + * @dest: destination buffer to decode message into (optional) + */ +struct qmi_txn { + struct qmi_handle *qmi; + + int id; + + struct mutex lock; + struct completion completion; + int result; + + struct qmi_elem_info *ei; + void *dest; +}; + +/** + * struct qmi_msg_handler - description of QMI message handler + * @type: type of message + * @msg_id: message id + * @ei: description of the QMI encoded message + * @decoded_size: size of the decoded object + * @fn: function to invoke as the message is decoded + */ +struct qmi_msg_handler { + unsigned int type; + unsigned int msg_id; + + struct qmi_elem_info *ei; + + size_t decoded_size; + void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, + struct qmi_txn *txn, const void *decoded); +}; + +/** + * struct qmi_handle - QMI context + * @sock: socket handle + * @sock_lock: synchronization of @sock modifications + * @sq: sockaddr of @sock + * @work: work for handling incoming messages + * @wq: workqueue to post @work on + * @recv_buf: scratch buffer for handling incoming messages + * @recv_buf_size: size of @recv_buf + * @lookups: list of registered lookup requests + * @lookup_results: list of lookup-results advertised to the client + * @services: list of registered services (by this client) + * @ops: reference to callbacks + * @txns: outstanding transactions + * @txn_lock: lock for modifications of @txns + * @handlers: list of handlers for incoming messages + */ +struct qmi_handle { + struct socket *sock; + struct mutex sock_lock; + + struct sockaddr_qrtr sq; + + struct work_struct work; + struct workqueue_struct *wq; + + void *recv_buf; + size_t recv_buf_size; + + struct list_head lookups; + struct list_head lookup_results; + struct list_head services; + + struct qmi_ops ops; + + struct idr txns; + struct mutex txn_lock; + + const struct qmi_msg_handler *handlers; +}; + +int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service, + unsigned int version, unsigned int instance); +int qmi_add_server(struct qmi_handle *qmi, unsigned int service, + unsigned int version, unsigned int instance); + +int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len, + const struct qmi_ops *ops, + const struct qmi_msg_handler *handlers); +void qmi_handle_release(struct qmi_handle *qmi); + +ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, + struct qmi_txn *txn, int msg_id, size_t len, + struct qmi_elem_info *ei, const void *c_struct); +ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, + struct qmi_txn *txn, int msg_id, size_t len, + struct qmi_elem_info *ei, const void *c_struct); +ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, + int msg_id, size_t len, struct qmi_elem_info *ei, + const void *c_struct); + +void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, + unsigned int txn_id, struct qmi_elem_info *ei, + const void *c_struct); + +int qmi_decode_message(const void *buf, size_t len, + struct qmi_elem_info *ei, void *c_struct); + +int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, + struct qmi_elem_info *ei, void *c_struct); +int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout); +void qmi_txn_cancel(struct qmi_txn *txn); + +#endif diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h new file mode 100644 index 000000000000..e91fdcf41049 --- /dev/null +++ b/include/linux/soundwire/sdw.h @@ -0,0 +1,479 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2015-17 Intel Corporation. + +#ifndef __SOUNDWIRE_H +#define __SOUNDWIRE_H + +struct sdw_bus; +struct sdw_slave; + +/* SDW spec defines and enums, as defined by MIPI 1.1. Spec */ + +/* SDW Broadcast Device Number */ +#define SDW_BROADCAST_DEV_NUM 15 + +/* SDW Enumeration Device Number */ +#define SDW_ENUM_DEV_NUM 0 + +/* SDW Group Device Numbers */ +#define SDW_GROUP12_DEV_NUM 12 +#define SDW_GROUP13_DEV_NUM 13 + +/* SDW Master Device Number, not supported yet */ +#define SDW_MASTER_DEV_NUM 14 + +#define SDW_NUM_DEV_ID_REGISTERS 6 + +#define SDW_MAX_DEVICES 11 + +/** + * enum sdw_slave_status - Slave status + * @SDW_SLAVE_UNATTACHED: Slave is not attached with the bus. + * @SDW_SLAVE_ATTACHED: Slave is attached with bus. + * @SDW_SLAVE_ALERT: Some alert condition on the Slave + * @SDW_SLAVE_RESERVED: Reserved for future use + */ +enum sdw_slave_status { + SDW_SLAVE_UNATTACHED = 0, + SDW_SLAVE_ATTACHED = 1, + SDW_SLAVE_ALERT = 2, + SDW_SLAVE_RESERVED = 3, +}; + +/** + * enum sdw_command_response - Command response as defined by SDW spec + * @SDW_CMD_OK: cmd was successful + * @SDW_CMD_IGNORED: cmd was ignored + * @SDW_CMD_FAIL: cmd was NACKed + * @SDW_CMD_TIMEOUT: cmd timedout + * @SDW_CMD_FAIL_OTHER: cmd failed due to other reason than above + * + * NOTE: The enum is different than actual Spec as response in the Spec is + * combination of ACK/NAK bits + * + * SDW_CMD_TIMEOUT/FAIL_OTHER is defined for SW use, not in spec + */ +enum sdw_command_response { + SDW_CMD_OK = 0, + SDW_CMD_IGNORED = 1, + SDW_CMD_FAIL = 2, + SDW_CMD_TIMEOUT = 3, + SDW_CMD_FAIL_OTHER = 4, +}; + +/* + * SDW properties, defined in MIPI DisCo spec v1.0 + */ +enum sdw_clk_stop_reset_behave { + SDW_CLK_STOP_KEEP_STATUS = 1, +}; + +/** + * enum sdw_p15_behave - Slave Port 15 behaviour when the Master attempts a + * read + * @SDW_P15_READ_IGNORED: Read is ignored + * @SDW_P15_CMD_OK: Command is ok + */ +enum sdw_p15_behave { + SDW_P15_READ_IGNORED = 0, + SDW_P15_CMD_OK = 1, +}; + +/** + * enum sdw_dpn_type - Data port types + * @SDW_DPN_FULL: Full Data Port is supported + * @SDW_DPN_SIMPLE: Simplified Data Port as defined in spec. + * DPN_SampleCtrl2, DPN_OffsetCtrl2, DPN_HCtrl and DPN_BlockCtrl3 + * are not implemented. + * @SDW_DPN_REDUCED: Reduced Data Port as defined in spec. + * DPN_SampleCtrl2, DPN_HCtrl are not implemented. + */ +enum sdw_dpn_type { + SDW_DPN_FULL = 0, + SDW_DPN_SIMPLE = 1, + SDW_DPN_REDUCED = 2, +}; + +/** + * enum sdw_clk_stop_mode - Clock Stop modes + * @SDW_CLK_STOP_MODE0: Slave can continue operation seamlessly on clock + * restart + * @SDW_CLK_STOP_MODE1: Slave may have entered a deeper power-saving mode, + * not capable of continuing operation seamlessly when the clock restarts + */ +enum sdw_clk_stop_mode { + SDW_CLK_STOP_MODE0 = 0, + SDW_CLK_STOP_MODE1 = 1, +}; + +/** + * struct sdw_dp0_prop - DP0 properties + * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64 + * (inclusive) + * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64 + * (inclusive) + * @num_words: number of wordlengths supported + * @words: wordlengths supported + * @flow_controlled: Slave implementation results in an OK_NotReady + * response + * @simple_ch_prep_sm: If channel prepare sequence is required + * @device_interrupts: If implementation-defined interrupts are supported + * + * The wordlengths are specified by Spec as max, min AND number of + * discrete values, implementation can define based on the wordlengths they + * support + */ +struct sdw_dp0_prop { + u32 max_word; + u32 min_word; + u32 num_words; + u32 *words; + bool flow_controlled; + bool simple_ch_prep_sm; + bool device_interrupts; +}; + +/** + * struct sdw_dpn_audio_mode - Audio mode properties for DPn + * @bus_min_freq: Minimum bus frequency, in Hz + * @bus_max_freq: Maximum bus frequency, in Hz + * @bus_num_freq: Number of discrete frequencies supported + * @bus_freq: Discrete bus frequencies, in Hz + * @min_freq: Minimum sampling frequency, in Hz + * @max_freq: Maximum sampling bus frequency, in Hz + * @num_freq: Number of discrete sampling frequency supported + * @freq: Discrete sampling frequencies, in Hz + * @prep_ch_behave: Specifies the dependencies between Channel Prepare + * sequence and bus clock configuration + * If 0, Channel Prepare can happen at any Bus clock rate + * If 1, Channel Prepare sequence shall happen only after Bus clock is + * changed to a frequency supported by this mode or compatible modes + * described by the next field + * @glitchless: Bitmap describing possible glitchless transitions from this + * Audio Mode to other Audio Modes + */ +struct sdw_dpn_audio_mode { + u32 bus_min_freq; + u32 bus_max_freq; + u32 bus_num_freq; + u32 *bus_freq; + u32 max_freq; + u32 min_freq; + u32 num_freq; + u32 *freq; + u32 prep_ch_behave; + u32 glitchless; +}; + +/** + * struct sdw_dpn_prop - Data Port DPn properties + * @num: port number + * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64 + * (inclusive) + * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64 + * (inclusive) + * @num_words: Number of discrete supported wordlengths + * @words: Discrete supported wordlength + * @type: Data port type. Full, Simplified or Reduced + * @max_grouping: Maximum number of samples that can be grouped together for + * a full data port + * @simple_ch_prep_sm: If the port supports simplified channel prepare state + * machine + * @ch_prep_timeout: Port-specific timeout value, in milliseconds + * @device_interrupts: If set, each bit corresponds to support for + * implementation-defined interrupts + * @max_ch: Maximum channels supported + * @min_ch: Minimum channels supported + * @num_ch: Number of discrete channels supported + * @ch: Discrete channels supported + * @num_ch_combinations: Number of channel combinations supported + * @ch_combinations: Channel combinations supported + * @modes: SDW mode supported + * @max_async_buffer: Number of samples that this port can buffer in + * asynchronous modes + * @block_pack_mode: Type of block port mode supported + * @port_encoding: Payload Channel Sample encoding schemes supported + * @audio_modes: Audio modes supported + */ +struct sdw_dpn_prop { + u32 num; + u32 max_word; + u32 min_word; + u32 num_words; + u32 *words; + enum sdw_dpn_type type; + u32 max_grouping; + bool simple_ch_prep_sm; + u32 ch_prep_timeout; + u32 device_interrupts; + u32 max_ch; + u32 min_ch; + u32 num_ch; + u32 *ch; + u32 num_ch_combinations; + u32 *ch_combinations; + u32 modes; + u32 max_async_buffer; + bool block_pack_mode; + u32 port_encoding; + struct sdw_dpn_audio_mode *audio_modes; +}; + +/** + * struct sdw_slave_prop - SoundWire Slave properties + * @mipi_revision: Spec version of the implementation + * @wake_capable: Wake-up events are supported + * @test_mode_capable: If test mode is supported + * @clk_stop_mode1: Clock-Stop Mode 1 is supported + * @simple_clk_stop_capable: Simple clock mode is supported + * @clk_stop_timeout: Worst-case latency of the Clock Stop Prepare State + * Machine transitions, in milliseconds + * @ch_prep_timeout: Worst-case latency of the Channel Prepare State Machine + * transitions, in milliseconds + * @reset_behave: Slave keeps the status of the SlaveStopClockPrepare + * state machine (P=1 SCSP_SM) after exit from clock-stop mode1 + * @high_PHY_capable: Slave is HighPHY capable + * @paging_support: Slave implements paging registers SCP_AddrPage1 and + * SCP_AddrPage2 + * @bank_delay_support: Slave implements bank delay/bridge support registers + * SCP_BankDelay and SCP_NextFrame + * @p15_behave: Slave behavior when the Master attempts a read to the Port15 + * alias + * @lane_control_support: Slave supports lane control + * @master_count: Number of Masters present on this Slave + * @source_ports: Bitmap identifying source ports + * @sink_ports: Bitmap identifying sink ports + * @dp0_prop: Data Port 0 properties + * @src_dpn_prop: Source Data Port N properties + * @sink_dpn_prop: Sink Data Port N properties + */ +struct sdw_slave_prop { + u32 mipi_revision; + bool wake_capable; + bool test_mode_capable; + bool clk_stop_mode1; + bool simple_clk_stop_capable; + u32 clk_stop_timeout; + u32 ch_prep_timeout; + enum sdw_clk_stop_reset_behave reset_behave; + bool high_PHY_capable; + bool paging_support; + bool bank_delay_support; + enum sdw_p15_behave p15_behave; + bool lane_control_support; + u32 master_count; + u32 source_ports; + u32 sink_ports; + struct sdw_dp0_prop *dp0_prop; + struct sdw_dpn_prop *src_dpn_prop; + struct sdw_dpn_prop *sink_dpn_prop; +}; + +/** + * struct sdw_master_prop - Master properties + * @revision: MIPI spec version of the implementation + * @master_count: Number of masters + * @clk_stop_mode: Bitmap for Clock Stop modes supported + * @max_freq: Maximum Bus clock frequency, in Hz + * @num_clk_gears: Number of clock gears supported + * @clk_gears: Clock gears supported + * @num_freq: Number of clock frequencies supported, in Hz + * @freq: Clock frequencies supported, in Hz + * @default_frame_rate: Controller default Frame rate, in Hz + * @default_row: Number of rows + * @default_col: Number of columns + * @dynamic_frame: Dynamic frame supported + * @err_threshold: Number of times that software may retry sending a single + * command + * @dpn_prop: Data Port N properties + */ +struct sdw_master_prop { + u32 revision; + u32 master_count; + enum sdw_clk_stop_mode clk_stop_mode; + u32 max_freq; + u32 num_clk_gears; + u32 *clk_gears; + u32 num_freq; + u32 *freq; + u32 default_frame_rate; + u32 default_row; + u32 default_col; + bool dynamic_frame; + u32 err_threshold; + struct sdw_dpn_prop *dpn_prop; +}; + +int sdw_master_read_prop(struct sdw_bus *bus); +int sdw_slave_read_prop(struct sdw_slave *slave); + +/* + * SDW Slave Structures and APIs + */ + +/** + * struct sdw_slave_id - Slave ID + * @mfg_id: MIPI Manufacturer ID + * @part_id: Device Part ID + * @class_id: MIPI Class ID, unused now. + * Currently a placeholder in MIPI SoundWire Spec + * @unique_id: Device unique ID + * @sdw_version: SDW version implemented + * + * The order of the IDs here does not follow the DisCo spec definitions + */ +struct sdw_slave_id { + __u16 mfg_id; + __u16 part_id; + __u8 class_id; + __u8 unique_id:4; + __u8 sdw_version:4; +}; + +/** + * struct sdw_slave_intr_status - Slave interrupt status + * @control_port: control port status + * @port: data port status + */ +struct sdw_slave_intr_status { + u8 control_port; + u8 port[15]; +}; + +/** + * struct sdw_slave_ops - Slave driver callback ops + * @read_prop: Read Slave properties + * @interrupt_callback: Device interrupt notification (invoked in thread + * context) + * @update_status: Update Slave status + */ +struct sdw_slave_ops { + int (*read_prop)(struct sdw_slave *sdw); + int (*interrupt_callback)(struct sdw_slave *slave, + struct sdw_slave_intr_status *status); + int (*update_status)(struct sdw_slave *slave, + enum sdw_slave_status status); +}; + +/** + * struct sdw_slave - SoundWire Slave + * @id: MIPI device ID + * @dev: Linux device + * @status: Status reported by the Slave + * @bus: Bus handle + * @ops: Slave callback ops + * @prop: Slave properties + * @node: node for bus list + * @port_ready: Port ready completion flag for each Slave port + * @dev_num: Device Number assigned by Bus + */ +struct sdw_slave { + struct sdw_slave_id id; + struct device dev; + enum sdw_slave_status status; + struct sdw_bus *bus; + const struct sdw_slave_ops *ops; + struct sdw_slave_prop prop; + struct list_head node; + struct completion *port_ready; + u16 dev_num; +}; + +#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev) + +struct sdw_driver { + const char *name; + + int (*probe)(struct sdw_slave *sdw, + const struct sdw_device_id *id); + int (*remove)(struct sdw_slave *sdw); + void (*shutdown)(struct sdw_slave *sdw); + + const struct sdw_device_id *id_table; + const struct sdw_slave_ops *ops; + + struct device_driver driver; +}; + +#define SDW_SLAVE_ENTRY(_mfg_id, _part_id, _drv_data) \ + { .mfg_id = (_mfg_id), .part_id = (_part_id), \ + .driver_data = (unsigned long)(_drv_data) } + +int sdw_handle_slave_status(struct sdw_bus *bus, + enum sdw_slave_status status[]); + +/* + * SDW master structures and APIs + */ + +struct sdw_msg; + +/** + * struct sdw_defer - SDW deffered message + * @length: message length + * @complete: message completion + * @msg: SDW message + */ +struct sdw_defer { + int length; + struct completion complete; + struct sdw_msg *msg; +}; + +/** + * struct sdw_master_ops - Master driver ops + * @read_prop: Read Master properties + * @xfer_msg: Transfer message callback + * @xfer_msg_defer: Defer version of transfer message callback + * @reset_page_addr: Reset the SCP page address registers + */ +struct sdw_master_ops { + int (*read_prop)(struct sdw_bus *bus); + + enum sdw_command_response (*xfer_msg) + (struct sdw_bus *bus, struct sdw_msg *msg); + enum sdw_command_response (*xfer_msg_defer) + (struct sdw_bus *bus, struct sdw_msg *msg, + struct sdw_defer *defer); + enum sdw_command_response (*reset_page_addr) + (struct sdw_bus *bus, unsigned int dev_num); +}; + +/** + * struct sdw_bus - SoundWire bus + * @dev: Master linux device + * @link_id: Link id number, can be 0 to N, unique for each Master + * @slaves: list of Slaves on this bus + * @assigned: Bitmap for Slave device numbers. + * Bit set implies used number, bit clear implies unused number. + * @bus_lock: bus lock + * @msg_lock: message lock + * @ops: Master callback ops + * @prop: Master properties + * @defer_msg: Defer message + * @clk_stop_timeout: Clock stop timeout computed + */ +struct sdw_bus { + struct device *dev; + unsigned int link_id; + struct list_head slaves; + DECLARE_BITMAP(assigned, SDW_MAX_DEVICES); + struct mutex bus_lock; + struct mutex msg_lock; + const struct sdw_master_ops *ops; + struct sdw_master_prop prop; + struct sdw_defer defer_msg; + unsigned int clk_stop_timeout; +}; + +int sdw_add_bus_master(struct sdw_bus *bus); +void sdw_delete_bus_master(struct sdw_bus *bus); + +/* messaging and data APIs */ + +int sdw_read(struct sdw_slave *slave, u32 addr); +int sdw_write(struct sdw_slave *slave, u32 addr, u8 value); +int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val); +int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val); + +#endif /* __SOUNDWIRE_H */ diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h new file mode 100644 index 000000000000..4b37528f592d --- /dev/null +++ b/include/linux/soundwire/sdw_intel.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2015-17 Intel Corporation. + +#ifndef __SDW_INTEL_H +#define __SDW_INTEL_H + +/** + * struct sdw_intel_res - Soundwire Intel resource structure + * @mmio_base: mmio base of SoundWire registers + * @irq: interrupt number + * @handle: ACPI parent handle + * @parent: parent device + */ +struct sdw_intel_res { + void __iomem *mmio_base; + int irq; + acpi_handle handle; + struct device *parent; +}; + +void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res); +void sdw_intel_exit(void *arg); + +#endif diff --git a/include/linux/soundwire/sdw_registers.h b/include/linux/soundwire/sdw_registers.h new file mode 100644 index 000000000000..df472b1ab410 --- /dev/null +++ b/include/linux/soundwire/sdw_registers.h @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2015-17 Intel Corporation. + +#ifndef __SDW_REGISTERS_H +#define __SDW_REGISTERS_H + +/* + * typically we define register and shifts but if one observes carefully, + * the shift can be generated from MASKS using few bit primitaives like ffs + * etc, so we use that and avoid defining shifts + */ +#define SDW_REG_SHIFT(n) (ffs(n) - 1) + +/* + * SDW registers as defined by MIPI 1.1 Spec + */ +#define SDW_REGADDR GENMASK(14, 0) +#define SDW_SCP_ADDRPAGE2_MASK GENMASK(22, 15) +#define SDW_SCP_ADDRPAGE1_MASK GENMASK(30, 23) + +#define SDW_REG_NO_PAGE 0x00008000 +#define SDW_REG_OPTIONAL_PAGE 0x00010000 +#define SDW_REG_MAX 0x80000000 + +#define SDW_DPN_SIZE 0x100 +#define SDW_BANK1_OFFSET 0x10 + +/* + * DP0 Interrupt register & bits + * + * Spec treats Status (RO) and Clear (WC) as separate but they are same + * address, so treat as same register with WC. + */ + +/* both INT and STATUS register are same */ +#define SDW_DP0_INT 0x0 +#define SDW_DP0_INTMASK 0x1 +#define SDW_DP0_PORTCTRL 0x2 +#define SDW_DP0_BLOCKCTRL1 0x3 +#define SDW_DP0_PREPARESTATUS 0x4 +#define SDW_DP0_PREPARECTRL 0x5 + +#define SDW_DP0_INT_TEST_FAIL BIT(0) +#define SDW_DP0_INT_PORT_READY BIT(1) +#define SDW_DP0_INT_BRA_FAILURE BIT(2) +#define SDW_DP0_INT_IMPDEF1 BIT(5) +#define SDW_DP0_INT_IMPDEF2 BIT(6) +#define SDW_DP0_INT_IMPDEF3 BIT(7) + +#define SDW_DP0_PORTCTRL_DATAMODE GENMASK(3, 2) +#define SDW_DP0_PORTCTRL_NXTINVBANK BIT(4) +#define SDW_DP0_PORTCTRL_BPT_PAYLD GENMASK(7, 6) + +#define SDW_DP0_CHANNELEN 0x20 +#define SDW_DP0_SAMPLECTRL1 0x22 +#define SDW_DP0_SAMPLECTRL2 0x23 +#define SDW_DP0_OFFSETCTRL1 0x24 +#define SDW_DP0_OFFSETCTRL2 0x25 +#define SDW_DP0_HCTRL 0x26 +#define SDW_DP0_LANECTRL 0x28 + +/* Both INT and STATUS register are same */ +#define SDW_SCP_INT1 0x40 +#define SDW_SCP_INTMASK1 0x41 + +#define SDW_SCP_INT1_PARITY BIT(0) +#define SDW_SCP_INT1_BUS_CLASH BIT(1) +#define SDW_SCP_INT1_IMPL_DEF BIT(2) +#define SDW_SCP_INT1_SCP2_CASCADE BIT(7) +#define SDW_SCP_INT1_PORT0_3 GENMASK(6, 3) + +#define SDW_SCP_INTSTAT2 0x42 +#define SDW_SCP_INTSTAT2_SCP3_CASCADE BIT(7) +#define SDW_SCP_INTSTAT2_PORT4_10 GENMASK(6, 0) + + +#define SDW_SCP_INTSTAT3 0x43 +#define SDW_SCP_INTSTAT3_PORT11_14 GENMASK(3, 0) + +/* Number of interrupt status registers */ +#define SDW_NUM_INT_STAT_REGISTERS 3 + +/* Number of interrupt clear registers */ +#define SDW_NUM_INT_CLEAR_REGISTERS 1 + +#define SDW_SCP_CTRL 0x44 +#define SDW_SCP_CTRL_CLK_STP_NOW BIT(1) +#define SDW_SCP_CTRL_FORCE_RESET BIT(7) + +#define SDW_SCP_STAT 0x44 +#define SDW_SCP_STAT_CLK_STP_NF BIT(0) +#define SDW_SCP_STAT_HPHY_NOK BIT(5) +#define SDW_SCP_STAT_CURR_BANK BIT(6) + +#define SDW_SCP_SYSTEMCTRL 0x45 +#define SDW_SCP_SYSTEMCTRL_CLK_STP_PREP BIT(0) +#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE BIT(2) +#define SDW_SCP_SYSTEMCTRL_WAKE_UP_EN BIT(3) +#define SDW_SCP_SYSTEMCTRL_HIGH_PHY BIT(4) + +#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE0 0 +#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE1 BIT(2) + +#define SDW_SCP_DEVNUMBER 0x46 +#define SDW_SCP_HIGH_PHY_CHECK 0x47 +#define SDW_SCP_ADDRPAGE1 0x48 +#define SDW_SCP_ADDRPAGE2 0x49 +#define SDW_SCP_KEEPEREN 0x4A +#define SDW_SCP_BANKDELAY 0x4B +#define SDW_SCP_TESTMODE 0x4F +#define SDW_SCP_DEVID_0 0x50 +#define SDW_SCP_DEVID_1 0x51 +#define SDW_SCP_DEVID_2 0x52 +#define SDW_SCP_DEVID_3 0x53 +#define SDW_SCP_DEVID_4 0x54 +#define SDW_SCP_DEVID_5 0x55 + +/* Banked Registers */ +#define SDW_SCP_FRAMECTRL_B0 0x60 +#define SDW_SCP_FRAMECTRL_B1 (0x60 + SDW_BANK1_OFFSET) +#define SDW_SCP_NEXTFRAME_B0 0x61 +#define SDW_SCP_NEXTFRAME_B1 (0x61 + SDW_BANK1_OFFSET) + +/* Both INT and STATUS register is same */ +#define SDW_DPN_INT(n) (0x0 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_INTMASK(n) (0x1 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_PORTCTRL(n) (0x2 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_BLOCKCTRL1(n) (0x3 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_PREPARESTATUS(n) (0x4 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_PREPARECTRL(n) (0x5 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_INT_TEST_FAIL BIT(0) +#define SDW_DPN_INT_PORT_READY BIT(1) +#define SDW_DPN_INT_IMPDEF1 BIT(5) +#define SDW_DPN_INT_IMPDEF2 BIT(6) +#define SDW_DPN_INT_IMPDEF3 BIT(7) + +#define SDW_DPN_PORTCTRL_FLOWMODE GENMASK(1, 0) +#define SDW_DPN_PORTCTRL_DATAMODE GENMASK(3, 2) +#define SDW_DPN_PORTCTRL_NXTINVBANK BIT(4) + +#define SDW_DPN_BLOCKCTRL1_WDLEN GENMASK(5, 0) + +#define SDW_DPN_PREPARECTRL_CH_PREP GENMASK(7, 0) + +#define SDW_DPN_CHANNELEN_B0(n) (0x20 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_CHANNELEN_B1(n) (0x30 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_BLOCKCTRL2_B0(n) (0x21 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_BLOCKCTRL2_B1(n) (0x31 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_SAMPLECTRL1_B0(n) (0x22 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_SAMPLECTRL1_B1(n) (0x32 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_SAMPLECTRL2_B0(n) (0x23 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_SAMPLECTRL2_B1(n) (0x33 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_OFFSETCTRL1_B0(n) (0x24 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_OFFSETCTRL1_B1(n) (0x34 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_OFFSETCTRL2_B0(n) (0x25 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_OFFSETCTRL2_B1(n) (0x35 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_HCTRL_B0(n) (0x26 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_HCTRL_B1(n) (0x36 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_BLOCKCTRL3_B0(n) (0x27 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_BLOCKCTRL3_B1(n) (0x37 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_LANECTRL_B0(n) (0x28 + SDW_DPN_SIZE * (n)) +#define SDW_DPN_LANECTRL_B1(n) (0x38 + SDW_DPN_SIZE * (n)) + +#define SDW_DPN_SAMPLECTRL_LOW GENMASK(7, 0) +#define SDW_DPN_SAMPLECTRL_HIGH GENMASK(15, 8) + +#define SDW_DPN_HCTRL_HSTART GENMASK(7, 4) +#define SDW_DPN_HCTRL_HSTOP GENMASK(3, 0) + +#define SDW_NUM_CASC_PORT_INTSTAT1 4 +#define SDW_CASC_PORT_START_INTSTAT1 0 +#define SDW_CASC_PORT_MASK_INTSTAT1 0x8 +#define SDW_CASC_PORT_REG_OFFSET_INTSTAT1 0x0 + +#define SDW_NUM_CASC_PORT_INTSTAT2 7 +#define SDW_CASC_PORT_START_INTSTAT2 4 +#define SDW_CASC_PORT_MASK_INTSTAT2 1 +#define SDW_CASC_PORT_REG_OFFSET_INTSTAT2 1 + +#define SDW_NUM_CASC_PORT_INTSTAT3 4 +#define SDW_CASC_PORT_START_INTSTAT3 11 +#define SDW_CASC_PORT_MASK_INTSTAT3 1 +#define SDW_CASC_PORT_REG_OFFSET_INTSTAT3 2 + +#endif /* __SDW_REGISTERS_H */ diff --git a/include/linux/soundwire/sdw_type.h b/include/linux/soundwire/sdw_type.h new file mode 100644 index 000000000000..9fd553e553e9 --- /dev/null +++ b/include/linux/soundwire/sdw_type.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright(c) 2015-17 Intel Corporation. + +#ifndef __SOUNDWIRE_TYPES_H +#define __SOUNDWIRE_TYPES_H + +extern struct bus_type sdw_bus_type; + +#define drv_to_sdw_driver(_drv) container_of(_drv, struct sdw_driver, driver) + +#define sdw_register_driver(drv) \ + __sdw_register_driver(drv, THIS_MODULE) + +int __sdw_register_driver(struct sdw_driver *drv, struct module *); +void sdw_unregister_driver(struct sdw_driver *drv); + +int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size); + +#endif /* __SOUNDWIRE_TYPES_H */ diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 40839c02d28c..b8bfdc173ec0 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -113,7 +113,7 @@ struct attribute_group { } #define __ATTR_RO(_name) { \ - .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ .show = _name##_show, \ } @@ -124,12 +124,11 @@ struct attribute_group { } #define __ATTR_WO(_name) { \ - .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ + .attr = { .name = __stringify(_name), .mode = 0200 }, \ .store = _name##_store, \ } -#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ - _name##_show, _name##_store) +#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store) #define __ATTR_NULL { .attr = { .name = NULL } } @@ -192,14 +191,13 @@ struct bin_attribute { } #define __BIN_ATTR_RO(_name, _size) { \ - .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ .read = _name##_read, \ .size = _size, \ } -#define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \ - (S_IWUSR | S_IRUGO), _name##_read, \ - _name##_write, _size) +#define __BIN_ATTR_RW(_name, _size) \ + __BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size) #define __BIN_ATTR_NULL __ATTR_NULL diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index cb889afe576b..a2b3dfcee0b5 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -17,6 +17,7 @@ #include <linux/types.h> #include <linux/idr.h> +#include <linux/kref.h> #include <linux/list.h> #include <linux/tee.h> @@ -25,8 +26,12 @@ * specific TEE driver. */ -#define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */ -#define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */ +#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */ +#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */ +#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */ +#define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */ +#define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */ +#define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */ struct device; struct tee_device; @@ -38,11 +43,17 @@ struct tee_shm_pool; * @teedev: pointer to this drivers struct tee_device * @list_shm: List of shared memory object owned by this context * @data: driver specific context data, managed by the driver + * @refcount: reference counter for this structure + * @releasing: flag that indicates if context is being released right now. + * It is needed to break circular dependency on context during + * shared memory release. */ struct tee_context { struct tee_device *teedev; struct list_head list_shm; void *data; + struct kref refcount; + bool releasing; }; struct tee_param_memref { @@ -76,6 +87,8 @@ struct tee_param { * @cancel_req: request cancel of an ongoing invoke or open * @supp_revc: called for supplicant to get a command * @supp_send: called for supplicant to send a response + * @shm_register: register shared memory buffer in TEE + * @shm_unregister: unregister shared memory buffer in TEE */ struct tee_driver_ops { void (*get_version)(struct tee_device *teedev, @@ -94,6 +107,10 @@ struct tee_driver_ops { struct tee_param *param); int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params, struct tee_param *param); + int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, + struct page **pages, size_t num_pages, + unsigned long start); + int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm); }; /** @@ -150,6 +167,97 @@ int tee_device_register(struct tee_device *teedev); void tee_device_unregister(struct tee_device *teedev); /** + * struct tee_shm - shared memory object + * @teedev: device used to allocate the object + * @ctx: context using the object, if NULL the context is gone + * @link link element + * @paddr: physical address of the shared memory + * @kaddr: virtual address of the shared memory + * @size: size of shared memory + * @offset: offset of buffer in user space + * @pages: locked pages from userspace + * @num_pages: number of locked pages + * @dmabuf: dmabuf used to for exporting to user space + * @flags: defined by TEE_SHM_* in tee_drv.h + * @id: unique id of a shared memory object on this device + * + * This pool is only supposed to be accessed directly from the TEE + * subsystem and from drivers that implements their own shm pool manager. + */ +struct tee_shm { + struct tee_device *teedev; + struct tee_context *ctx; + struct list_head link; + phys_addr_t paddr; + void *kaddr; + size_t size; + unsigned int offset; + struct page **pages; + size_t num_pages; + struct dma_buf *dmabuf; + u32 flags; + int id; +}; + +/** + * struct tee_shm_pool_mgr - shared memory manager + * @ops: operations + * @private_data: private data for the shared memory manager + */ +struct tee_shm_pool_mgr { + const struct tee_shm_pool_mgr_ops *ops; + void *private_data; +}; + +/** + * struct tee_shm_pool_mgr_ops - shared memory pool manager operations + * @alloc: called when allocating shared memory + * @free: called when freeing shared memory + * @destroy_poolmgr: called when destroying the pool manager + */ +struct tee_shm_pool_mgr_ops { + int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm, + size_t size); + void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm); + void (*destroy_poolmgr)(struct tee_shm_pool_mgr *poolmgr); +}; + +/** + * tee_shm_pool_alloc() - Create a shared memory pool from shm managers + * @priv_mgr: manager for driver private shared memory allocations + * @dmabuf_mgr: manager for dma-buf shared memory allocations + * + * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied + * in @dmabuf, others will use the range provided by @priv. + * + * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure. + */ +struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr, + struct tee_shm_pool_mgr *dmabuf_mgr); + +/* + * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved + * memory + * @vaddr: Virtual address of start of pool + * @paddr: Physical address of start of pool + * @size: Size in bytes of the pool + * + * @returns pointer to a 'struct tee_shm_pool_mgr' or an ERR_PTR on failure. + */ +struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr, + phys_addr_t paddr, + size_t size, + int min_alloc_order); + +/** + * tee_shm_pool_mgr_destroy() - Free a shared memory manager + */ +static inline void tee_shm_pool_mgr_destroy(struct tee_shm_pool_mgr *poolm) +{ + poolm->ops->destroy_poolmgr(poolm); +} + +/** * struct tee_shm_pool_mem_info - holds information needed to create a shared * memory pool * @vaddr: Virtual address of start of pool @@ -211,6 +319,40 @@ void *tee_get_drvdata(struct tee_device *teedev); struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); /** + * tee_shm_priv_alloc() - Allocate shared memory privately + * @dev: Device that allocates the shared memory + * @size: Requested size of shared memory + * + * Allocates shared memory buffer that is not associated with any client + * context. Such buffers are owned by TEE driver and used for internal calls. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size); + +/** + * tee_shm_register() - Register shared memory buffer + * @ctx: Context that registers the shared memory + * @addr: Address is userspace of the shared buffer + * @length: Length of the shared buffer + * @flags: Flags setting properties for the requested shared memory. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, + size_t length, u32 flags); + +/** + * tee_shm_is_registered() - Check if shared memory object in registered in TEE + * @shm: Shared memory handle + * @returns true if object is registered in TEE + */ +static inline bool tee_shm_is_registered(struct tee_shm *shm) +{ + return shm && (shm->flags & TEE_SHM_REGISTER); +} + +/** * tee_shm_free() - Free shared memory * @shm: Handle to shared memory to free */ @@ -260,11 +402,47 @@ void *tee_shm_get_va(struct tee_shm *shm, size_t offs); int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa); /** + * tee_shm_get_size() - Get size of shared memory buffer + * @shm: Shared memory handle + * @returns size of shared memory + */ +static inline size_t tee_shm_get_size(struct tee_shm *shm) +{ + return shm->size; +} + +/** + * tee_shm_get_pages() - Get list of pages that hold shared buffer + * @shm: Shared memory handle + * @num_pages: Number of pages will be stored there + * @returns pointer to pages array + */ +static inline struct page **tee_shm_get_pages(struct tee_shm *shm, + size_t *num_pages) +{ + *num_pages = shm->num_pages; + return shm->pages; +} + +/** + * tee_shm_get_page_offset() - Get shared buffer offset from page start + * @shm: Shared memory handle + * @returns page offset of shared buffer + */ +static inline size_t tee_shm_get_page_offset(struct tee_shm *shm) +{ + return shm->offset; +} + +/** * tee_shm_get_id() - Get id of a shared memory object * @shm: Shared memory handle * @returns id */ -int tee_shm_get_id(struct tee_shm *shm); +static inline int tee_shm_get_id(struct tee_shm *shm) +{ + return shm->id; +} /** * tee_shm_get_from_id() - Find shared memory object and increase reference @@ -275,4 +453,16 @@ int tee_shm_get_id(struct tee_shm *shm); */ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); +static inline bool tee_param_is_memref(struct tee_param *param) +{ + switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: + return true; + default: + return false; + } +} + #endif /*__TEE_DRV_H*/ diff --git a/include/linux/ti-emif-sram.h b/include/linux/ti-emif-sram.h new file mode 100644 index 000000000000..45bc6b376492 --- /dev/null +++ b/include/linux/ti-emif-sram.h @@ -0,0 +1,69 @@ +/* + * TI AM33XX EMIF Routines + * + * Copyright (C) 2016-2017 Texas Instruments Inc. + * Dave Gerlach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __LINUX_TI_EMIF_H +#define __LINUX_TI_EMIF_H + +#include <linux/kbuild.h> +#include <linux/types.h> +#ifndef __ASSEMBLY__ + +struct emif_regs_amx3 { + u32 emif_sdcfg_val; + u32 emif_timing1_val; + u32 emif_timing2_val; + u32 emif_timing3_val; + u32 emif_ref_ctrl_val; + u32 emif_zqcfg_val; + u32 emif_pmcr_val; + u32 emif_pmcr_shdw_val; + u32 emif_rd_wr_level_ramp_ctrl; + u32 emif_rd_wr_exec_thresh; + u32 emif_cos_config; + u32 emif_priority_to_cos_mapping; + u32 emif_connect_id_serv_1_map; + u32 emif_connect_id_serv_2_map; + u32 emif_ocp_config_val; + u32 emif_lpddr2_nvm_tim; + u32 emif_lpddr2_nvm_tim_shdw; + u32 emif_dll_calib_ctrl_val; + u32 emif_dll_calib_ctrl_val_shdw; + u32 emif_ddr_phy_ctlr_1; + u32 emif_ext_phy_ctrl_vals[120]; +}; + +struct ti_emif_pm_data { + void __iomem *ti_emif_base_addr_virt; + phys_addr_t ti_emif_base_addr_phys; + unsigned long ti_emif_sram_config; + struct emif_regs_amx3 *regs_virt; + phys_addr_t regs_phys; +} __packed __aligned(8); + +struct ti_emif_pm_functions { + u32 save_context; + u32 restore_context; + u32 enter_sr; + u32 exit_sr; + u32 abort_sr; +} __packed __aligned(8); + +struct gen_pool; + +int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst); +int ti_emif_get_mem_type(void); + +#endif +#endif /* __LINUX_TI_EMIF_H */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 7ac8ba208b1f..0a6c71e0ad01 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -405,6 +405,8 @@ extern const char *tty_name(const struct tty_struct *tty); extern struct tty_struct *tty_kopen(dev_t device); extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); +extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); +extern void tty_ldisc_unlock(struct tty_struct *tty); #else static inline void tty_kref_put(struct tty_struct *tty) { } diff --git a/include/linux/usb.h b/include/linux/usb.h index fbbe974661f2..0173597e59aa 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -609,6 +609,10 @@ struct usb3_lpm_parameters { * to keep track of the number of functions that require USB 3.0 Link Power * Management to be disabled for this usb_device. This count should only * be manipulated by those functions, with the bandwidth_mutex is held. + * @hub_delay: cached value consisting of: + * parent->hub_delay + wHubDelay + tTPTransmissionDelay (40ns) + * + * Will be used as wValue for SetIsochDelay requests. * * Notes: * Usbcore drivers should not set usbdev->state directly. Instead use @@ -689,6 +693,8 @@ struct usb_device { struct usb3_lpm_parameters u1_params; struct usb3_lpm_parameters u2_params; unsigned lpm_disable_count; + + u16 hub_delay; }; #define to_usb_device(d) container_of(d, struct usb_device, dev) @@ -1293,7 +1299,6 @@ extern int usb_disabled(void); #define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired * slot in the schedule */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ -#define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt * needed */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 0142f3af0da6..66a5cff7ee14 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -330,6 +330,7 @@ struct usb_gadget_ops { * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. + * @isoch_delay: value from Set Isoch Delay request. Only valid on SS/SSP * @out_epnum: last used out ep number * @in_epnum: last used in ep number * @mA: last set mA value @@ -394,6 +395,7 @@ struct usb_gadget { enum usb_device_state state; const char *name; struct device dev; + unsigned isoch_delay; unsigned out_epnum; unsigned in_epnum; unsigned mA; diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index 6cbe7a5c2b57..dba55ccb9b53 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -12,13 +12,17 @@ #include <linux/usb/otg.h> #include <linux/usb/phy.h> +struct usb_device; + #if IS_ENABLED(CONFIG_OF) enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); -struct device_node *usb_of_get_child_node(struct device_node *parent, - int portnum); +struct device_node *usb_of_get_device_node(struct usb_device *hub, int port1); +bool usb_of_has_combined_node(struct usb_device *udev); +struct device_node *usb_of_get_interface_node(struct usb_device *udev, + u8 config, u8 ifnum); struct device *usb_of_get_companion_dev(struct device *dev); #else static inline enum usb_dr_mode @@ -35,8 +39,17 @@ static inline int of_usb_update_otg_caps(struct device_node *np, { return 0; } -static inline struct device_node *usb_of_get_child_node - (struct device_node *parent, int portnum) +static inline struct device_node * +usb_of_get_device_node(struct usb_device *hub, int port1) +{ + return NULL; +} +static inline bool usb_of_has_combined_node(struct usb_device *udev) +{ + return false; +} +static inline struct device_node * +usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum) { return NULL; } diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index e00051ced806..b3d41d7409b3 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -148,6 +148,8 @@ enum pd_pdo_type { (PDO_TYPE(PDO_TYPE_FIXED) | (flags) | \ PDO_FIXED_VOLT(mv) | PDO_FIXED_CURR(ma)) +#define VSAFE5V 5000 /* mv units */ + #define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */ #define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */ #define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ diff --git a/include/linux/usb/pd_vdo.h b/include/linux/usb/pd_vdo.h index d92259f8de0a..2b64d23ace5c 100644 --- a/include/linux/usb/pd_vdo.h +++ b/include/linux/usb/pd_vdo.h @@ -65,7 +65,7 @@ #define CMD_EXIT_MODE 5 #define CMD_ATTENTION 6 -#define VDO_CMD_VENDOR(x) (((10 + (x)) & 0x1f)) +#define VDO_CMD_VENDOR(x) (((0x10 + (x)) & 0x1f)) /* ChromeOS specific commands */ #define VDO_CMD_VERSION VDO_CMD_VENDOR(0) diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 67102f3d59d4..53924f8e840c 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -17,6 +17,7 @@ */ #ifndef RENESAS_USB_H #define RENESAS_USB_H +#include <linux/notifier.h> #include <linux/platform_device.h> #include <linux/usb/ch9.h> @@ -98,6 +99,13 @@ struct renesas_usbhs_platform_callback { * VBUS control is needed for Host */ int (*set_vbus)(struct platform_device *pdev, int enable); + + /* + * option: + * extcon notifier to set host/peripheral mode. + */ + int (*notifier)(struct notifier_block *nb, unsigned long event, + void *data); }; /* @@ -187,6 +195,7 @@ struct renesas_usbhs_driver_param { #define USBHS_TYPE_RCAR_GEN2 1 #define USBHS_TYPE_RCAR_GEN3 2 #define USBHS_TYPE_RCAR_GEN3_WITH_PLL 3 +#define USBHS_TYPE_RZA1 4 /* * option: diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index 073197f0d2bb..ca1c0b57f03f 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -183,14 +183,14 @@ struct tcpm_port; struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc); void tcpm_unregister_port(struct tcpm_port *port); -void tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo, - unsigned int nr_pdo); -void tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo, - unsigned int nr_pdo, - unsigned int max_snk_mv, - unsigned int max_snk_ma, - unsigned int max_snk_mw, - unsigned int operating_snk_mw); +int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo, + unsigned int nr_pdo); +int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo, + unsigned int nr_pdo, + unsigned int max_snk_mv, + unsigned int max_snk_ma, + unsigned int max_snk_mw, + unsigned int operating_snk_mw); void tcpm_vbus_change(struct tcpm_port *port); void tcpm_cc_change(struct tcpm_port *port); diff --git a/include/linux/vbox_utils.h b/include/linux/vbox_utils.h new file mode 100644 index 000000000000..c71def6b310f --- /dev/null +++ b/include/linux/vbox_utils.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0) */ +/* Copyright (C) 2006-2016 Oracle Corporation */ + +#ifndef __VBOX_UTILS_H__ +#define __VBOX_UTILS_H__ + +#include <linux/printk.h> +#include <linux/vbox_vmmdev_types.h> + +struct vbg_dev; + +/** + * vboxguest logging functions, these log both to the backdoor and call + * the equivalent kernel pr_foo function. + */ +__printf(1, 2) void vbg_info(const char *fmt, ...); +__printf(1, 2) void vbg_warn(const char *fmt, ...); +__printf(1, 2) void vbg_err(const char *fmt, ...); + +/* Only use backdoor logging for non-dynamic debug builds */ +#if defined(DEBUG) && !defined(CONFIG_DYNAMIC_DEBUG) +__printf(1, 2) void vbg_debug(const char *fmt, ...); +#else +#define vbg_debug pr_debug +#endif + +/** + * Allocate memory for generic request and initialize the request header. + * + * Return: the allocated memory + * @len: Size of memory block required for the request. + * @req_type: The generic request type. + */ +void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type); + +/** + * Perform a generic request. + * + * Return: VBox status code + * @gdev: The Guest extension device. + * @req: Pointer to the request structure. + */ +int vbg_req_perform(struct vbg_dev *gdev, void *req); + +int vbg_hgcm_connect(struct vbg_dev *gdev, + struct vmmdev_hgcm_service_location *loc, + u32 *client_id, int *vbox_status); + +int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status); + +int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function, + u32 timeout_ms, struct vmmdev_hgcm_function_parameter *parms, + u32 parm_count, int *vbox_status); + +int vbg_hgcm_call32( + struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms, + struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count, + int *vbox_status); + +/** + * Convert a VirtualBox status code to a standard Linux kernel return value. + * Return: 0 or negative errno value. + * @rc: VirtualBox status code to convert. + */ +int vbg_status_code_to_errno(int rc); + +/** + * Helper for the vboxsf driver to get a reference to the guest device. + * Return: a pointer to the gdev; or a ERR_PTR value on error. + */ +struct vbg_dev *vbg_get_gdev(void); + +/** + * Helper for the vboxsf driver to put a guest device reference. + * @gdev: Reference returned by vbg_get_gdev to put. + */ +void vbg_put_gdev(struct vbg_dev *gdev); + +#endif diff --git a/include/linux/vfio.h b/include/linux/vfio.h index a47b985341d1..66741ab087c1 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -145,7 +145,8 @@ extern struct vfio_info_cap_header *vfio_info_cap_add( extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); extern int vfio_info_add_capability(struct vfio_info_cap *caps, - int cap_type_id, void *cap_type); + struct vfio_info_cap_header *cap, + size_t size); extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, int max_irq_type, diff --git a/include/linux/visorbus.h b/include/linux/visorbus.h new file mode 100644 index 000000000000..0d8bd6769b13 --- /dev/null +++ b/include/linux/visorbus.h @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2010 - 2013 UNISYS CORPORATION + * All rights reserved. + */ + +/* + * This header file is to be included by other kernel mode components that + * implement a particular kind of visor_device. Each of these other kernel + * mode components is called a visor device driver. Refer to visortemplate + * for a minimal sample visor device driver. + * + * There should be nothing in this file that is private to the visorbus + * bus implementation itself. + */ + +#ifndef __VISORBUS_H__ +#define __VISORBUS_H__ + +#include <linux/device.h> + +#define VISOR_CHANNEL_SIGNATURE ('L' << 24 | 'N' << 16 | 'C' << 8 | 'E') + +/* + * enum channel_serverstate + * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state. + * @CHANNELSRV_READY: Channel has been initialized by server. + */ +enum channel_serverstate { + CHANNELSRV_UNINITIALIZED = 0, + CHANNELSRV_READY = 1 +}; + +/* + * enum channel_clientstate + * @CHANNELCLI_DETACHED: + * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it + * unless given TBD* explicit request + * (should actually be < DETACHED). + * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach. + * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time. + * @CHANNELCLI_BUSY: Client either wants to use or is using channel. + * @CHANNELCLI_OWNED: "No worries" state - client can access channel + * anytime. + */ +enum channel_clientstate { + CHANNELCLI_DETACHED = 0, + CHANNELCLI_DISABLED = 1, + CHANNELCLI_ATTACHING = 2, + CHANNELCLI_ATTACHED = 3, + CHANNELCLI_BUSY = 4, + CHANNELCLI_OWNED = 5 +}; + +/* + * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that + * a guest can look at the FeatureFlags in the io channel, and configure the + * driver to use interrupts or not based on this setting. All feature bits for + * all channels should be defined here. The io channel feature bits are defined + * below. + */ +#define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1) +#define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3) +#define VISOR_IOVM_OK_DRIVER_DISABLING_INTS (0x1ULL << 4) +#define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5) +#define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6) + +/* + * struct channel_header - Common Channel Header + * @signature: Signature. + * @legacy_state: DEPRECATED - being replaced by. + * @header_size: sizeof(struct channel_header). + * @size: Total size of this channel in bytes. + * @features: Flags to modify behavior. + * @chtype: Channel type: data, bus, control, etc.. + * @partition_handle: ID of guest partition. + * @handle: Device number of this channel in client. + * @ch_space_offset: Offset in bytes to channel specific area. + * @version_id: Struct channel_header Version ID. + * @partition_index: Index of guest partition. + * @zone_uuid: Guid of Channel's zone. + * @cli_str_offset: Offset from channel header to null-terminated + * ClientString (0 if ClientString not present). + * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this + * channel. + * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel. + * @ch_characteristic: CHANNEL_CHARACTERISTIC_<xxx>. + * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @srv_state: CHANNEL_SERVERSTATE. + * @cli_error_boot: Bits to indicate err states for boot clients, so err + * messages can be throttled. + * @cli_error_os: Bits to indicate err states for OS clients, so err + * messages can be throttled. + * @filler: Pad out to 128 byte cacheline. + * @recover_channel: Please add all new single-byte values below here. + */ +struct channel_header { + u64 signature; + u32 legacy_state; + /* SrvState, CliStateBoot, and CliStateOS below */ + u32 header_size; + u64 size; + u64 features; + guid_t chtype; + u64 partition_handle; + u64 handle; + u64 ch_space_offset; + u32 version_id; + u32 partition_index; + guid_t zone_guid; + u32 cli_str_offset; + u32 cli_state_boot; + u32 cmd_state_cli; + u32 cli_state_os; + u32 ch_characteristic; + u32 cmd_state_srv; + u32 srv_state; + u8 cli_error_boot; + u8 cli_error_os; + u8 filler[1]; + u8 recover_channel; +} __packed; + +#define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0) + +/* + * struct signal_queue_header - Subheader for the Signal Type variation of the + * Common Channel. + * @version: SIGNAL_QUEUE_HEADER Version ID. + * @chtype: Queue type: storage, network. + * @size: Total size of this queue in bytes. + * @sig_base_offset: Offset to signal queue area. + * @features: Flags to modify behavior. + * @num_sent: Total # of signals placed in this queue. + * @num_overflows: Total # of inserts failed due to full queue. + * @signal_size: Total size of a signal for this queue. + * @max_slots: Max # of slots in queue, 1 slot is always empty. + * @max_signals: Max # of signals in queue (MaxSignalSlots-1). + * @head: Queue head signal #. + * @num_received: Total # of signals removed from this queue. + * @tail: Queue tail signal. + * @reserved1: Reserved field. + * @reserved2: Reserved field. + * @client_queue: + * @num_irq_received: Total # of Interrupts received. This is incremented by the + * ISR in the guest windows driver. + * @num_empty: Number of times that visor_signal_remove is called and + * returned Empty Status. + * @errorflags: Error bits set during SignalReinit to denote trouble with + * client's fields. + * @filler: Pad out to 64 byte cacheline. + */ +struct signal_queue_header { + /* 1st cache line */ + u32 version; + u32 chtype; + u64 size; + u64 sig_base_offset; + u64 features; + u64 num_sent; + u64 num_overflows; + u32 signal_size; + u32 max_slots; + u32 max_signals; + u32 head; + /* 2nd cache line */ + u64 num_received; + u32 tail; + u32 reserved1; + u64 reserved2; + u64 client_queue; + u64 num_irq_received; + u64 num_empty; + u32 errorflags; + u8 filler[12]; +} __packed; + +/* VISORCHANNEL Guids */ +/* {414815ed-c58c-11da-95a9-00e08161165f} */ +#define VISOR_VHBA_CHANNEL_GUID \ + GUID_INIT(0x414815ed, 0xc58c, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VHBA_CHANNEL_GUID_STR \ + "414815ed-c58c-11da-95a9-00e08161165f" +struct visorchipset_state { + u32 created:1; + u32 attached:1; + u32 configured:1; + u32 running:1; + /* Remaining bits in this 32-bit word are reserved. */ +}; + +/** + * struct visor_device - A device type for things "plugged" into the visorbus + * bus + * @visorchannel: Points to the channel that the device is + * associated with. + * @channel_type_guid: Identifies the channel type to the bus driver. + * @device: Device struct meant for use by the bus driver + * only. + * @list_all: Used by the bus driver to enumerate devices. + * @timer: Timer fired periodically to do interrupt-type + * activity. + * @being_removed: Indicates that the device is being removed from + * the bus. Private bus driver use only. + * @visordriver_callback_lock: Used by the bus driver to lock when adding and + * removing devices. + * @pausing: Indicates that a change towards a paused state. + * is in progress. Only modified by the bus driver. + * @resuming: Indicates that a change towards a running state + * is in progress. Only modified by the bus driver. + * @chipset_bus_no: Private field used by the bus driver. + * @chipset_dev_no: Private field used the bus driver. + * @state: Used to indicate the current state of the + * device. + * @inst: Unique GUID for this instance of the device. + * @name: Name of the device. + * @pending_msg_hdr: For private use by bus driver to respond to + * hypervisor requests. + * @vbus_hdr_info: A pointer to header info. Private use by bus + * driver. + * @partition_guid: Indicates client partion id. This should be the + * same across all visor_devices in the current + * guest. Private use by bus driver only. + */ +struct visor_device { + struct visorchannel *visorchannel; + guid_t channel_type_guid; + /* These fields are for private use by the bus driver only. */ + struct device device; + struct list_head list_all; + struct timer_list timer; + bool timer_active; + bool being_removed; + struct mutex visordriver_callback_lock; /* synchronize probe/remove */ + bool pausing; + bool resuming; + u32 chipset_bus_no; + u32 chipset_dev_no; + struct visorchipset_state state; + guid_t inst; + u8 *name; + struct controlvm_message_header *pending_msg_hdr; + void *vbus_hdr_info; + guid_t partition_guid; + struct dentry *debugfs_dir; + struct dentry *debugfs_bus_info; +}; + +#define to_visor_device(x) container_of(x, struct visor_device, device) + +typedef void (*visorbus_state_complete_func) (struct visor_device *dev, + int status); + +/* + * This struct describes a specific visor channel, by providing its GUID, name, + * and sizes. + */ +struct visor_channeltype_descriptor { + const guid_t guid; + const char *name; + u64 min_bytes; + u32 version; +}; + +/** + * struct visor_driver - Information provided by each visor driver when it + * registers with the visorbus driver + * @name: Name of the visor driver. + * @owner: The module owner. + * @channel_types: Types of channels handled by this driver, ending with + * a zero GUID. Our specialized BUS.match() method knows + * about this list, and uses it to determine whether this + * driver will in fact handle a new device that it has + * detected. + * @probe: Called when a new device comes online, by our probe() + * function specified by driver.probe() (triggered + * ultimately by some call to driver_register(), + * bus_add_driver(), or driver_attach()). + * @remove: Called when a new device is removed, by our remove() + * function specified by driver.remove() (triggered + * ultimately by some call to device_release_driver()). + * @channel_interrupt: Called periodically, whenever there is a possiblity + * that "something interesting" may have happened to the + * channel. + * @pause: Called to initiate a change of the device's state. If + * the return valu`e is < 0, there was an error and the + * state transition will NOT occur. If the return value + * is >= 0, then the state transition was INITIATED + * successfully, and complete_func() will be called (or + * was just called) with the final status when either the + * state transition fails or completes successfully. + * @resume: Behaves similar to pause. + * @driver: Private reference to the device driver. For use by bus + * driver only. + */ +struct visor_driver { + const char *name; + struct module *owner; + struct visor_channeltype_descriptor *channel_types; + int (*probe)(struct visor_device *dev); + void (*remove)(struct visor_device *dev); + void (*channel_interrupt)(struct visor_device *dev); + int (*pause)(struct visor_device *dev, + visorbus_state_complete_func complete_func); + int (*resume)(struct visor_device *dev, + visorbus_state_complete_func complete_func); + + /* These fields are for private use by the bus driver only. */ + struct device_driver driver; +}; + +#define to_visor_driver(x) (container_of(x, struct visor_driver, driver)) + +int visor_check_channel(struct channel_header *ch, struct device *dev, + const guid_t *expected_uuid, char *chname, + u64 expected_min_bytes, u32 expected_version, + u64 expected_signature); + +int visorbus_register_visor_driver(struct visor_driver *drv); +void visorbus_unregister_visor_driver(struct visor_driver *drv); +int visorbus_read_channel(struct visor_device *dev, + unsigned long offset, void *dest, + unsigned long nbytes); +int visorbus_write_channel(struct visor_device *dev, + unsigned long offset, void *src, + unsigned long nbytes); +int visorbus_enable_channel_interrupts(struct visor_device *dev); +void visorbus_disable_channel_interrupts(struct visor_device *dev); + +int visorchannel_signalremove(struct visorchannel *channel, u32 queue, + void *msg); +int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, + void *msg); +bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); +const guid_t *visorchannel_get_guid(struct visorchannel *channel); + +#define BUS_ROOT_DEVICE UINT_MAX +struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, + struct visor_device *from); +#endif |